From 8bf01a13e70435ceefd24fe4e7ec26f8b7e68c51 Mon Sep 17 00:00:00 2001
From: sqlcoder
Date: Tue, 2 Dec 2008 00:00:44 +0000
Subject: [PATCH 01/32] Start of fpdb-sql repository
---
readme.txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 readme.txt
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 00000000..e69de29b
From a824814c0a34689f7ed36321f7217b5a66e61e81 Mon Sep 17 00:00:00 2001
From: sqlcoder
Date: Tue, 2 Dec 2008 00:15:50 +0000
Subject: [PATCH 02/32] sqlcoder initial updates
---
pyfpdb/CliFpdb.py | 0
pyfpdb/Configuration.py | 1219 +++++++++++++++++++-----------------
pyfpdb/FpdbSQLQueries.py | 29 +-
pyfpdb/GuiAutoImport.py | 427 +++++++------
pyfpdb/GuiGraphViewer.py | 18 +-
pyfpdb/HUD_main.py | 337 +++++-----
pyfpdb/Hud.py | 1140 ++++++++++++++++-----------------
pyfpdb/SQL.py | 19 +-
pyfpdb/Stats.py | 110 +++-
pyfpdb/fpdb.py | 898 +++++++++++++-------------
pyfpdb/fpdb_db.py | 0
pyfpdb/fpdb_import.py | 608 +++++++++---------
pyfpdb/fpdb_parse_logic.py | 10 +-
pyfpdb/fpdb_save_to_db.py | 24 +-
pyfpdb/fpdb_simple.py | 73 ++-
15 files changed, 2578 insertions(+), 2334 deletions(-)
mode change 100755 => 100644 pyfpdb/CliFpdb.py
mode change 100755 => 100644 pyfpdb/Configuration.py
mode change 100755 => 100644 pyfpdb/HUD_main.py
mode change 100755 => 100644 pyfpdb/fpdb.py
mode change 100755 => 100644 pyfpdb/fpdb_db.py
mode change 100755 => 100644 pyfpdb/fpdb_import.py
diff --git a/pyfpdb/CliFpdb.py b/pyfpdb/CliFpdb.py
old mode 100755
new mode 100644
diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py
old mode 100755
new mode 100644
index 5e599d4b..3b5c6d70
--- a/pyfpdb/Configuration.py
+++ b/pyfpdb/Configuration.py
@@ -1,578 +1,641 @@
-#!/usr/bin/env python
-"""Configuration.py
-
-Handles HUD configuration files.
-"""
-# Copyright 2008, Ray E. Barker
-
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-########################################################################
-
-# Standard Library modules
-import os
-import sys
-import string
-import traceback
-import shutil
-import xml.dom.minidom
-from xml.dom.minidom import Node
-
-class Layout:
- def __init__(self, max):
- self.max = int(max)
- self.location = []
- for i in range(self.max + 1): self.location.append(None)
-
- def __str__(self):
- temp = " Layout = %d max, width= %d, height = %d, fav_seat = %d\n" % (self.max, self.width, self.height, self.fav_seat)
- temp = temp + " Locations = "
- for i in range(1, len(self.location)):
- temp = temp + "(%d,%d)" % self.location[i]
-
- return temp + "\n"
-
-class Site:
- def __init__(self, node):
- self.site_name = node.getAttribute("site_name")
- self.table_finder = node.getAttribute("table_finder")
- self.screen_name = node.getAttribute("screen_name")
- self.site_path = node.getAttribute("site_path")
- self.HH_path = node.getAttribute("HH_path")
- self.decoder = node.getAttribute("decoder")
- self.hudopacity = node.getAttribute("hudopacity")
- self.hudbgcolor = node.getAttribute("bgcolor")
- self.hudfgcolor = node.getAttribute("fgcolor")
- self.converter = node.getAttribute("converter")
- self.layout = {}
-
- for layout_node in node.getElementsByTagName('layout'):
- max = int( layout_node.getAttribute('max') )
- lo = Layout(max)
- lo.fav_seat = int( layout_node.getAttribute('fav_seat') )
- lo.width = int( layout_node.getAttribute('width') )
- lo.height = int( layout_node.getAttribute('height') )
-
- for location_node in layout_node.getElementsByTagName('location'):
- lo.location[int( location_node.getAttribute('seat') )] = (int( location_node.getAttribute('x') ), int( location_node.getAttribute('y')))
-
- self.layout[lo.max] = lo
-
- def __str__(self):
- temp = "Site = " + self.site_name + "\n"
- for key in dir(self):
- if key.startswith('__'): continue
- if key == 'layout': continue
- value = getattr(self, key)
- if callable(value): continue
- temp = temp + ' ' + key + " = " + str(value) + "\n"
-
- for layout in self.layout:
- temp = temp + "%s" % self.layout[layout]
-
- return temp
-
-class Stat:
- def __init__(self):
- pass
-
- 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)
- return temp
-
-class Game:
- def __init__(self, node):
- self.game_name = node.getAttribute("game_name")
- self.db = node.getAttribute("db")
- self.rows = int( node.getAttribute("rows") )
- self.cols = int( node.getAttribute("cols") )
-
- self.stats = {}
- for stat_node in node.getElementsByTagName('stat'):
- stat = Stat()
- stat.stat_name = stat_node.getAttribute("stat_name")
- stat.row = int( stat_node.getAttribute("row") )
- stat.col = int( stat_node.getAttribute("col") )
- stat.tip = stat_node.getAttribute("tip")
- stat.click = stat_node.getAttribute("click")
- stat.popup = stat_node.getAttribute("popup")
- stat.hudprefix = stat_node.getAttribute("hudprefix")
- stat.hudsuffix = stat_node.getAttribute("hudsuffix")
-
- self.stats[stat.stat_name] = stat
-
- def __str__(self):
- temp = "Game = " + self.game_name + "\n"
- temp = temp + " db = %s\n" % self.db
- temp = temp + " rows = %d\n" % self.rows
- temp = temp + " cols = %d\n" % self.cols
-
- for stat in self.stats.keys():
- temp = temp + "%s" % self.stats[stat]
-
- return temp
-
-class Database:
- def __init__(self, node):
- self.db_name = node.getAttribute("db_name")
- self.db_server = node.getAttribute("db_server")
- self.db_ip = node.getAttribute("db_ip")
- self.db_user = node.getAttribute("db_user")
- self.db_type = node.getAttribute("db_type")
- self.db_pass = node.getAttribute("db_pass")
-
- def __str__(self):
- temp = 'Database = ' + self.db_name + '\n'
- for key in dir(self):
- if key.startswith('__'): continue
- value = getattr(self, key)
- if callable(value): continue
- temp = temp + ' ' + key + " = " + value + "\n"
- return temp
-
-class Mucked:
- def __init__(self, node):
- self.name = node.getAttribute("mw_name")
- self.cards = node.getAttribute("deck")
- self.card_wd = node.getAttribute("card_wd")
- self.card_ht = node.getAttribute("card_ht")
- self.rows = node.getAttribute("rows")
- self.cols = node.getAttribute("cols")
- self.format = node.getAttribute("stud")
-
- def __str__(self):
- temp = 'Mucked = ' + self.name + "\n"
- for key in dir(self):
- if key.startswith('__'): continue
- value = getattr(self, key)
- if callable(value): continue
- temp = temp + ' ' + key + " = " + value + "\n"
- return temp
-
-class Popup:
- def __init__(self, node):
- self.name = node.getAttribute("pu_name")
- self.pu_stats = []
- for stat_node in node.getElementsByTagName('pu_stat'):
- self.pu_stats.append(stat_node.getAttribute("pu_stat_name"))
-
- def __str__(self):
- temp = "Popup = " + self.name + "\n"
- for stat in self.pu_stats:
- temp = temp + " " + stat
- return temp + "\n"
-
-class Import:
- def __init__(self, node):
- self.interval = node.getAttribute("interval")
- self.callFpdbHud = node.getAttribute("callFpdbHud")
-
- def __str__(self):
- return " interval = %s\n callFpdbHud = %s\n" % (self.interval, self.callFpdbHud)
-
-class Tv:
- def __init__(self, node):
- self.combinedStealFold = node.getAttribute("combinedStealFold")
- self.combined2B3B = node.getAttribute("combined2B3B")
- self.combinedPostflop = node.getAttribute("combinedPostflop")
-
- def __str__(self):
- return (" combinedStealFold = %s\n combined2B3B = %s\n combinedPostflop = %s\n" %
- (self.combinedStealFold, self.combined2B3B, self.combinedPostflop) )
-
-class Config:
- def __init__(self, file = None):
-
-# "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
-
- self.default_config_path = self.get_default_config_path()
- if not file == None: # configuration file path has been passed
- if not os.path.exists(file):
- print "Configuration file %s not found. Using defaults." % (file)
- sys.stderr.write("Configuration file %s not found. Using defaults." % (file))
- file = None
-
- if file == None: # configuration file path not passed or invalid
- file = self.find_config() #Look for a config file in the normal places
-
- if file == None: # no config file in the normal places
- file = self.find_example_config() #Look for an example file to edit
- if not file == None:
- pass
-
- if file == None: # that didn't work either, just die
- print "No HUD_config_xml found. Exiting"
- sys.stderr.write("No HUD_config_xml found. Exiting")
- sys.exit()
-
-# 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
- try:
- print "Reading configuration file %s\n" % (file)
- doc = xml.dom.minidom.parse(file)
- except:
- print "Error parsing %s. See error log file." % (file)
- traceback.print_exc(file=sys.stderr)
- print "press enter to continue"
- sys.stdin.readline()
- sys.exit()
-
- self.doc = doc
- self.file = file
- self.supported_sites = {}
- self.supported_games = {}
- self.supported_databases = {}
- self.mucked_windows = {}
- self.popup_windows = {}
-
-# s_sites = doc.getElementsByTagName("supported_sites")
- for site_node in doc.getElementsByTagName("site"):
- site = Site(node = site_node)
- self.supported_sites[site.site_name] = site
-
-# s_games = doc.getElementsByTagName("supported_games")
- for game_node in doc.getElementsByTagName("game"):
- game = Game(node = game_node)
- self.supported_games[game.game_name] = game
-
-# s_dbs = doc.getElementsByTagName("supported_databases")
- for db_node in doc.getElementsByTagName("database"):
- db = Database(node = db_node)
- self.supported_databases[db.db_name] = db
-
-# s_dbs = doc.getElementsByTagName("mucked_windows")
- for mw_node in doc.getElementsByTagName("mw"):
- mw = Mucked(node = mw_node)
- self.mucked_windows[mw.name] = mw
-
-# s_dbs = doc.getElementsByTagName("popup_windows")
- for pu_node in doc.getElementsByTagName("pu"):
- pu = Popup(node = pu_node)
- self.popup_windows[pu.name] = pu
-
- for imp_node in doc.getElementsByTagName("import"):
- imp = Import(node = imp_node)
- self.imp = imp
-
- for tv_node in doc.getElementsByTagName("tv"):
- tv = Tv(node = tv_node)
- self.tv = tv
-
- db = self.get_db_parameters('fpdb')
- if db['db-password'] == 'YOUR MYSQL PASSWORD':
- df_file = self.find_default_conf()
- if df_file == None: # this is bad
- pass
- else:
- df_parms = self.read_default_conf(df_file)
- self.set_db_parameters(db_name = 'fpdb', db_ip = df_parms['db-host'],
- db_user = df_parms['db-user'],
- db_pass = df_parms['db-password'])
- self.save(file=os.path.join(self.default_config_path, "HUD_config.xml"))
-
-
- 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):
- if os.name == 'posix':
- config_path = os.path.join(os.path.expanduser("~"), '.fpdb', 'default.conf')
- elif os.name == 'nt':
- config_path = os.path.join(os.environ["APPDATA"], 'fpdb', 'default.conf')
- else: config_path = False
-
- if config_path and os.path.exists(config_path):
- file = config_path
- else:
- file = None
- return file
-
- def read_default_conf(self, file):
- parms = {}
- fh = open(file, "r")
- for line in fh:
- line = string.strip(line)
- (key, value) = line.split('=')
- parms[key] = value
- fh.close
- 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.example' # so we use it
- print "No HUD_config.xml found, using HUD_config.xml.example.\n", \
- "A HUD_config.xml will be written. 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 will be written. You will probably have to edit it.")
- else:
- file = None
- return file
-
- def get_site_node(self, site):
- for site_node in self.doc.getElementsByTagName("site"):
- if site_node.getAttribute("site_name") == site:
- return site_node
-
- def get_db_node(self, db_name):
- for db_node in self.doc.getElementsByTagName("database"):
- if db_node.getAttribute("db_name") == db_name:
- return db_node
- return None
-
- def get_layout_node(self, site_node, layout):
- for layout_node in site_node.getElementsByTagName("layout"):
- if layout_node.getAttribute("max") == None:
- return None
- if int( layout_node.getAttribute("max") ) == int( layout ):
- return layout_node
-
- def get_location_node(self, layout_node, seat):
- for location_node in layout_node.getElementsByTagName("location"):
- if int( location_node.getAttribute("seat") ) == int( seat ):
- return location_node
-
- def save(self, file = None):
- if not file == None:
- f = open(file, 'w')
- self.doc.writexml(f)
- f.close()
- else:
- shutil.move(self.file, self.file+".backup")
- f = open(self.file, 'w')
- self.doc.writexml(f)
- f.close
-
- def edit_layout(self, site_name, max, width = None, height = None,
- fav_seat = None, locations = None):
- print "max = ", max
- site_node = self.get_site_node(site_name)
- layout_node = self.get_layout_node(site_node, max)
- if layout_node == None: return
- for i in range(1, max + 1):
- location_node = self.get_location_node(layout_node, i)
- location_node.setAttribute("x", str( locations[i-1][0] ))
- location_node.setAttribute("y", str( locations[i-1][1] ))
- self.supported_sites[site_name].layout[max].location[i] = ( locations[i-1][0], locations[i-1][1] )
-
- def get_db_parameters(self, name = None):
- if name == None: name = 'fpdb'
- db = {}
- try:
- db['db-databaseName'] = name
- db['db-host'] = self.supported_databases[name].db_ip
- db['db-user'] = self.supported_databases[name].db_user
- db['db-password'] = self.supported_databases[name].db_pass
- db['db-server'] = self.supported_databases[name].db_server
- if string.lower(self.supported_databases[name].db_server) == 'mysql':
- db['db-backend'] = 2
- elif string.lower(self.supported_databases[name].db_server) == 'postgresql':
- db['db-backend'] = 3
- else: db['db-backend'] = None # this is big trouble
- except:
- pass
- return db
-
- def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None,
- db_pass = None, db_server = None, db_type = None):
- db_node = self.get_db_node(db_name)
- if not db_node == None:
- if not db_ip == None: db_node.setAttribute("db_ip", db_ip)
- if not db_user == None: db_node.setAttribute("db_user", db_user)
- if not db_pass == None: db_node.setAttribute("db_pass", db_pass)
- if not db_server == None: db_node.setAttribute("db_server", db_server)
- if not db_type == None: db_node.setAttribute("db_type", db_type)
- if self.supported_databases.has_key(db_name):
- if not db_ip == None: self.supported_databases[db_name].dp_ip = db_ip
- if not db_user == None: self.supported_databases[db_name].dp_user = db_user
- if not db_pass == None: self.supported_databases[db_name].dp_pass = db_pass
- if not db_server == None: self.supported_databases[db_name].dp_server = db_server
- if not db_type == None: self.supported_databases[db_name].dp_type = db_type
- return
-
- def get_tv_parameters(self):
- tv = {}
- try:
- tv['combinedStealFold'] = self.tv.combinedStealFold
- tv['combined2B3B'] = self.tv.combined2B3B
- tv['combinedPostflop'] = self.tv.combinedPostflop
- except: # Default tv parameters
- tv['combinedStealFold'] = True
- tv['combined2B3B'] = True
- tv['combinedPostflop'] = True
- return tv
-
- def get_import_parameters(self):
- imp = {}
- try:
- imp['imp-callFpdbHud'] = self.imp.callFpdbHud
- imp['hud-defaultInterval'] = int(self.imp.interval)
- except: # Default import parameters
- imp['imp-callFpdbHud'] = True
- imp['hud-defaultInterval'] = 10
- return imp
-
- def get_default_paths(self, site = "PokerStars"):
- paths = {}
- try:
- paths['hud-defaultPath'] = os.path.expanduser(self.supported_sites[site].HH_path)
- paths['bulkImport-defaultPath'] = os.path.expanduser(self.supported_sites[site].HH_path)
- except:
- paths['hud-defaultPath'] = "default"
- paths['bulkImport-defaultPath'] = "default"
- return paths
-
- def get_default_colors(self, site = "PokerStars"):
- colors = {}
- if self.supported_sites[site].hudopacity == "":
- colors['hudopacity'] = 0.90
- else:
- colors['hudopacity'] = float(self.supported_sites[site].hudopacity)
- if self.supported_sites[site].hudbgcolor == "":
- colors['hudbgcolor'] = "#FFFFFF"
- else:
- colors['hudbgcolor'] = self.supported_sites[site].hudbgcolor
- if self.supported_sites[site].hudfgcolor == "":
- colors['hudfgcolor'] = "#000000"
- else:
- colors['hudfgcolor'] = self.supported_sites[site].hudfgcolor
- return colors
-
- def get_locations(self, site = "PokerStars", max = "8"):
-
- try:
- locations = self.supported_sites[site].layout[max].location
- except:
- locations = ( ( 0, 0), (684, 61), (689, 239), (692, 346),
- (586, 393), (421, 440), (267, 440), ( 0, 361),
- ( 0, 280), (121, 280), ( 46, 30) )
- return locations
-
- def get_site_parameters(self, site):
- """Returns a dict of the site parameters for the specified site"""
- if not self.supported_sites.has_key(site):
- return None
- parms = {}
- parms["converter"] = self.supported_sites[site].converter
- parms["decoder"] = self.supported_sites[site].decoder
- parms["hudbgcolor"] = self.supported_sites[site].hudbgcolor
- parms["hudfgcolor"] = self.supported_sites[site].hudfgcolor
- parms["hudopacity"] = self.supported_sites[site].hudopacity
- parms["screen_name"] = self.supported_sites[site].screen_name
- parms["site_path"] = self.supported_sites[site].site_path
- parms["table_finder"] = self.supported_sites[site].table_finder
- parms["HH_path"] = self.supported_sites[site].HH_path
- return parms
-
- def set_site_parameters(self, site_name, converter = None, decoder = None,
- hudbgcolor = None, hudfgcolor = None,
- hudopacity = None, screen_name = None,
- site_path = None, table_finder = None,
- HH_path = None):
- """Sets the specified site parameters for the specified site."""
- site_node = self.get_site_node(site_name)
- if not db_node == None:
- if not converter == None: site_node.setAttribute("converter", converter)
- if not decoder == None: site_node.setAttribute("decoder", decoder)
- if not hudbgcolor == None: site_node.setAttribute("hudbgcolor", hudbgcolor)
- if not hudfgcolor == None: site_node.setAttribute("hudfgcolor", hudfgcolor)
- if not hudopacity == None: site_node.setAttribute("hudopacity", hudopacity)
- if not screen_name == None: site_node.setAttribute("screen_name", screen_name)
- if not site_path == None: site_node.setAttribute("site_path", site_path)
- if not table_finder == None: site_node.setAttribute("table_finder", table_finder)
- if not HH_path == None: site_node.setAttribute("HH_path", HH_path)
-
- if self.supported_databases.has_key(db_name):
- if not converter == None: self.supported_sites[site].converter = converter
- if not decoder == None: self.supported_sites[site].decoder = decoder
- if not hudbgcolor == None: self.supported_sites[site].hudbgcolor = hudbgcolor
- if not hudfgcolor == None: self.supported_sites[site].hudfgcolor = hudfgcolor
- if not hudopacity == None: self.supported_sites[site].hudopacity = hudopacity
- if not screen_name == None: self.supported_sites[site].screen_name = screen_name
- if not site_path == None: self.supported_sites[site].site_path = site_path
- if not table_finder == None: self.supported_sites[site].table_finder = table_finder
- if not HH_path == None: self.supported_sites[site].HH_path = HH_path
- return
-
-if __name__== "__main__":
- c = Config()
-
- print "\n----------- SUPPORTED SITES -----------"
- for s in c.supported_sites.keys():
- print c.supported_sites[s]
- print "----------- END SUPPORTED SITES -----------"
-
-
- print "\n----------- SUPPORTED GAMES -----------"
- for game in c.supported_games.keys():
- print c.supported_games[game]
- print "----------- END SUPPORTED GAMES -----------"
-
-
- print "\n----------- SUPPORTED DATABASES -----------"
- for db in c.supported_databases.keys():
- print c.supported_databases[db]
- print "----------- END SUPPORTED DATABASES -----------"
-
- print "\n----------- MUCKED WINDOW FORMATS -----------"
- for w in c.mucked_windows.keys():
- print c.mucked_windows[w]
- print "----------- END MUCKED WINDOW FORMATS -----------"
-
- print "\n----------- POPUP WINDOW FORMATS -----------"
- for w in c.popup_windows.keys():
- print c.popup_windows[w]
- print "----------- END MUCKED WINDOW FORMATS -----------"
-
- print "\n----------- IMPORT -----------"
-# print c.imp
- print "----------- END IMPORT -----------"
-
- print "\n----------- TABLE VIEW -----------"
-# print c.tv
- print "----------- END TABLE VIEW -----------"
-
- c.edit_layout("PokerStars", 6, locations=( (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6) ))
- c.save(file="testout.xml")
-
- print "db = ", c.get_db_parameters()
-# print "tv = ", c.get_tv_parameters()
-# print "imp = ", c.get_import_parameters()
- print "paths = ", c.get_default_paths("PokerStars")
- print "colors = ", c.get_default_colors("PokerStars")
- print "locs = ", c.get_locations("PokerStars", 8)
- for site in c.supported_sites.keys():
- print "site = ", site,
- print c.get_site_parameters(site)
\ No newline at end of file
+#!/usr/bin/env python
+"""Configuration.py
+
+Handles HUD configuration files.
+"""
+# Copyright 2008, Ray E. Barker
+
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+########################################################################
+
+# Standard Library modules
+import os
+import sys
+import string
+import traceback
+import shutil
+import xml.dom.minidom
+from xml.dom.minidom import Node
+
+class Layout:
+ def __init__(self, max):
+ self.max = int(max)
+ self.location = []
+ for i in range(self.max + 1): self.location.append(None)
+
+ def __str__(self):
+ temp = " Layout = %d max, width= %d, height = %d, fav_seat = %d\n" % (self.max, self.width, self.height, self.fav_seat)
+ temp = temp + " Locations = "
+ for i in range(1, len(self.location)):
+ temp = temp + "(%d,%d)" % self.location[i]
+
+ return temp + "\n"
+
+class Site:
+ def __init__(self, node):
+ self.site_name = node.getAttribute("site_name")
+ self.table_finder = node.getAttribute("table_finder")
+ self.screen_name = node.getAttribute("screen_name")
+ self.site_path = node.getAttribute("site_path")
+ self.HH_path = node.getAttribute("HH_path")
+ self.decoder = node.getAttribute("decoder")
+ self.hudopacity = node.getAttribute("hudopacity")
+ self.hudbgcolor = node.getAttribute("bgcolor")
+ self.hudfgcolor = node.getAttribute("fgcolor")
+ self.converter = node.getAttribute("converter")
+ self.enabled = node.getAttribute("enabled")
+ self.aux_window = node.getAttribute("aux_window")
+ self.layout = {}
+
+ for layout_node in node.getElementsByTagName('layout'):
+ max = int( layout_node.getAttribute('max') )
+ lo = Layout(max)
+ lo.fav_seat = int( layout_node.getAttribute('fav_seat') )
+ lo.width = int( layout_node.getAttribute('width') )
+ lo.height = int( layout_node.getAttribute('height') )
+
+ for location_node in layout_node.getElementsByTagName('location'):
+ lo.location[int( location_node.getAttribute('seat') )] = (int( location_node.getAttribute('x') ), int( location_node.getAttribute('y')))
+
+ self.layout[lo.max] = lo
+
+ def __str__(self):
+ temp = "Site = " + self.site_name + "\n"
+ for key in dir(self):
+ if key.startswith('__'): continue
+ if key == 'layout': continue
+ value = getattr(self, key)
+ if callable(value): continue
+ temp = temp + ' ' + key + " = " + str(value) + "\n"
+
+ for layout in self.layout:
+ temp = temp + "%s" % self.layout[layout]
+
+ return temp
+
+class Stat:
+ def __init__(self):
+ pass
+
+ 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)
+ return temp
+
+class Game:
+ def __init__(self, node):
+ self.game_name = node.getAttribute("game_name")
+ self.db = node.getAttribute("db")
+ self.rows = int( node.getAttribute("rows") )
+ self.cols = int( node.getAttribute("cols") )
+ self.aux = node.getAttribute("aux")
+
+ self.stats = {}
+ for stat_node in node.getElementsByTagName('stat'):
+ stat = Stat()
+ stat.stat_name = stat_node.getAttribute("stat_name")
+ stat.row = int( stat_node.getAttribute("row") )
+ stat.col = int( stat_node.getAttribute("col") )
+ stat.tip = stat_node.getAttribute("tip")
+ stat.click = stat_node.getAttribute("click")
+ stat.popup = stat_node.getAttribute("popup")
+ stat.hudprefix = stat_node.getAttribute("hudprefix")
+ stat.hudsuffix = stat_node.getAttribute("hudsuffix")
+
+ self.stats[stat.stat_name] = stat
+
+ def __str__(self):
+ temp = "Game = " + self.game_name + "\n"
+ temp = temp + " db = %s\n" % self.db
+ temp = temp + " rows = %d\n" % self.rows
+ temp = temp + " cols = %d\n" % self.cols
+ temp = temp + " aux = %s\n" % self.aux
+
+ for stat in self.stats.keys():
+ temp = temp + "%s" % self.stats[stat]
+
+ return temp
+
+class Database:
+ def __init__(self, node):
+ self.db_name = node.getAttribute("db_name")
+ self.db_server = node.getAttribute("db_server")
+ self.db_ip = node.getAttribute("db_ip")
+ self.db_user = node.getAttribute("db_user")
+ self.db_type = node.getAttribute("db_type")
+ self.db_pass = node.getAttribute("db_pass")
+
+ def __str__(self):
+ temp = 'Database = ' + self.db_name + '\n'
+ for key in dir(self):
+ if key.startswith('__'): continue
+ value = getattr(self, key)
+ if callable(value): continue
+ temp = temp + ' ' + key + " = " + value + "\n"
+ return temp
+
+class Aux_window:
+ def __init__(self, node):
+ for (name, value) in node.attributes.items():
+ setattr(self, name, value)
+# self.name = node.getAttribute("mw_name")
+# self.cards = node.getAttribute("deck")
+# self.card_wd = node.getAttribute("card_wd")
+# self.card_ht = node.getAttribute("card_ht")
+# self.rows = node.getAttribute("rows")
+# self.cols = node.getAttribute("cols")
+# self.format = node.getAttribute("stud")
+
+ def __str__(self):
+ temp = 'Aux = ' + self.name + "\n"
+ for key in dir(self):
+ if key.startswith('__'): continue
+ value = getattr(self, key)
+ if callable(value): continue
+ temp = temp + ' ' + key + " = " + value + "\n"
+ return temp
+
+class Popup:
+ def __init__(self, node):
+ self.name = node.getAttribute("pu_name")
+ self.pu_stats = []
+ for stat_node in node.getElementsByTagName('pu_stat'):
+ self.pu_stats.append(stat_node.getAttribute("pu_stat_name"))
+
+ def __str__(self):
+ temp = "Popup = " + self.name + "\n"
+ for stat in self.pu_stats:
+ temp = temp + " " + stat
+ return temp + "\n"
+
+class Import:
+ def __init__(self, node):
+ self.interval = node.getAttribute("interval")
+ self.callFpdbHud = node.getAttribute("callFpdbHud")
+ self.hhArchiveBase = node.getAttribute("hhArchiveBase")
+
+ def __str__(self):
+ return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s" % (self.interval, self.callFpdbHud, self.hhArchiveBase)
+
+class Tv:
+ def __init__(self, node):
+ self.combinedStealFold = node.getAttribute("combinedStealFold")
+ self.combined2B3B = node.getAttribute("combined2B3B")
+ self.combinedPostflop = node.getAttribute("combinedPostflop")
+
+ def __str__(self):
+ return (" combinedStealFold = %s\n combined2B3B = %s\n combinedPostflop = %s\n" %
+ (self.combinedStealFold, self.combined2B3B, self.combinedPostflop) )
+
+class Config:
+ def __init__(self, file = None):
+
+# "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
+
+ self.default_config_path = self.get_default_config_path()
+ if not file == None: # configuration file path has been passed
+ if not os.path.exists(file):
+ print "Configuration file %s not found. Using defaults." % (file)
+ sys.stderr.write("Configuration file %s not found. Using defaults." % (file))
+ file = None
+
+ if file == None: # configuration file path not passed or invalid
+ file = self.find_config() #Look for a config file in the normal places
+
+ if file == None: # no config file in the normal places
+ file = self.find_example_config() #Look for an example file to edit
+ if not file == None:
+ pass
+
+ if file == None: # that didn't work either, just die
+ print "No HUD_config_xml found. Exiting"
+ sys.stderr.write("No HUD_config_xml found. Exiting")
+ sys.exit()
+
+# 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
+ try:
+ print "Reading configuration file %s\n" % (file)
+ doc = xml.dom.minidom.parse(file)
+ except:
+ print "Error parsing %s. See error log file." % (file)
+ traceback.print_exc(file=sys.stderr)
+ print "press enter to continue"
+ sys.stdin.readline()
+ sys.exit()
+
+ self.doc = doc
+ self.file = file
+ self.supported_sites = {}
+ self.supported_games = {}
+ self.supported_databases = {}
+ self.aux_windows = {}
+ self.popup_windows = {}
+
+# s_sites = doc.getElementsByTagName("supported_sites")
+ for site_node in doc.getElementsByTagName("site"):
+ site = Site(node = site_node)
+ self.supported_sites[site.site_name] = site
+
+# s_games = doc.getElementsByTagName("supported_games")
+ for game_node in doc.getElementsByTagName("game"):
+ game = Game(node = game_node)
+ self.supported_games[game.game_name] = game
+
+# s_dbs = doc.getElementsByTagName("supported_databases")
+ for db_node in doc.getElementsByTagName("database"):
+ db = Database(node = db_node)
+ self.supported_databases[db.db_name] = db
+
+# s_dbs = doc.getElementsByTagName("mucked_windows")
+ for aw_node in doc.getElementsByTagName("aw"):
+ aw = Aux_window(node = aw_node)
+ self.aux_windows[aw.name] = aw
+
+# s_dbs = doc.getElementsByTagName("popup_windows")
+ for pu_node in doc.getElementsByTagName("pu"):
+ pu = Popup(node = pu_node)
+ self.popup_windows[pu.name] = pu
+
+ for imp_node in doc.getElementsByTagName("import"):
+ imp = Import(node = imp_node)
+ self.imp = imp
+
+ for tv_node in doc.getElementsByTagName("tv"):
+ tv = Tv(node = tv_node)
+ self.tv = tv
+
+ db = self.get_db_parameters('fpdb')
+ if db['db-password'] == 'YOUR MYSQL PASSWORD':
+ df_file = self.find_default_conf()
+ if df_file == None: # this is bad
+ pass
+ else:
+ df_parms = self.read_default_conf(df_file)
+ self.set_db_parameters(db_name = 'fpdb', db_ip = df_parms['db-host'],
+ db_user = df_parms['db-user'],
+ db_pass = df_parms['db-password'])
+ self.save(file=os.path.join(self.default_config_path, "HUD_config.xml"))
+
+
+ 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):
+ if os.name == 'posix':
+ config_path = os.path.join(os.path.expanduser("~"), '.fpdb', 'default.conf')
+ elif os.name == 'nt':
+ config_path = os.path.join(os.environ["APPDATA"], 'fpdb', 'default.conf')
+ else: config_path = False
+
+ if config_path and os.path.exists(config_path):
+ file = config_path
+ else:
+ file = None
+ return file
+
+ def read_default_conf(self, file):
+ parms = {}
+ fh = open(file, "r")
+ for line in fh:
+ line = string.strip(line)
+ (key, value) = line.split('=')
+ parms[key] = value
+ fh.close
+ 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.example' # so we use it
+ print "No HUD_config.xml found, using HUD_config.xml.example.\n", \
+ "A HUD_config.xml will be written. 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 will be written. You will probably have to edit it.")
+ else:
+ file = None
+ return file
+
+ def get_site_node(self, site):
+ for site_node in self.doc.getElementsByTagName("site"):
+ if site_node.getAttribute("site_name") == site:
+ return site_node
+
+ def get_db_node(self, db_name):
+ for db_node in self.doc.getElementsByTagName("database"):
+ if db_node.getAttribute("db_name") == db_name:
+ return db_node
+ return None
+
+ def get_layout_node(self, site_node, layout):
+ for layout_node in site_node.getElementsByTagName("layout"):
+ if layout_node.getAttribute("max") == None:
+ return None
+ if int( layout_node.getAttribute("max") ) == int( layout ):
+ return layout_node
+
+ def get_location_node(self, layout_node, seat):
+ for location_node in layout_node.getElementsByTagName("location"):
+ if int( location_node.getAttribute("seat") ) == int( seat ):
+ return location_node
+
+ def save(self, file = None):
+ if not file == None:
+ f = open(file, 'w')
+ self.doc.writexml(f)
+ f.close()
+ else:
+ shutil.move(self.file, self.file+".backup")
+ f = open(self.file, 'w')
+ self.doc.writexml(f)
+ f.close
+
+ def edit_layout(self, site_name, max, width = None, height = None,
+ fav_seat = None, locations = None):
+ site_node = self.get_site_node(site_name)
+ layout_node = self.get_layout_node(site_node, max)
+ if layout_node == None: return
+ for i in range(1, max + 1):
+ location_node = self.get_location_node(layout_node, i)
+ location_node.setAttribute("x", str( locations[i-1][0] ))
+ location_node.setAttribute("y", str( locations[i-1][1] ))
+ self.supported_sites[site_name].layout[max].location[i] = ( locations[i-1][0], locations[i-1][1] )
+
+ def get_db_parameters(self, name = None):
+ if name == None: name = 'fpdb'
+ db = {}
+ try:
+ db['db-databaseName'] = name
+ db['db-host'] = self.supported_databases[name].db_ip
+ db['db-user'] = self.supported_databases[name].db_user
+ db['db-password'] = self.supported_databases[name].db_pass
+ db['db-server'] = self.supported_databases[name].db_server
+ if string.lower(self.supported_databases[name].db_server) == 'mysql':
+ db['db-backend'] = 2
+ elif string.lower(self.supported_databases[name].db_server) == 'postgresql':
+ db['db-backend'] = 3
+ else: db['db-backend'] = None # this is big trouble
+ except:
+ pass
+ return db
+
+ def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None,
+ db_pass = None, db_server = None, db_type = None):
+ db_node = self.get_db_node(db_name)
+ if not db_node == None:
+ if not db_ip == None: db_node.setAttribute("db_ip", db_ip)
+ if not db_user == None: db_node.setAttribute("db_user", db_user)
+ if not db_pass == None: db_node.setAttribute("db_pass", db_pass)
+ if not db_server == None: db_node.setAttribute("db_server", db_server)
+ if not db_type == None: db_node.setAttribute("db_type", db_type)
+ if self.supported_databases.has_key(db_name):
+ if not db_ip == None: self.supported_databases[db_name].dp_ip = db_ip
+ if not db_user == None: self.supported_databases[db_name].dp_user = db_user
+ if not db_pass == None: self.supported_databases[db_name].dp_pass = db_pass
+ if not db_server == None: self.supported_databases[db_name].dp_server = db_server
+ if not db_type == None: self.supported_databases[db_name].dp_type = db_type
+ return
+
+ def get_tv_parameters(self):
+ tv = {}
+ try:
+ tv['combinedStealFold'] = self.tv.combinedStealFold
+ tv['combined2B3B'] = self.tv.combined2B3B
+ tv['combinedPostflop'] = self.tv.combinedPostflop
+ except: # Default tv parameters
+ tv['combinedStealFold'] = True
+ tv['combined2B3B'] = True
+ tv['combinedPostflop'] = True
+ return tv
+
+ def get_import_parameters(self):
+ imp = {}
+ try:
+ imp['callFpdbHud'] = self.callFpdbHud
+ imp['interval'] = self.interval
+ imp['hhArchiveBase'] = self.hhArchiveBase
+ except: # Default params
+ imp['callFpdbHud'] = True
+ imp['interval'] = 10
+ imp['hhArchiveBase'] = "~/.fpdb/HandHistories/"
+ return imp
+
+ def get_default_paths(self, site = "PokerStars"):
+ paths = {}
+ try:
+ paths['hud-defaultPath'] = os.path.expanduser(self.supported_sites[site].HH_path)
+ paths['bulkImport-defaultPath'] = os.path.expanduser(self.supported_sites[site].HH_path)
+ except:
+ paths['hud-defaultPath'] = "default"
+ paths['bulkImport-defaultPath'] = "default"
+ return paths
+
+ def get_default_colors(self, site = "PokerStars"):
+ colors = {}
+ if self.supported_sites[site].hudopacity == "":
+ colors['hudopacity'] = 0.90
+ else:
+ colors['hudopacity'] = float(self.supported_sites[site].hudopacity)
+ if self.supported_sites[site].hudbgcolor == "":
+ colors['hudbgcolor'] = "#FFFFFF"
+ else:
+ colors['hudbgcolor'] = self.supported_sites[site].hudbgcolor
+ if self.supported_sites[site].hudfgcolor == "":
+ colors['hudfgcolor'] = "#000000"
+ else:
+ colors['hudfgcolor'] = self.supported_sites[site].hudfgcolor
+ return colors
+
+ def get_locations(self, site = "PokerStars", max = "8"):
+
+ try:
+ locations = self.supported_sites[site].layout[max].location
+ except:
+ locations = ( ( 0, 0), (684, 61), (689, 239), (692, 346),
+ (586, 393), (421, 440), (267, 440), ( 0, 361),
+ ( 0, 280), (121, 280), ( 46, 30) )
+ return locations
+
+ def get_supported_sites(self):
+ """Returns the list of supported sites."""
+ return self.supported_sites.keys()
+
+ def get_site_parameters(self, site):
+ """Returns a dict of the site parameters for the specified site"""
+ if not self.supported_sites.has_key(site):
+ return None
+ parms = {}
+ parms["converter"] = self.supported_sites[site].converter
+ parms["decoder"] = self.supported_sites[site].decoder
+ parms["hudbgcolor"] = self.supported_sites[site].hudbgcolor
+ parms["hudfgcolor"] = self.supported_sites[site].hudfgcolor
+ parms["hudopacity"] = self.supported_sites[site].hudopacity
+ parms["screen_name"] = self.supported_sites[site].screen_name
+ parms["site_path"] = self.supported_sites[site].site_path
+ parms["table_finder"] = self.supported_sites[site].table_finder
+ parms["HH_path"] = self.supported_sites[site].HH_path
+ parms["site_name"] = self.supported_sites[site].site_name
+ parms["enabled"] = self.supported_sites[site].enabled
+ parms["aux_window"] = self.supported_sites[site].aux_window
+ return parms
+
+ def set_site_parameters(self, site_name, converter = None, decoder = None,
+ hudbgcolor = None, hudfgcolor = None,
+ hudopacity = None, screen_name = None,
+ site_path = None, table_finder = None,
+ HH_path = None, enabled = None):
+ """Sets the specified site parameters for the specified site."""
+ site_node = self.get_site_node(site_name)
+ if not db_node == None:
+ if not converter == None: site_node.setAttribute("converter", converter)
+ if not decoder == None: site_node.setAttribute("decoder", decoder)
+ if not hudbgcolor == None: site_node.setAttribute("hudbgcolor", hudbgcolor)
+ if not hudfgcolor == None: site_node.setAttribute("hudfgcolor", hudfgcolor)
+ if not hudopacity == None: site_node.setAttribute("hudopacity", hudopacity)
+ if not screen_name == None: site_node.setAttribute("screen_name", screen_name)
+ if not site_path == None: site_node.setAttribute("site_path", site_path)
+ if not table_finder == None: site_node.setAttribute("table_finder", table_finder)
+ if not HH_path == None: site_node.setAttribute("HH_path", HH_path)
+ if not enabled == None: site_node.setAttribute("enabled", enabled)
+
+ if self.supported_databases.has_key(db_name):
+ if not converter == None: self.supported_sites[site].converter = converter
+ if not decoder == None: self.supported_sites[site].decoder = decoder
+ if not hudbgcolor == None: self.supported_sites[site].hudbgcolor = hudbgcolor
+ if not hudfgcolor == None: self.supported_sites[site].hudfgcolor = hudfgcolor
+ if not hudopacity == None: self.supported_sites[site].hudopacity = hudopacity
+ if not screen_name == None: self.supported_sites[site].screen_name = screen_name
+ if not site_path == None: self.supported_sites[site].site_path = site_path
+ if not table_finder == None: self.supported_sites[site].table_finder = table_finder
+ if not HH_path == None: self.supported_sites[site].HH_path = HH_path
+ if not enabled == None: self.supported_sites[site].enabled = enabled
+ return
+
+ def get_aux_windows(self):
+ """Gets the list of mucked window formats in the configuration."""
+ mw = []
+ for w in self.aux_windows.keys():
+ mw.append(w)
+ return mw
+
+ def get_aux_parameters(self, name):
+ """Gets a dict of mucked window parameters from the named mw."""
+ param = {}
+ if self.aux_windows.has_key(name):
+ for key in dir(self.aux_windows[name]):
+ if key.startswith('__'): continue
+ value = getattr(self.aux_windows[name], key)
+ if callable(value): continue
+ param[key] = value
+
+ return param
+ return None
+
+ def get_game_parameters(self, name):
+ """Get the configuration parameters for the named game."""
+ param = {}
+ if self.supported_games.has_key(name):
+ param['game_name'] = self.supported_games[name].game_name
+ param['db'] = self.supported_games[name].db
+ param['rows'] = self.supported_games[name].rows
+ param['cols'] = self.supported_games[name].cols
+ param['aux'] = self.supported_games[name].aux
+ return param
+
+ def get_supported_games(self):
+ """Get the list of supported games."""
+ sg = []
+ for game in c.supported_games.keys():
+ sg.append(c.supported_games[game].game_name)
+ return sg
+
+if __name__== "__main__":
+ c = Config()
+
+ print "\n----------- SUPPORTED SITES -----------"
+ for s in c.supported_sites.keys():
+ print c.supported_sites[s]
+ print "----------- END SUPPORTED SITES -----------"
+
+
+ print "\n----------- SUPPORTED GAMES -----------"
+ for game in c.supported_games.keys():
+ print c.supported_games[game]
+ print "----------- END SUPPORTED GAMES -----------"
+
+
+ print "\n----------- SUPPORTED DATABASES -----------"
+ for db in c.supported_databases.keys():
+ print c.supported_databases[db]
+ print "----------- END SUPPORTED DATABASES -----------"
+
+ print "\n----------- AUX WINDOW FORMATS -----------"
+ for w in c.aux_windows.keys():
+ print c.aux_windows[w]
+ print "----------- END AUX WINDOW FORMATS -----------"
+
+ print "\n----------- POPUP WINDOW FORMATS -----------"
+ for w in c.popup_windows.keys():
+ print c.popup_windows[w]
+ print "----------- END POPUP WINDOW FORMATS -----------"
+
+ print "\n----------- IMPORT -----------"
+ tmp = c.get_import_parameters()
+ for param in tmp:
+ print " " + str(param) + ": " + str(tmp[param])
+ print "----------- END IMPORT -----------"
+
+ print "\n----------- TABLE VIEW -----------"
+# print c.tv
+ print "----------- END TABLE VIEW -----------"
+
+ c.edit_layout("PokerStars", 6, locations=( (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6) ))
+ c.save(file="testout.xml")
+
+ print "db = ", c.get_db_parameters()
+# print "tv = ", c.get_tv_parameters()
+# print "imp = ", c.get_import_parameters()
+ print "paths = ", c.get_default_paths("PokerStars")
+ print "colors = ", c.get_default_colors("PokerStars")
+ print "locs = ", c.get_locations("PokerStars", 8)
+ for mw in c.get_aux_windows():
+ print c.get_aux_parameters(mw)
+
+ for site in c.supported_sites.keys():
+ print "site = ", site,
+ print c.get_site_parameters(site)
+
+ for game in c.get_supported_games():
+ print c.get_game_parameters(game)
diff --git a/pyfpdb/FpdbSQLQueries.py b/pyfpdb/FpdbSQLQueries.py
index e582c681..9b791f5d 100644
--- a/pyfpdb/FpdbSQLQueries.py
+++ b/pyfpdb/FpdbSQLQueries.py
@@ -601,7 +601,34 @@ class FpdbSQLQueries:
WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)
ORDER BY handStart"""
- # Returns the profit for a given ring game handId, Total pot - money invested by playerId
+ # Returns the profit for all hands, Total pot - money invested by playerId
+ if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
+ self.query['getRingProfitAllHandsPlayerIdSite'] = """
+ SELECT hp.handId, hp.winnings, SUM(ha.amount) costs, hp.winnings - SUM(ha.amount) profit
+ FROM HandsPlayers hp
+ INNER JOIN Players pl ON hp.playerId = pl.id
+ INNER JOIN Hands h ON h.id = hp.handId
+ INNER JOIN HandsActions ha ON ha.handPlayerId = hp.id
+ WHERE pl.name = %s
+ AND pl.siteId = %s
+ AND hp.tourneysPlayersId IS NULL
+ group by hp.handId, hp.winnings, h.handStart
+ ORDER BY h.handStart"""
+ elif(self.dbname == 'SQLite'):
+ #May not work.
+ self.query['getRingProfitAllHandsPlayerIdSite'] = """
+ SELECT hp.handId, hp.winnings, SUM(ha.amount) costs, hp.winnings - SUM(ha.amount) profit
+ FROM HandsPlayers hp
+ INNER JOIN Players pl ON hp.playerId = pl.id
+ INNER JOIN Hands h ON h.id = hp.handId
+ INNER JOIN HandsActions ha ON ha.handPlayerId = hp.id
+ WHERE pl.name = %s
+ AND pl.siteId = %s
+ AND hp.tourneysPlayersId IS NULL
+ group by hp.handId, hp.winnings, h.handStart
+ ORDER BY h.handStart"""
+
+ # Returns the profit for a given ring game handId, Total pot - money invested by playerId - WRONG, returns players costs
if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
diff --git a/pyfpdb/GuiAutoImport.py b/pyfpdb/GuiAutoImport.py
index 916170f0..9f07910c 100644
--- a/pyfpdb/GuiAutoImport.py
+++ b/pyfpdb/GuiAutoImport.py
@@ -1,216 +1,211 @@
-#!/usr/bin/python
-
-#Copyright 2008 Steffen Jobbagy-Felso
-#This program is free software: you can redistribute it and/or modify
-#it under the terms of the GNU Affero General Public License as published by
-#the Free Software Foundation, version 3 of the License.
-#
-#This program is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-#GNU General Public License for more details.
-#
-#You should have received a copy of the GNU Affero General Public License
-#along with this program. If not, see .
-#In the "official" distribution you can find the license in
-#agpl-3.0.txt in the docs folder of the package.
-
-import threading
-import subprocess
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-import gobject
-import os
-import time
-import fpdb_import
-
-class GuiAutoImport (threading.Thread):
- def starsBrowseClicked(self, widget, data):
- """runs when user clicks browse on auto import tab"""
- #print "start of GuiAutoImport.starsBrowseClicked"
- current_path=self.starsDirPath.get_text()
-
- dia_chooser = gtk.FileChooserDialog(title="Please choose the path that you want to auto import",
- action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
- buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
- #dia_chooser.set_current_folder(pathname)
- dia_chooser.set_filename(current_path)
- #dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
-
- response = dia_chooser.run()
- if response == gtk.RESPONSE_OK:
- #print dia_chooser.get_filename(), 'selected'
- self.starsDirPath.set_text(dia_chooser.get_filename())
- elif response == gtk.RESPONSE_CANCEL:
- print 'Closed, no files selected'
- dia_chooser.destroy()
- #end def GuiAutoImport.starsBrowseClicked
-
- def tiltBrowseClicked(self, widget, data):
- """runs when user clicks browse on auto import tab"""
- #print "start of GuiAutoImport.tiltBrowseClicked"
- current_path=self.tiltDirPath.get_text()
-
- dia_chooser = gtk.FileChooserDialog(title="Please choose the path that you want to auto import",
- action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
- buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
- #dia_chooser.set_current_folder(pathname)
- dia_chooser.set_filename(current_path)
- #dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
-
- response = dia_chooser.run()
- if response == gtk.RESPONSE_OK:
- #print dia_chooser.get_filename(), 'selected'
- self.tiltDirPath.set_text(dia_chooser.get_filename())
- elif response == gtk.RESPONSE_CANCEL:
- print 'Closed, no files selected'
- dia_chooser.destroy()
- #end def GuiAutoImport.tiltBrowseClicked
-
- def do_import(self):
- """Callback for timer to do an import iteration."""
- self.importer.runUpdated()
- print "GuiAutoImport.import_dir done"
- return True
-
- def startClicked(self, widget, data):
- """runs when user clicks start on auto import tab"""
-
-# Check to see if we have an open file handle to the HUD and open one if we do not.
-# bufsize = 1 means unbuffered
-# We need to close this file handle sometime.
-
-# TODO: Allow for importing from multiple dirs - REB 29AUG2008
-# As presently written this function does nothing if there is already a pipe open.
-# That is not correct. It should open another dir for importing while piping the
-# results to the same pipe. This means that self.path should be a a list of dirs
-# to watch.
- try: #uhhh, I don't this this is the best way to check for the existence of an attr
- getattr(self, "pipe_to_hud")
- except AttributeError:
- if os.name == 'nt':
- command = "python HUD_main.py" + " %s" % (self.database)
- bs = 0 # windows is not happy with line buffing here
- self.pipe_to_hud = subprocess.Popen(command, bufsize = bs, stdin = subprocess.PIPE,
- universal_newlines=True)
- else:
- cwd = os.getcwd()
- command = os.path.join(cwd, 'HUD_main.py')
- bs = 1
- self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
- universal_newlines=True)
-# self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
-# universal_newlines=True)
-# command = command + " %s" % (self.database)
-# print "command = ", command
-# self.pipe_to_hud = os.popen(command, 'w')
- self.starspath=self.starsDirPath.get_text()
- self.tiltpath=self.tiltDirPath.get_text()
-
-# Add directory to importer object.
- self.importer.addImportDirectory(self.starspath, True, "PokerStars", "passthrough")
- self.importer.addImportDirectory(self.tiltpath, True, "FullTilt", "passthrough")
- self.do_import()
-
- interval=int(self.intervalEntry.get_text())
- gobject.timeout_add(interval*1000, self.do_import)
- #end def GuiAutoImport.startClicked
-
- def get_vbox(self):
- """returns the vbox of this thread"""
- return self.mainVBox
- #end def get_vbox
-
- def __init__(self, settings, config, debug=True):
- """Constructor for GuiAutoImport"""
- self.settings=settings
- self.config=config
- self.importer = fpdb_import.Importer(self,self.settings)
- self.importer.setCallHud(True)
- self.importer.setMinPrint(30)
- self.importer.setQuiet(False)
- self.importer.setFailOnError(False)
- self.importer.setHandCount(0)
-# self.importer.setWatchTime()
-
- self.server=settings['db-host']
- self.user=settings['db-user']
- self.password=settings['db-password']
- self.database=settings['db-databaseName']
-
- self.mainVBox=gtk.VBox(False,1)
- self.mainVBox.show()
-
- self.settingsHBox = gtk.HBox(False, 0)
- self.mainVBox.pack_start(self.settingsHBox, False, True, 0)
- self.settingsHBox.show()
-
- self.intervalLabel = gtk.Label("Interval (ie. break) between imports in seconds:")
- self.settingsHBox.pack_start(self.intervalLabel)
- self.intervalLabel.show()
-
- self.intervalEntry=gtk.Entry()
- self.intervalEntry.set_text(str(self.settings['hud-defaultInterval']))
- self.settingsHBox.pack_start(self.intervalEntry)
- self.intervalEntry.show()
-
- self.pathHBox = gtk.HBox(False, 0)
- self.mainVBox.pack_start(self.pathHBox, False, True, 0)
- self.pathHBox.show()
-
- self.pathStarsLabel = gtk.Label("Path to PokerStars auto-import:")
- self.pathHBox.pack_start(self.pathStarsLabel, False, False, 0)
- self.pathStarsLabel.show()
-
- self.starsDirPath=gtk.Entry()
- paths = self.config.get_default_paths("PokerStars")
- self.starsDirPath.set_text(paths['hud-defaultPath'])
- self.pathHBox.pack_start(self.starsDirPath, False, True, 0)
- self.starsDirPath.show()
-
- self.browseButton=gtk.Button("Browse...")
- self.browseButton.connect("clicked", self.starsBrowseClicked, "Browse clicked")
- self.pathHBox.pack_start(self.browseButton, False, False, 0)
- self.browseButton.show()
-
- self.pathTiltLabel = gtk.Label("Path to Full Tilt auto-import:")
- self.pathHBox.pack_start(self.pathTiltLabel, False, False, 0)
- self.pathTiltLabel.show()
-
- self.tiltDirPath=gtk.Entry()
- paths = self.config.get_default_paths("Full Tilt")
- self.tiltDirPath.set_text(paths['hud-defaultPath'])
- self.pathHBox.pack_start(self.tiltDirPath, False, True, 0)
- self.tiltDirPath.show()
-
- self.browseButton=gtk.Button("Browse...")
- self.browseButton.connect("clicked", self.tiltBrowseClicked, "Browse clicked")
- self.pathHBox.pack_start(self.browseButton, False, False, 0)
- self.browseButton.show()
-
- self.startButton=gtk.Button("Start Autoimport")
- self.startButton.connect("clicked", self.startClicked, "start clicked")
- self.mainVBox.add(self.startButton)
- self.startButton.show()
- #end of GuiAutoImport.__init__
-if __name__== "__main__":
- def destroy(*args): # call back for terminating the main eventloop
- gtk.main_quit()
-
- settings = {}
- settings['db-host'] = "192.168.1.100"
- settings['db-user'] = "mythtv"
- settings['db-password'] = "mythtv"
- settings['db-databaseName'] = "fpdb"
- settings['hud-defaultInterval'] = 10
- settings['hud-defaultPath'] = 'C:/Program Files/PokerStars/HandHistory/nutOmatic'
- settings['imp-callFpdbHud'] = True
-
- i = GuiAutoImport(settings)
- main_window = gtk.Window()
- main_window.connect("destroy", destroy)
- main_window.add(i.mainVBox)
- main_window.show()
- gtk.main()
+#!/usr/bin/python
+
+#Copyright 2008 Steffen Jobbagy-Felso
+#This program is free software: you can redistribute it and/or modify
+#it under the terms of the GNU Affero General Public License as published by
+#the Free Software Foundation, version 3 of the License.
+#
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+#
+#You should have received a copy of the GNU Affero General Public License
+#along with this program. If not, see .
+#In the "official" distribution you can find the license in
+#agpl-3.0.txt in the docs folder of the package.
+
+import threading
+import subprocess
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+import gobject
+import os
+import time
+import fpdb_import
+
+
+class GuiAutoImport (threading.Thread):
+ def __init__(self, settings, config):
+ """Constructor for GuiAutoImport"""
+ self.settings=settings
+ self.config=config
+
+ imp = self.config.get_import_parameters()
+
+ print "Import parameters"
+ print imp
+
+ self.input_settings = {}
+
+ self.importer = fpdb_import.Importer(self, self.settings, self.config)
+ self.importer.setCallHud(True)
+ self.importer.setMinPrint(30)
+ self.importer.setQuiet(False)
+ self.importer.setFailOnError(False)
+ self.importer.setHandCount(0)
+# self.importer.setWatchTime()
+
+ self.server=settings['db-host']
+ self.user=settings['db-user']
+ self.password=settings['db-password']
+ self.database=settings['db-databaseName']
+
+ self.mainVBox=gtk.VBox(False,1)
+ self.mainVBox.show()
+
+ self.settingsHBox = gtk.HBox(False, 0)
+ self.mainVBox.pack_start(self.settingsHBox, False, True, 0)
+ self.settingsHBox.show()
+
+ self.intervalLabel = gtk.Label("Time between imports in seconds:")
+ self.settingsHBox.pack_start(self.intervalLabel)
+ self.intervalLabel.show()
+
+ self.intervalEntry=gtk.Entry()
+ self.intervalEntry.set_text(str(self.config.get_import_parameters().get("interval")))
+ self.settingsHBox.pack_start(self.intervalEntry)
+ self.intervalEntry.show()
+
+ self.addSites(self.mainVBox)
+
+ self.startButton=gtk.Button("Start Autoimport")
+ self.startButton.connect("clicked", self.startClicked, "start clicked")
+ self.mainVBox.add(self.startButton)
+ self.startButton.show()
+
+
+ #end of GuiAutoImport.__init__
+ def browseClicked(self, widget, data):
+ """runs when user clicks one of the browse buttons in the auto import tab"""
+ current_path=data[1].get_text()
+
+ dia_chooser = gtk.FileChooserDialog(title="Please choose the path that you want to auto import",
+ action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
+ #dia_chooser.set_current_folder(pathname)
+ dia_chooser.set_filename(current_path)
+ #dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
+
+ response = dia_chooser.run()
+ if response == gtk.RESPONSE_OK:
+ #print dia_chooser.get_filename(), 'selected'
+ data[1].set_text(dia_chooser.get_filename())
+ self.input_settings[data[0]][0] = dia_chooser.get_filename()
+ elif response == gtk.RESPONSE_CANCEL:
+ print 'Closed, no files selected'
+ dia_chooser.destroy()
+ #end def GuiAutoImport.browseClicked
+
+ def do_import(self):
+ """Callback for timer to do an import iteration."""
+ self.importer.runUpdated()
+ print "GuiAutoImport.import_dir done"
+ return True
+
+ def startClicked(self, widget, data):
+ """runs when user clicks start on auto import tab"""
+
+# Check to see if we have an open file handle to the HUD and open one if we do not.
+# bufsize = 1 means unbuffered
+# We need to close this file handle sometime.
+
+# TODO: Allow for importing from multiple dirs - REB 29AUG2008
+# As presently written this function does nothing if there is already a pipe open.
+# That is not correct. It should open another dir for importing while piping the
+# results to the same pipe. This means that self.path should be a a list of dirs
+# to watch.
+ try: #uhhh, I don't this this is the best way to check for the existence of an attr
+ getattr(self, "pipe_to_hud")
+ except AttributeError:
+ if os.name == 'nt':
+ command = "python HUD_main.py" + " %s" % (self.database)
+ bs = 0 # windows is not happy with line buffing here
+ self.pipe_to_hud = subprocess.Popen(command, bufsize = bs, stdin = subprocess.PIPE,
+ universal_newlines=True)
+ else:
+ cwd = os.getcwd()
+ command = os.path.join(cwd, 'HUD_main.py')
+ bs = 1
+ self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
+ universal_newlines=True)
+# self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
+# universal_newlines=True)
+# command = command + " %s" % (self.database)
+# print "command = ", command
+# self.pipe_to_hud = os.popen(command, 'w')
+
+# Add directories to importer object.
+ for site in self.input_settings:
+ self.importer.addImportDirectory(self.input_settings[site][0], True, site, self.input_settings[site][1])
+ print "Adding import directories - Site: " + site + " dir: "+ str(self.input_settings[site][0])
+ self.do_import()
+
+ interval=int(self.intervalEntry.get_text())
+ gobject.timeout_add(interval*1000, self.do_import)
+ #end def GuiAutoImport.startClicked
+
+ def get_vbox(self):
+ """returns the vbox of this thread"""
+ return self.mainVBox
+ #end def get_vbox
+
+ #Create the site line given required info and setup callbacks
+ #enabling and disabling sites from this interface not possible
+ #expects a box to layout the line horizontally
+ def createSiteLine(self, hbox, site, iconpath, hhpath, filter_name, active = True):
+ label = gtk.Label(site + " auto-import:")
+ hbox.pack_start(label, False, False, 0)
+ label.show()
+
+ dirPath=gtk.Entry()
+ dirPath.set_text(hhpath)
+ hbox.pack_start(dirPath, False, True, 0)
+ dirPath.show()
+
+ browseButton=gtk.Button("Browse...")
+ browseButton.connect("clicked", self.browseClicked, [site] + [dirPath])
+ hbox.pack_start(browseButton, False, False, 0)
+ browseButton.show()
+
+ label = gtk.Label(site + " filter:")
+ hbox.pack_start(label, False, False, 0)
+ label.show()
+
+ filter=gtk.Entry()
+ filter.set_text(filter_name)
+ hbox.pack_start(filter, False, True, 0)
+ filter.show()
+
+ def addSites(self, vbox):
+ for site in self.config.supported_sites.keys():
+ pathHBox = gtk.HBox(False, 0)
+ vbox.pack_start(pathHBox, False, True, 0)
+ pathHBox.show()
+
+ paths = self.config.get_default_paths(site)
+ params = self.config.get_site_parameters(site)
+ self.createSiteLine(pathHBox, site, False, paths['hud-defaultPath'], params['converter'], params['enabled'])
+ self.input_settings[site] = [paths['hud-defaultPath']] + [params['converter']]
+
+if __name__== "__main__":
+ def destroy(*args): # call back for terminating the main eventloop
+ gtk.main_quit()
+
+ settings = {}
+ settings['db-host'] = "192.168.1.100"
+ settings['db-user'] = "mythtv"
+ settings['db-password'] = "mythtv"
+ settings['db-databaseName'] = "fpdb"
+ settings['hud-defaultInterval'] = 10
+ settings['hud-defaultPath'] = 'C:/Program Files/PokerStars/HandHistory/nutOmatic'
+ settings['callFpdbHud'] = True
+
+ i = GuiAutoImport(settings)
+ main_window = gtk.Window()
+ main_window.connect("destroy", destroy)
+ main_window.add(i.mainVBox)
+ main_window.show()
+ gtk.main()
diff --git a/pyfpdb/GuiGraphViewer.py b/pyfpdb/GuiGraphViewer.py
index 7385e9fe..e4f9270e 100644
--- a/pyfpdb/GuiGraphViewer.py
+++ b/pyfpdb/GuiGraphViewer.py
@@ -87,16 +87,20 @@ class GuiGraphViewer (threading.Thread):
#end of def showClicked
def getRingProfitGraph(self, name, site):
- self.cursor.execute(self.sql.query['getRingWinningsAllGamesPlayerIdSite'], (name, site))
+ #self.cursor.execute(self.sql.query['getRingWinningsAllGamesPlayerIdSite'], (name, site))
+ self.cursor.execute(self.sql.query['getRingProfitAllHandsPlayerIdSite'], (name, site))
+ # returns (HandId,Winnings,Costs,Profit)
winnings = self.db.cursor.fetchall()
- profit=range(len(winnings))
- for i in profit:
- self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site))
- spent = self.db.cursor.fetchone()
- profit[i]=(i, winnings[i][1]-spent[0])
+ #profit=range(len(winnings))
+ #for i in profit:
+ # self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site))
+ # spent = self.db.cursor.fetchone()
+ # profit[i]=(i, winnings[i][1]-spent[0])
+
+ #y=map(lambda x:float(x[1]), profit)
+ y=map(lambda x:float(x[3]), winnings)
- y=map(lambda x:float(x[1]), profit)
line = cumsum(y)
return line/100
#end of def getRingProfitGraph
diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py
old mode 100755
new mode 100644
index f54fa9af..c0244e8d
--- a/pyfpdb/HUD_main.py
+++ b/pyfpdb/HUD_main.py
@@ -1,166 +1,171 @@
-#!/usr/bin/env python
-
-"""Hud_main.py
-
-Main for FreePokerTools HUD.
-"""
-# Copyright 2008, Ray E. Barker
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-########################################################################
-
-# to do kill window on my seat
-# to do adjust for preferred seat
-# to do allow window resizing
-# to do hud to echo, but ignore non numbers
-# to do no hud window for hero
-# to do things to add to config.xml
-# to do font and size
-# to do opacity
-
-# Standard Library modules
-import sys
-import os
-import thread
-import time
-import string
-import re
-
-errorfile = open('HUD-error.txt', 'w', 0)
-sys.stderr = errorfile
-
-# pyGTK modules
-import pygtk
-import gtk
-import gobject
-
-# FreePokerTools modules
-import Configuration
-import Database
-import Tables
-import Hud
-
-# global dict for keeping the huds
-hud_dict = {}
-
-db_connection = 0;
-config = 0;
-
-def destroy(*args): # call back for terminating the main eventloop
- gtk.main_quit()
-
-def create_HUD(new_hand_id, table, db_name, table_name, max, poker_game, db_connection, config, stat_dict):
- global hud_dict
- def idle_func():
- global hud_dict
- gtk.gdk.threads_enter()
- try:
- hud_dict[table_name] = Hud.Hud(table, max, poker_game, config, db_name)
- hud_dict[table_name].create(new_hand_id, config)
- hud_dict[table_name].update(new_hand_id, config, stat_dict)
- hud_dict[table_name].reposition_windows()
- return False
- finally:
- gtk.gdk.threads_leave()
- gobject.idle_add(idle_func)
-
-def update_HUD(new_hand_id, table_name, config, stat_dict):
- global hud_dict
- def idle_func():
- gtk.gdk.threads_enter()
- try:
- hud_dict[table_name].update(new_hand_id, config, stat_dict)
- return False
- finally:
- gtk.gdk.threads_leave()
- gobject.idle_add(idle_func)
-
-def read_stdin(): # This is the thread function
- global hud_dict
-
- db_connection = Database.Database(config, db_name, 'temp')
-# tourny_finder = re.compile('(\d+) (\d+)')
-
- while True: # wait for a new hand number on stdin
- new_hand_id = sys.stdin.readline()
- new_hand_id = string.rstrip(new_hand_id)
- if new_hand_id == "": # blank line means quit
- destroy()
-
-# delete hud_dict entries for any HUD destroyed since last iteration
- for h in hud_dict.keys():
- if hud_dict[h].deleted:
- del(hud_dict[h])
-
-# get basic info about the new hand from the db
- (table_name, max, poker_game) = db_connection.get_table_name(new_hand_id)
-
-# find out if this hand is from a tournament
- is_tournament = False
-# (t_number, s_number) = (0, 0)
-# mat_obj = tourny_finder(table_name)
-# if len(mat_obj.groups) == 2:
-# is_tournament = True
-# (t_number, s_number) = mat_obj.group(1, 2)
-
- stat_dict = db_connection.get_stats_from_hand(new_hand_id)
-
-# if a hud for this CASH table exists, just update it
- if hud_dict.has_key(table_name):
- update_HUD(new_hand_id, table_name, config, stat_dict)
-# if a hud for this TOURNAMENT table exists, just update it
-# elif hud_dict.has_key(t_number):
-# update_HUD(new_hand_id, t_number, config, stat_dict)
-# otherwise create a new hud
- else:
- if is_tournament:
- tablewindow = Tables.discover_tournament_table(config, t_number, s_number)
- if tablewindow == None:
- sys.stderr.write("table name "+table_name+" not found\n")
- else:
- create_HUD(new_hand_id, tablewindow, db_name, t_number, max, poker_game, db_connection, config, stat_dict)
- else:
- tablewindow = Tables.discover_table_by_name(config, table_name)
- if tablewindow == None:
- sys.stderr.write("table name "+table_name+" not found\n")
- else:
- create_HUD(new_hand_id, tablewindow, db_name, table_name, max, poker_game, db_connection, config, stat_dict)
-
-if __name__== "__main__":
- sys.stderr.write("HUD_main starting\n")
-
- try:
- db_name = sys.argv[1]
- except:
- db_name = 'fpdb'
- sys.stderr.write("Using db name = %s\n" % (db_name))
-
- config = Configuration.Config()
-
- gobject.threads_init() # this is required
- thread.start_new_thread(read_stdin, ()) # starts the thread
-
- main_window = gtk.Window()
- main_window.connect("destroy", destroy)
- eb = gtk.EventBox()
- label = gtk.Label('Closing this window will exit from the HUD.')
- eb.add(label)
- main_window.add(eb)
- main_window.set_title("HUD Main Window")
- main_window.show_all()
-
- gtk.main()
-
+#!/usr/bin/env python
+
+"""Hud_main.py
+
+Main for FreePokerTools HUD.
+"""
+# Copyright 2008, Ray E. Barker
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+########################################################################
+
+# to do kill window on my seat
+# to do adjust for preferred seat
+# to do allow window resizing
+# to do hud to echo, but ignore non numbers
+# to do no hud window for hero
+# to do things to add to config.xml
+# to do font and size
+# to do opacity
+
+# Standard Library modules
+import sys
+import os
+import thread
+import time
+import string
+import re
+
+errorfile = open('HUD-error.txt', 'w', 0)
+sys.stderr = errorfile
+
+# pyGTK modules
+import pygtk
+import gtk
+import gobject
+
+# FreePokerTools modules
+import Configuration
+import Database
+import Tables
+import Hud
+
+# global dict for keeping the huds
+hud_dict = {}
+
+db_connection = 0;
+config = 0;
+
+def destroy(*args): # call back for terminating the main eventloop
+ gtk.main_quit()
+
+def create_HUD(new_hand_id, table, db_name, table_name, max, poker_game, db_connection, config, stat_dict):
+ global hud_dict
+ def idle_func():
+ global hud_dict
+ gtk.gdk.threads_enter()
+ try:
+ hud_dict[table_name] = Hud.Hud(table, max, poker_game, config, db_name)
+ hud_dict[table_name].create(new_hand_id, config)
+ hud_dict[table_name].update(new_hand_id, config, stat_dict)
+ hud_dict[table_name].reposition_windows()
+ return False
+ finally:
+ gtk.gdk.threads_leave()
+ gobject.idle_add(idle_func)
+
+def update_HUD(new_hand_id, table_name, config, stat_dict):
+ global hud_dict
+ def idle_func():
+ gtk.gdk.threads_enter()
+ try:
+ hud_dict[table_name].update(new_hand_id, config, stat_dict)
+ for m in hud_dict[table_name].aux_windows:
+ m.update_gui(new_hand_id)
+ return False
+ finally:
+ gtk.gdk.threads_leave()
+ gobject.idle_add(idle_func)
+
+def read_stdin(): # This is the thread function
+ global hud_dict
+
+ db_connection = Database.Database(config, db_name, 'temp')
+ tourny_finder = re.compile('(\d+) (\d+)')
+
+ while True: # wait for a new hand number on stdin
+ new_hand_id = sys.stdin.readline()
+ new_hand_id = string.rstrip(new_hand_id)
+ if new_hand_id == "": # blank line means quit
+ destroy()
+
+# delete hud_dict entries for any HUD destroyed since last iteration
+ for h in hud_dict.keys():
+ if hud_dict[h].deleted:
+ del(hud_dict[h])
+
+# get basic info about the new hand from the db
+ (table_name, max, poker_game) = db_connection.get_table_name(new_hand_id)
+
+# find out if this hand is from a tournament
+ is_tournament = False
+ (tour_number, tab_number) = (0, 0)
+ mat_obj = tourny_finder.search(table_name)
+# if len(mat_obj.groups) == 2:
+ if mat_obj:
+ is_tournament = True
+ (tour_number, tab_number) = mat_obj.group(1, 2)
+
+ stat_dict = db_connection.get_stats_from_hand(new_hand_id)
+
+# if a hud for this CASH table exists, just update it
+ if hud_dict.has_key(table_name):
+# update the data for the aux_windows
+ for aw in hud_dict[table_name].aux_windows:
+ aw.update_data(new_hand_id)
+ update_HUD(new_hand_id, table_name, config, stat_dict)
+# if a hud for this TOURNAMENT table exists, just update it
+ elif hud_dict.has_key(tour_number):
+ update_HUD(new_hand_id, tour_number, config, stat_dict)
+# otherwise create a new hud
+ else:
+ if is_tournament:
+ tablewindow = Tables.discover_tournament_table(config, tour_number, tab_number)
+ if tablewindow == None:
+ sys.stderr.write("tournament %s, table %s not found\n" % (tour_number, tab_number))
+ else:
+ create_HUD(new_hand_id, tablewindow, db_name, tour_number, max, poker_game, db_connection, config, stat_dict)
+ else:
+ tablewindow = Tables.discover_table_by_name(config, table_name)
+ if tablewindow == None:
+ sys.stderr.write("table name "+table_name+" not found\n")
+ else:
+ create_HUD(new_hand_id, tablewindow, db_name, table_name, max, poker_game, db_connection, config, stat_dict)
+
+if __name__== "__main__":
+ sys.stderr.write("HUD_main starting\n")
+
+ try:
+ db_name = sys.argv[1]
+ except:
+ db_name = 'fpdb'
+ sys.stderr.write("Using db name = %s\n" % (db_name))
+
+ config = Configuration.Config()
+
+ gobject.threads_init() # this is required
+ thread.start_new_thread(read_stdin, ()) # starts the thread
+
+ main_window = gtk.Window()
+ main_window.connect("destroy", destroy)
+ eb = gtk.EventBox()
+ label = gtk.Label('Closing this window will exit from the HUD.')
+ eb.add(label)
+ main_window.add(eb)
+ main_window.set_title("HUD Main Window")
+ main_window.show_all()
+
+ gtk.main()
diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py
index 2490ad91..1ad38ee0 100644
--- a/pyfpdb/Hud.py
+++ b/pyfpdb/Hud.py
@@ -1,562 +1,578 @@
-#!/usr/bin/env python
-"""Hud.py
-
-Create and manage the hud overlays.
-"""
-# Copyright 2008, Ray E. Barker
-
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-########################################################################
-# Standard Library modules
-import os
-import sys
-
-# pyGTK modules
-import pygtk
-import gtk
-import pango
-import gobject
-
-# win32 modules -- only imported on windows systems
-if os.name == 'nt':
- import win32gui
- import win32con
- import win32api
-
-# FreePokerTools modules
-import Tables # needed for testing only
-import Configuration
-import Stats
-import Mucked
-import Database
-import HUD_main
-
-class Hud:
-
- def __init__(self, table, max, poker_game, config, db_name):
- self.table = table
- self.config = config
- self.poker_game = poker_game
- self.max = max
- self.db_name = db_name
- self.deleted = False
- self.stacked = True
- self.colors = config.get_default_colors(self.table.site)
-
- self.stat_windows = {}
- self.popup_windows = {}
- self.font = pango.FontDescription("Sans 8")
-
-# Set up a main window for this this instance of the HUD
- self.main_window = gtk.Window()
-# self.window.set_decorated(0)
- self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC)
- self.main_window.set_title(table.name + " FPDBHUD")
- self.main_window.connect("destroy", self.kill_hud)
- self.main_window.set_decorated(False)
- #self.main_window.set_transient_for(parent.get_toplevel())
-
- self.ebox = gtk.EventBox()
- self.label = gtk.Label("Right click to close HUD for %s\nor Save Stat Positions." % (table.name))
-
- self.label.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudbgcolor']))
- self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
-
- self.main_window.add(self.ebox)
- self.ebox.add(self.label)
- self.ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudbgcolor']))
- self.ebox.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
-
- self.main_window.move(self.table.x, self.table.y)
-
-# A popup window for the main window
- self.menu = gtk.Menu()
- self.item1 = gtk.MenuItem('Kill this HUD')
- self.menu.append(self.item1)
- self.item1.connect("activate", self.kill_hud)
- self.item1.show()
- self.item2 = gtk.MenuItem('Save Layout')
- self.menu.append(self.item2)
- self.item2.connect("activate", self.save_layout)
- self.item2.show()
- self.item3 = gtk.MenuItem('Reposition Stats')
- self.menu.append(self.item3)
- self.item3.connect("activate", self.reposition_windows)
- self.item3.show()
- self.ebox.connect_object("button-press-event", self.on_button_press, self.menu)
-
- self.main_window.show_all()
-# set_keep_above(1) for windows
- if os.name == 'nt':
- self.topify_window(self.main_window)
- else:
- self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(self.table.number) # gets a gdk handle for poker client
- self.main_window.gdkhandle = gtk.gdk.window_foreign_new(self.main_window.window.xid) # gets a gdk handle for the hud table window
- self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle) #
-
- self.main_window.set_destroy_with_parent(True)
-
- def on_button_press(self, widget, event):
- if event.button == 3:
- widget.popup(None, None, None, event.button, event.time)
- return True
- return False
-
- def kill_hud(self, args):
- for k in self.stat_windows.keys():
- self.stat_windows[k].window.destroy()
- self.main_window.destroy()
- self.deleted = True
-
- def reposition_windows(self, args):
- for w in self.stat_windows:
- self.stat_windows[w].window.move(self.stat_windows[w].x,
- self.stat_windows[w].y)
- def save_layout(self, *args):
- new_layout = []
-# todo: have the hud track the poker table's window position regularly, don't forget to update table.x and table.y.
- for sw in self.stat_windows:
- loc = self.stat_windows[sw].window.get_position()
- new_loc = (loc[0] - self.table.x, loc[1] - self.table.y)
- new_layout.append(new_loc)
-# print new_layout
- self.config.edit_layout(self.table.site, self.max, locations = new_layout)
- self.config.save()
-
- def adj_seats(self, hand, config):
- adj = range(0, self.max + 1) # default seat adjustments = no adjustment
-# does the user have a fav_seat?
- try:
- if int(config.supported_sites[self.table.site].layout[self.max].fav_seat) > 0:
- fav_seat = config.supported_sites[self.table.site].layout[self.max].fav_seat
- db_connection = Database.Database(config, self.db_name, 'temp')
- actual_seat = db_connection.get_actual_seat(hand, config.supported_sites[self.table.site].screen_name)
- db_connection.close_connection()
- for i in range(0, self.max + 1):
- j = actual_seat + i
- if j > self.max: j = j - self.max
- adj[j] = fav_seat + i
- if adj[j] > self.max: adj[j] = adj[j] - self.max
- except:
- pass
- return adj
-
- def create(self, hand, config):
-# update this hud, to the stats and players as of "hand"
-# hand is the hand id of the most recent hand played at this table
-#
-# this method also manages the creating and destruction of stat
-# windows via calls to the Stat_Window class
-
- adj = self.adj_seats(hand, config)
- loc = self.config.get_locations(self.table.site, self.max)
-
-# create the stat windows
- for i in range(1, self.max + 1):
- (x, y) = loc[adj[i]]
- if self.stat_windows.has_key(i):
- self.stat_windows[i].relocate(x, y)
- else:
- self.stat_windows[i] = Stat_Window(game = config.supported_games[self.poker_game],
- parent = self,
- table = self.table,
- x = x,
- y = y,
- seat = i,
- player_id = 'fake',
- font = self.font)
-
- self.stats = []
- for i in range(0, config.supported_games[self.poker_game].rows + 1):
- row_list = [''] * config.supported_games[self.poker_game].cols
- self.stats.append(row_list)
- for stat in config.supported_games[self.poker_game].stats.keys():
- 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].stat_name
-# self.mucked_window = gtk.Window()
-# self.m = Mucked.Mucked(self.mucked_window, self.db_connection)
-# self.mucked_window.show_all()
-
- def update(self, hand, config, stat_dict):
- self.hand = hand # this is the last hand, so it is available later
- for s in stat_dict.keys():
- try:
- self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id']
- except: # omg, we have more seats than stat windows .. damn poker sites with incorrect max seating info .. let's force 10 here
- self.max = 10
- self.create(hand, config)
- self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id']
-
- for r in range(0, config.supported_games[self.poker_game].rows):
- for c in range(0, config.supported_games[self.poker_game].cols):
- this_stat = config.supported_games[self.poker_game].stats[self.stats[r][c]]
- number = Stats.do_stat(stat_dict, player = stat_dict[s]['player_id'], stat = self.stats[r][c])
- statstring = this_stat.hudprefix + str(number[1]) + this_stat.hudsuffix
- self.stat_windows[stat_dict[s]['seat']].label[r][c].set_text(statstring)
- tip = stat_dict[s]['screen_name'] + "\n" + number[5] + "\n" + \
- number[3] + ", " + number[4]
- Stats.do_tip(self.stat_windows[stat_dict[s]['seat']].e_box[r][c], tip)
-# self.m.update(hand)
-
- def topify_window(self, window):
- """Set the specified gtk window to stayontop in MS Windows."""
-
- def windowEnumerationHandler(hwnd, resultList):
- '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
- resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
-
- unique_name = 'unique name for finding this window'
- real_name = window.get_title()
- window.set_title(unique_name)
- tl_windows = []
- win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
-
- for w in tl_windows:
- if w[1] == unique_name:
- #win32gui.ShowWindow(w[0], win32con.SW_HIDE)
- window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number))
- self.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
- self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle)
- #win32gui.ShowWindow(w[0], win32con.SW_SHOW)
-
- style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
- #style |= win32con.WS_EX_TOOLWINDOW
- #style &= ~win32con.WS_EX_APPWINDOW
- style |= win32con.WS_CLIPCHILDREN
- win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style)
-
-
- #win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE)
-
-# notify_id = (w[0],
-# 0,
-# win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,
-# win32con.WM_USER+20,
-# 0,
-# '')
-# win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, notify_id)
-#
- window.set_title(real_name)
-
-class Stat_Window:
-
- def button_press_cb(self, widget, event, *args):
-# 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-
-# and double-clicks.
- if event.button == 1: # left button event
- if event.type == gtk.gdk.BUTTON_PRESS: # left button single click
- if self.sb_click > 0: return
- self.sb_click = gobject.timeout_add(250, self.single_click, widget)
- elif event.type == gtk.gdk._2BUTTON_PRESS: # left button double click
- if self.sb_click > 0:
- gobject.source_remove(self.sb_click)
- self.sb_click = 0
- self.double_click(widget, event, *args)
-
- if event.button == 2: # middle button event
- pass
-# print "middle button clicked"
-
- if event.button == 3: # right button event
- pass
-# print "right button clicked"
-
- def single_click(self, widget):
-# Callback from the timeout in the single-click finding part of the
-# button press call back. This needs to be modified to get all the
-# arguments from the call.
-# print "left button clicked"
- self.sb_click = 0
- Popup_window(widget, self)
- return False
-
- def double_click(self, widget, event, *args):
- self.toggle_decorated(widget)
-
- def toggle_decorated(self, widget):
- top = widget.get_toplevel()
- (x, y) = top.get_position()
-
- if top.get_decorated():
- top.set_decorated(0)
- top.move(x, y)
- else:
- top.set_decorated(1)
- top.move(x, y)
-
- def relocate(self, x, y):
- self.x = x + self.table.x
- self.y = y + self.table.y
- self.window.move(self.x, self.y)
-
- def __init__(self, parent, game, table, seat, x, y, player_id, font):
- self.parent = parent # Hud object that this stat window belongs to
- self.game = game # Configuration object for the curren
- self.table = table # Table object where this is going
- self.x = x + table.x # table.x and y are the location of the table
- self.y = y + table.y # x and y are the location relative to table.x & y
- self.player_id = player_id # looks like this isn't used ;)
- self.sb_click = 0 # used to figure out button clicks
-
- self.window = gtk.Window()
- self.window.set_decorated(0)
- self.window.set_gravity(gtk.gdk.GRAVITY_STATIC)
-
- self.window.set_title("%s" % seat)
- self.window.set_property("skip-taskbar-hint", True)
- self.window.set_transient_for(parent.main_window)
-
- self.grid = gtk.Table(rows = self.game.rows, columns = self.game.cols, homogeneous = False)
- self.window.add(self.grid)
-
- self.e_box = []
- self.frame = []
- self.label = []
- for r in range(self.game.rows):
- self.e_box.append([])
- self.label.append([])
- for c in range(self.game.cols):
- self.e_box[r].append( gtk.EventBox() )
-
- self.e_box[r][c].modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudbgcolor']))
- self.e_box[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudfgcolor']))
-
- Stats.do_tip(self.e_box[r][c], 'farts')
- self.grid.attach(self.e_box[r][c], c, c+1, r, r+1, xpadding = 0, ypadding = 0)
- self.label[r].append( gtk.Label('xxx') )
-
- self.label[r][c].modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudbgcolor']))
- self.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudfgcolor']))
-
- self.e_box[r][c].add(self.label[r][c])
- self.e_box[r][c].connect("button_press_event", self.button_press_cb)
-# font = pango.FontDescription("Sans 8")
- self.label[r][c].modify_font(font)
-
- if not os.name == 'nt': # seems to be a bug in opacity on windows
- self.window.set_opacity(parent.colors['hudopacity'])
- self.window.realize
- self.window.move(self.x, self.y)
- self.window.show_all()
-# set_keep_above(1) for windows
- if os.name == 'nt': self.topify_window(self.window)
-
- def topify_window(self, window):
- """Set the specified gtk window to stayontop in MS Windows."""
-
- def windowEnumerationHandler(hwnd, resultList):
- '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
- resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
-
- unique_name = 'unique name for finding this window'
- real_name = window.get_title()
- window.set_title(unique_name)
- tl_windows = []
- win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
-
- for w in tl_windows:
- if w[1] == unique_name:
-
- #win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE)
-
-# style = win32gui.GetWindowLong(w[0], win32con.GWL_EXSTYLE)
-# style |= win32con.WS_EX_TOOLWINDOW
-# style &= ~win32con.WS_EX_APPWINDOW
-# win32gui.SetWindowLong(w[0], win32con.GWL_EXSTYLE, style)
- win32gui.ShowWindow(w[0], win32con.SW_SHOW)
- window.set_title(real_name)
-
-def destroy(*args): # call back for terminating the main eventloop
- gtk.main_quit()
-
-class Popup_window:
- def __init__(self, parent, stat_window):
- self.sb_click = 0
-
-# create the popup window
- self.window = gtk.Window()
- self.window.set_decorated(0)
- self.window.set_gravity(gtk.gdk.GRAVITY_STATIC)
-# self.window.set_keep_above(1)
- self.window.set_title("popup")
- self.window.set_property("skip-taskbar-hint", True)
- self.window.set_transient_for(parent.get_toplevel())
-
- self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
-
- self.ebox = gtk.EventBox()
- self.ebox.connect("button_press_event", self.button_press_cb)
- self.lab = gtk.Label("stuff\nstuff\nstuff")
-
-# need an event box so we can respond to clicks
- self.window.add(self.ebox)
- self.ebox.add(self.lab)
-
- self.ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudbgcolor']))
- self.ebox.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudfgcolor']))
- self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudbgcolor']))
- self.window.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudfgcolor']))
- self.lab.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudbgcolor']))
- self.lab.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudfgcolor']))
-
- self.window.realize
-
-# figure out the row, col address of the click that activated the popup
- row = 0
- col = 0
- for r in range(0, stat_window.game.rows):
- for c in range(0, stat_window.game.cols):
- if stat_window.e_box[r][c] == parent:
- row = r
- col = c
- break
-
-# figure out what popup format we're using
- popup_format = "default"
- for stat in stat_window.game.stats.keys():
- if stat_window.game.stats[stat].row == row and stat_window.game.stats[stat].col == col:
- popup_format = stat_window.game.stats[stat].popup
- break
-
-# get the list of stats to be presented from the config
- stat_list = []
- for w in stat_window.parent.config.popup_windows.keys():
- if w == popup_format:
- stat_list = stat_window.parent.config.popup_windows[w].pu_stats
- break
-
-# get a database connection
- 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
-# 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)
- db_connection.close_connection()
-
- pu_text = ""
- for s in stat_list:
- number = Stats.do_stat(stat_dict, player = int(stat_window.player_id), stat = s)
- pu_text += number[3] + "\n"
-
- self.lab.set_text(pu_text)
- self.window.show_all()
-
- self.window.set_transient_for(stat_window.main_window)
-
-# set_keep_above(1) for windows
- if os.name == 'nt': self.topify_window(self.window)
-
- def button_press_cb(self, widget, event, *args):
-# 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-
-# and double-clicks. This is the same code as in the Stat_window class
- if event.button == 1: # left button event
- if event.type == gtk.gdk.BUTTON_PRESS: # left button single click
- if self.sb_click > 0: return
- self.sb_click = gobject.timeout_add(250, self.single_click, widget)
- elif event.type == gtk.gdk._2BUTTON_PRESS: # left button double click
- if self.sb_click > 0:
- gobject.source_remove(self.sb_click)
- self.sb_click = 0
- self.double_click(widget, event, *args)
-
- if event.button == 2: # middle button event
- pass
-# print "middle button clicked"
-
- if event.button == 3: # right button event
- pass
-# print "right button clicked"
-
- def single_click(self, widget):
-# Callback from the timeout in the single-click finding part of the
-# button press call back. This needs to be modified to get all the
-# arguments from the call.
- self.sb_click = 0
- self.window.destroy()
- return False
-
- def double_click(self, widget, event, *args):
- self.toggle_decorated(widget)
-
- def toggle_decorated(self, widget):
- top = widget.get_toplevel()
- (x, y) = top.get_position()
-
- if top.get_decorated():
- top.set_decorated(0)
- top.move(x, y)
- else:
- top.set_decorated(1)
- top.move(x, y)
-
- def topify_window(self, window):
- """Set the specified gtk window to stayontop in MS Windows."""
-
- def windowEnumerationHandler(hwnd, resultList):
- '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
- resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
-
- unique_name = 'unique name for finding this window'
- real_name = window.get_title()
- window.set_title(unique_name)
- tl_windows = []
- win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
-
- for w in tl_windows:
- if w[1] == unique_name:
-# win32gui.ShowWindow(w[0], win32con.SW_HIDE)
-# style = win32gui.GetWindowLong(w[0], win32con.GWL_EXSTYLE)
-# style |= win32con.WS_EX_TOOLWINDOW
-# style &= ~win32con.WS_EX_APPWINDOW
-# win32gui.SetWindowLong(w[0], win32con.GWL_EXSTYLE, style)
-# win32gui.ShowWindow(w[0], win32con.SW_SHOW)
- win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE)
-
-# notify_id = (w[0],
-# 0,
-# win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,
-# win32con.WM_USER+20,
-# 0,
-# '')
-# win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, notify_id)
-#
- window.set_title(real_name)
-
-if __name__== "__main__":
- main_window = gtk.Window()
- main_window.connect("destroy", destroy)
- label = gtk.Label('Fake main window, blah blah, blah\nblah, blah')
- main_window.add(label)
- main_window.show_all()
-
- c = Configuration.Config()
- #tables = Tables.discover(c)
- t = Tables.discover_table_by_name(c, "Chelsea")
- if t is None:
- print "Table not found."
- db = Database.Database(c, 'fpdb', 'holdem')
-
-# for t in tables:
- win = Hud(t, 10, 'holdem', c, db)
- win.create(1, c)
-# t.get_details()
- win.update(8300, db, c)
-
- gtk.main()
+#!/usr/bin/env python
+"""Hud.py
+
+Create and manage the hud overlays.
+"""
+# Copyright 2008, Ray E. Barker
+
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+########################################################################
+# Standard Library modules
+import os
+import sys
+
+# pyGTK modules
+import pygtk
+import gtk
+import pango
+import gobject
+
+# win32 modules -- only imported on windows systems
+if os.name == 'nt':
+ import win32gui
+ import win32con
+ import win32api
+
+# FreePokerTools modules
+import Tables # needed for testing only
+import Configuration
+import Stats
+import Mucked
+import Database
+import HUD_main
+
+class Hud:
+
+ def __init__(self, table, max, poker_game, config, db_name):
+ self.table = table
+ self.config = config
+ self.poker_game = poker_game
+ self.max = max
+ self.db_name = db_name
+ self.deleted = False
+ self.stacked = True
+ self.colors = config.get_default_colors(self.table.site)
+
+ self.stat_windows = {}
+ self.popup_windows = {}
+ self.aux_windows = []
+ self.font = pango.FontDescription("Sans 8")
+
+# Set up a main window for this this instance of the HUD
+ self.main_window = gtk.Window()
+# self.window.set_decorated(0)
+ self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC)
+ self.main_window.set_title(table.name + " FPDBHUD")
+ self.main_window.connect("destroy", self.kill_hud)
+ self.main_window.set_decorated(False)
+ self.main_window.set_opacity(self.colors["hudopacity"])
+ #self.main_window.set_transient_for(parent.get_toplevel())
+
+ self.ebox = gtk.EventBox()
+# self.label = gtk.Label("Right click to close HUD for %s\nor Save Stat Positions." % (table.name))
+ self.label = gtk.Label("FPDB Menu (Right Click)\nLeft-drag to move")
+
+ self.label.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudbgcolor']))
+ self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
+
+ self.main_window.add(self.ebox)
+ self.ebox.add(self.label)
+ self.ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudbgcolor']))
+ self.ebox.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
+
+ self.main_window.move(self.table.x, self.table.y)
+
+# A popup window for the main window
+ self.menu = gtk.Menu()
+ self.item1 = gtk.MenuItem('Kill this HUD')
+ self.menu.append(self.item1)
+ self.item1.connect("activate", self.kill_hud)
+ self.item1.show()
+ self.item2 = gtk.MenuItem('Save Layout')
+ self.menu.append(self.item2)
+ self.item2.connect("activate", self.save_layout)
+ self.item2.show()
+ self.item3 = gtk.MenuItem('Reposition Stats')
+ self.menu.append(self.item3)
+ self.item3.connect("activate", self.reposition_windows)
+ self.item3.show()
+ self.ebox.connect_object("button-press-event", self.on_button_press, self.menu)
+
+ self.main_window.show_all()
+# set_keep_above(1) for windows
+ if os.name == 'nt':
+ self.topify_window(self.main_window)
+ else:
+ self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(self.table.number) # gets a gdk handle for poker client
+ self.main_window.gdkhandle = gtk.gdk.window_foreign_new(self.main_window.window.xid) # gets a gdk handle for the hud table window
+ self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle) #
+
+ self.main_window.set_destroy_with_parent(True)
+
+ def on_button_press(self, widget, event):
+ if event.button == 1:
+ self.main_window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
+ return True
+ if event.button == 3:
+ widget.popup(None, None, None, event.button, event.time)
+ return True
+ return False
+
+ def kill_hud(self, *args):
+ for k in self.stat_windows.keys():
+ self.stat_windows[k].window.destroy()
+ self.main_window.destroy()
+ self.deleted = True
+
+ def reposition_windows(self, *args):
+ for w in self.stat_windows:
+ self.stat_windows[w].window.move(self.stat_windows[w].x,
+ self.stat_windows[w].y)
+ def save_layout(self, *args):
+ new_layout = [(0, 0)] * self.max
+# todo: have the hud track the poker table's window position regularly, don't forget to update table.x and table.y.
+ for sw in self.stat_windows:
+ loc = self.stat_windows[sw].window.get_position()
+ new_loc = (loc[0] - self.table.x, loc[1] - self.table.y)
+ new_layout[self.stat_windows[sw].adj - 1] = new_loc
+ self.config.edit_layout(self.table.site, self.max, locations = new_layout)
+ self.config.save()
+
+ def adj_seats(self, hand, config):
+ adj = range(0, self.max + 1) # default seat adjustments = no adjustment
+# does the user have a fav_seat?
+ try:
+ if int(config.supported_sites[self.table.site].layout[self.max].fav_seat) > 0:
+ fav_seat = config.supported_sites[self.table.site].layout[self.max].fav_seat
+ db_connection = Database.Database(config, self.db_name, 'temp')
+ actual_seat = db_connection.get_actual_seat(hand, config.supported_sites[self.table.site].screen_name)
+ db_connection.close_connection()
+ for i in range(0, self.max + 1):
+ j = actual_seat + i
+ if j > self.max: j = j - self.max
+ adj[j] = fav_seat + i
+ if adj[j] > self.max: adj[j] = adj[j] - self.max
+ except:
+ pass
+ return adj
+
+ def create(self, hand, config):
+# update this hud, to the stats and players as of "hand"
+# hand is the hand id of the most recent hand played at this table
+#
+# this method also manages the creating and destruction of stat
+# windows via calls to the Stat_Window class
+
+ adj = self.adj_seats(hand, config)
+ loc = self.config.get_locations(self.table.site, self.max)
+
+# create the stat windows
+ for i in range(1, self.max + 1):
+ (x, y) = loc[adj[i]]
+ if self.stat_windows.has_key(i):
+ self.stat_windows[i].relocate(x, y)
+ else:
+ self.stat_windows[i] = Stat_Window(game = config.supported_games[self.poker_game],
+ parent = self,
+ table = self.table,
+ x = x,
+ y = y,
+ seat = i,
+ adj = adj[i],
+ player_id = 'fake',
+ font = self.font)
+
+ self.stats = []
+ for i in range(0, config.supported_games[self.poker_game].rows + 1):
+ row_list = [''] * config.supported_games[self.poker_game].cols
+ self.stats.append(row_list)
+ for stat in config.supported_games[self.poker_game].stats.keys():
+ 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].stat_name
+
+ game_params = config.get_game_parameters(self.poker_game)
+ if not game_params['aux'] == "":
+ aux_params = config.get_aux_parameters(game_params['aux'])
+ self.aux_windows.append(eval("%s.%s(gtk.Window(), config, 'fpdb')" % (aux_params['module'], aux_params['class'])))
+
+ def update(self, hand, config, stat_dict):
+ self.hand = hand # this is the last hand, so it is available later
+ for s in stat_dict.keys():
+ try:
+ self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id']
+ except: # omg, we have more seats than stat windows .. damn poker sites with incorrect max seating info .. let's force 10 here
+ self.max = 10
+ self.create(hand, config)
+ self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id']
+
+ for r in range(0, config.supported_games[self.poker_game].rows):
+ for c in range(0, config.supported_games[self.poker_game].cols):
+ this_stat = config.supported_games[self.poker_game].stats[self.stats[r][c]]
+ number = Stats.do_stat(stat_dict, player = stat_dict[s]['player_id'], stat = self.stats[r][c])
+ statstring = this_stat.hudprefix + str(number[1]) + this_stat.hudsuffix
+ self.stat_windows[stat_dict[s]['seat']].label[r][c].set_text(statstring)
+ tip = stat_dict[s]['screen_name'] + "\n" + number[5] + "\n" + \
+ number[3] + ", " + number[4]
+ Stats.do_tip(self.stat_windows[stat_dict[s]['seat']].e_box[r][c], tip)
+# for m in self.aux_windows:
+# m.update_data(hand)
+# m.update_gui(hand)
+
+ def topify_window(self, window):
+ """Set the specified gtk window to stayontop in MS Windows."""
+
+ def windowEnumerationHandler(hwnd, resultList):
+ '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
+ resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
+
+ unique_name = 'unique name for finding this window'
+ real_name = window.get_title()
+ window.set_title(unique_name)
+ tl_windows = []
+ win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
+
+ for w in tl_windows:
+ if w[1] == unique_name:
+ #win32gui.ShowWindow(w[0], win32con.SW_HIDE)
+ window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number))
+ self.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
+ self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle)
+ #win32gui.ShowWindow(w[0], win32con.SW_SHOW)
+
+ style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
+ #style |= win32con.WS_EX_TOOLWINDOW
+ #style &= ~win32con.WS_EX_APPWINDOW
+ style |= win32con.WS_CLIPCHILDREN
+ win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style)
+
+
+ #win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE)
+
+# notify_id = (w[0],
+# 0,
+# win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,
+# win32con.WM_USER+20,
+# 0,
+# '')
+# win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, notify_id)
+#
+ window.set_title(real_name)
+
+class Stat_Window:
+
+ def button_press_cb(self, widget, event, *args):
+# 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-
+# and double-clicks.
+
+ if event.button == 3: # right button event
+ if event.type == gtk.gdk.BUTTON_PRESS: # left button single click
+ if self.sb_click > 0: return
+ self.sb_click = gobject.timeout_add(250, self.single_click, widget)
+ elif event.type == gtk.gdk._2BUTTON_PRESS: # left button double click
+ if self.sb_click > 0:
+ gobject.source_remove(self.sb_click)
+ self.sb_click = 0
+ self.double_click(widget, event, *args)
+
+ if event.button == 2: # middle button event
+# print "middle button clicked"
+ pass
+
+ if event.button == 1: # left button event
+ if event.state & gtk.gdk.SHIFT_MASK:
+ self.window.begin_resize_drag(gtk.gdk.WINDOW_EDGE_SOUTH_EAST, event.button, int(event.x_root), int(event.y_root), event.time)
+ else:
+ self.window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
+
+ def single_click(self, widget):
+# Callback from the timeout in the single-click finding part of the
+# button press call back. This needs to be modified to get all the
+# arguments from the call.
+# print "left button clicked"
+ self.sb_click = 0
+ Popup_window(widget, self)
+ return False
+
+ def double_click(self, widget, event, *args):
+ self.toggle_decorated(widget)
+
+ def toggle_decorated(self, widget):
+ top = widget.get_toplevel()
+ (x, y) = top.get_position()
+
+ if top.get_decorated():
+ top.set_decorated(0)
+ top.move(x, y)
+ else:
+ top.set_decorated(1)
+ top.move(x, y)
+
+ def relocate(self, x, y):
+ self.x = x + self.table.x
+ self.y = y + self.table.y
+ self.window.move(self.x, self.y)
+
+ def __init__(self, parent, game, table, seat, adj, x, y, player_id, font):
+ self.parent = parent # Hud object that this stat window belongs to
+ self.game = game # Configuration object for the curren
+ self.table = table # Table object where this is going
+ self.seat = seat # seat number of his player
+ self.adj = adj # the adjusted seat number for this player
+ self.x = x + table.x # table.x and y are the location of the table
+ self.y = y + table.y # x and y are the location relative to table.x & y
+ self.player_id = player_id # looks like this isn't used ;)
+ self.sb_click = 0 # used to figure out button clicks
+
+ self.window = gtk.Window()
+ self.window.set_decorated(0)
+ self.window.set_gravity(gtk.gdk.GRAVITY_STATIC)
+
+ self.window.set_title("%s" % seat)
+ self.window.set_property("skip-taskbar-hint", True)
+ self.window.set_transient_for(parent.main_window)
+
+ self.grid = gtk.Table(rows = self.game.rows, columns = self.game.cols, homogeneous = False)
+ self.window.add(self.grid)
+
+ self.e_box = []
+ self.frame = []
+ self.label = []
+ for r in range(self.game.rows):
+ self.e_box.append([])
+ self.label.append([])
+ for c in range(self.game.cols):
+ self.e_box[r].append( gtk.EventBox() )
+
+ self.e_box[r][c].modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudbgcolor']))
+ self.e_box[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudfgcolor']))
+
+ Stats.do_tip(self.e_box[r][c], 'farts')
+ self.grid.attach(self.e_box[r][c], c, c+1, r, r+1, xpadding = 0, ypadding = 0)
+ self.label[r].append( gtk.Label('xxx') )
+
+ self.label[r][c].modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudbgcolor']))
+ self.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudfgcolor']))
+
+ self.e_box[r][c].add(self.label[r][c])
+ self.e_box[r][c].connect("button_press_event", self.button_press_cb)
+# font = pango.FontDescription("Sans 8")
+ self.label[r][c].modify_font(font)
+
+# if not os.name == 'nt': # seems to be a bug in opacity on windows
+ self.window.set_opacity(parent.colors['hudopacity'])
+
+ self.window.realize
+ self.window.move(self.x, self.y)
+ self.window.show_all()
+# set_keep_above(1) for windows
+ if os.name == 'nt': self.topify_window(self.window)
+
+ def topify_window(self, window):
+ """Set the specified gtk window to stayontop in MS Windows."""
+
+ def windowEnumerationHandler(hwnd, resultList):
+ '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
+ resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
+
+ unique_name = 'unique name for finding this window'
+ real_name = window.get_title()
+ window.set_title(unique_name)
+ tl_windows = []
+ win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
+
+ for w in tl_windows:
+ if w[1] == unique_name:
+
+ #win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE)
+
+# style = win32gui.GetWindowLong(w[0], win32con.GWL_EXSTYLE)
+# style |= win32con.WS_EX_TOOLWINDOW
+# style &= ~win32con.WS_EX_APPWINDOW
+# win32gui.SetWindowLong(w[0], win32con.GWL_EXSTYLE, style)
+ win32gui.ShowWindow(w[0], win32con.SW_SHOW)
+ window.set_title(real_name)
+
+def destroy(*args): # call back for terminating the main eventloop
+ gtk.main_quit()
+
+class Popup_window:
+ def __init__(self, parent, stat_window):
+ self.sb_click = 0
+
+# create the popup window
+ self.window = gtk.Window()
+ self.window.set_decorated(0)
+ self.window.set_gravity(gtk.gdk.GRAVITY_STATIC)
+# self.window.set_keep_above(1)
+ self.window.set_title("popup")
+ self.window.set_property("skip-taskbar-hint", True)
+ self.window.set_transient_for(parent.get_toplevel())
+
+ self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
+
+ self.ebox = gtk.EventBox()
+ self.ebox.connect("button_press_event", self.button_press_cb)
+ self.lab = gtk.Label("stuff\nstuff\nstuff")
+
+# need an event box so we can respond to clicks
+ self.window.add(self.ebox)
+ self.ebox.add(self.lab)
+
+ self.ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudbgcolor']))
+ self.ebox.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudfgcolor']))
+ self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudbgcolor']))
+ self.window.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudfgcolor']))
+ self.lab.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudbgcolor']))
+ self.lab.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudfgcolor']))
+
+ self.window.realize
+
+# figure out the row, col address of the click that activated the popup
+ row = 0
+ col = 0
+ for r in range(0, stat_window.game.rows):
+ for c in range(0, stat_window.game.cols):
+ if stat_window.e_box[r][c] == parent:
+ row = r
+ col = c
+ break
+
+# figure out what popup format we're using
+ popup_format = "default"
+ for stat in stat_window.game.stats.keys():
+ if stat_window.game.stats[stat].row == row and stat_window.game.stats[stat].col == col:
+ popup_format = stat_window.game.stats[stat].popup
+ break
+
+# get the list of stats to be presented from the config
+ stat_list = []
+ for w in stat_window.parent.config.popup_windows.keys():
+ if w == popup_format:
+ stat_list = stat_window.parent.config.popup_windows[w].pu_stats
+ break
+
+# get a database connection
+ 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
+# 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)
+ db_connection.close_connection()
+
+ pu_text = ""
+ for s in stat_list:
+ number = Stats.do_stat(stat_dict, player = int(stat_window.player_id), stat = s)
+ pu_text += number[3] + "\n"
+
+ self.lab.set_text(pu_text)
+ self.window.show_all()
+
+ self.window.set_transient_for(stat_window.window)
+
+# set_keep_above(1) for windows
+ if os.name == 'nt': self.topify_window(self.window)
+
+ def button_press_cb(self, widget, event, *args):
+# 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-
+# and double-clicks. This is the same code as in the Stat_window class
+ if event.button == 1: # left button event
+ if event.type == gtk.gdk.BUTTON_PRESS: # left button single click
+ if self.sb_click > 0: return
+ self.sb_click = gobject.timeout_add(250, self.single_click, widget)
+ elif event.type == gtk.gdk._2BUTTON_PRESS: # left button double click
+ if self.sb_click > 0:
+ gobject.source_remove(self.sb_click)
+ self.sb_click = 0
+ self.double_click(widget, event, *args)
+
+ if event.button == 2: # middle button event
+ pass
+# print "middle button clicked"
+
+ if event.button == 3: # right button event
+ pass
+# print "right button clicked"
+
+ def single_click(self, widget):
+# Callback from the timeout in the single-click finding part of the
+# button press call back. This needs to be modified to get all the
+# arguments from the call.
+ self.sb_click = 0
+ self.window.destroy()
+ return False
+
+ def double_click(self, widget, event, *args):
+ self.toggle_decorated(widget)
+
+ def toggle_decorated(self, widget):
+ top = widget.get_toplevel()
+ (x, y) = top.get_position()
+
+ if top.get_decorated():
+ top.set_decorated(0)
+ top.move(x, y)
+ else:
+ top.set_decorated(1)
+ top.move(x, y)
+
+ def topify_window(self, window):
+ """Set the specified gtk window to stayontop in MS Windows."""
+
+ def windowEnumerationHandler(hwnd, resultList):
+ '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
+ resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
+
+ unique_name = 'unique name for finding this window'
+ real_name = window.get_title()
+ window.set_title(unique_name)
+ tl_windows = []
+ win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
+
+ for w in tl_windows:
+ if w[1] == unique_name:
+# win32gui.ShowWindow(w[0], win32con.SW_HIDE)
+# style = win32gui.GetWindowLong(w[0], win32con.GWL_EXSTYLE)
+# style |= win32con.WS_EX_TOOLWINDOW
+# style &= ~win32con.WS_EX_APPWINDOW
+# win32gui.SetWindowLong(w[0], win32con.GWL_EXSTYLE, style)
+# win32gui.ShowWindow(w[0], win32con.SW_SHOW)
+ win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE)
+
+# notify_id = (w[0],
+# 0,
+# win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP,
+# win32con.WM_USER+20,
+# 0,
+# '')
+# win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, notify_id)
+#
+ window.set_title(real_name)
+
+if __name__== "__main__":
+ main_window = gtk.Window()
+ main_window.connect("destroy", destroy)
+ label = gtk.Label('Fake main window, blah blah, blah\nblah, blah')
+ main_window.add(label)
+ main_window.show_all()
+
+ c = Configuration.Config()
+ #tables = Tables.discover(c)
+ t = Tables.discover_table_by_name(c, "Chelsea")
+ if t is None:
+ print "Table not found."
+ db = Database.Database(c, 'fpdb', 'holdem')
+
+# for t in tables:
+ win = Hud(t, 10, 'holdem', c, db)
+ win.create(1, c)
+# t.get_details()
+ win.update(8300, db, c)
+
+ gtk.main()
diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py
index 9bc125f6..7ff0b18c 100644
--- a/pyfpdb/SQL.py
+++ b/pyfpdb/SQL.py
@@ -229,14 +229,21 @@ class Sql:
sum(street3CheckCallRaiseDone) AS ccr_3,
sum(street4CheckCallRaiseChance) AS ccr_opp_4,
sum(street4CheckCallRaiseDone) AS ccr_4
- FROM HudCache, Hands
- WHERE HudCache.PlayerId in
- (SELECT PlayerId FROM HandsPlayers
- WHERE handId = %s)
- AND Hands.id = %s
- AND Hands.gametypeId = HudCache.gametypeId
+ FROM Hands
+ INNER JOIN HandsPlayers ON (HandsPlayers.handId = %s)
+ INNER JOIN HudCache ON ( HudCache.PlayerId = HandsPlayers.PlayerId+0
+ AND HudCache.gametypeId+0 = Hands.gametypeId+0)
+ WHERE Hands.id = %s
GROUP BY HudCache.PlayerId
"""
+
+# FROM HudCache, Hands
+# WHERE HudCache.PlayerId in
+# (SELECT PlayerId FROM HandsPlayers
+# WHERE handId = %s)
+# AND Hands.id = %s
+# AND Hands.gametypeId = HudCache.gametypeId
+
# AND PlayerId LIKE %s
# HudCache.gametypeId AS gametypeId,
# activeSeats AS n_active,
diff --git a/pyfpdb/Stats.py b/pyfpdb/Stats.py
index 7bb9a8c5..50a502e3 100644
--- a/pyfpdb/Stats.py
+++ b/pyfpdb/Stats.py
@@ -71,6 +71,7 @@ def do_stat(stat_dict, player = 24, stat = 'vpip'):
# functions that return individual stats
def playername(stat_dict, player):
+ """ Player Name."""
return (stat_dict[player]['screen_name'],
stat_dict[player]['screen_name'],
stat_dict[player]['screen_name'],
@@ -98,6 +99,26 @@ def vpip(stat_dict, player):
'wtsd'
)
+def vpip_0(stat_dict, player):
+ """ Voluntarily put $ in the pot (no decimals)."""
+ stat = 0.0
+ try:
+ stat = float(stat_dict[player]['vpip'])/float(stat_dict[player]['n'])
+ return (stat,
+ '%2.0f' % (100*stat) + '%',
+ 'v=%2.0f' % (100*stat) + '%',
+ 'vpip=%2.0f' % (100*stat) + '%',
+ '(%d/%d)' % (stat_dict[player]['vpip'], stat_dict[player]['n']),
+ 'vpip'
+ )
+ except: return (stat,
+ '%2.0f' % (0) + '%',
+ 'w=%2.0f' % (0) + '%',
+ 'wtsd=%2.0f' % (0) + '%',
+ '(%d/%d)' % (0, 0),
+ 'wtsd'
+ )
+
def pfr(stat_dict, player):
""" Preflop (3rd street) raise."""
stat = 0.0
@@ -119,6 +140,27 @@ def pfr(stat_dict, player):
'pfr'
)
+def pfr_0(stat_dict, player):
+ """ Preflop (3rd street) raise (no decimals)."""
+ stat = 0.0
+ try:
+ stat = float(stat_dict[player]['pfr'])/float(stat_dict[player]['n'])
+ return (stat,
+ '%2.0f' % (100*stat) + '%',
+ 'p=%2.0f' % (100*stat) + '%',
+ 'pfr=%2.0f' % (100*stat) + '%',
+ '(%d/%d)' % (stat_dict[player]['pfr'], stat_dict[player]['n']),
+ 'pfr'
+ )
+ except:
+ return (stat,
+ '%2.0f' % (0) + '%',
+ 'p=%2.0f' % (0) + '%',
+ 'pfr=%2.0f' % (0) + '%',
+ '(%d/%d)' % (0, 0),
+ 'pfr'
+ )
+
def wtsd(stat_dict, player):
""" Went to SD when saw flop/4th."""
stat = 0.0
@@ -149,7 +191,7 @@ def wmsd(stat_dict, player):
'%3.1f' % (100*stat) + '%',
'w=%3.1f' % (100*stat) + '%',
'wmsd=%3.1f' % (100*stat) + '%',
- '(%f5.0/%d)' % (stat_dict[player]['wmsd'], stat_dict[player]['sd']),
+ '(%5.1f/%d)' % (float(stat_dict[player]['wmsd']), stat_dict[player]['sd']),
'% won money at showdown'
)
except:
@@ -414,6 +456,61 @@ def a_freq_4(stat_dict, player):
'(%d/%d)' % (0, 0),
'Aggression Freq flop/4th'
)
+
+def a_freq_123(stat_dict, player):
+ """ Post-Flop aggression frequency."""
+ stat = 0.0
+ try:
+ stat = float( stat_dict[player]['aggr_1'] + stat_dict[player]['aggr_2'] + stat_dict[player]['aggr_3']
+ ) / float( stat_dict[player]['saw_1'] + stat_dict[player]['saw_2'] + stat_dict[player]['saw_3']);
+ return (stat,
+ '%3.1f' % (100*stat) + '%',
+ 'afq=%3.1f' % (100*stat) + '%',
+ 'postf_aggfq=%3.1f' % (100*stat) + '%',
+ '(%d/%d)' % ( stat_dict[player]['aggr_1']
+ + stat_dict[player]['aggr_2']
+ + stat_dict[player]['aggr_3']
+ , stat_dict[player]['saw_1']
+ + stat_dict[player]['saw_2']
+ + stat_dict[player]['saw_3']
+ ),
+ 'Post-Flop Aggression Freq'
+ )
+ except:
+ return (stat,
+ '%2.0f' % (0) + '%',
+ 'a3=%2.0f' % (0) + '%',
+ 'a_fq_3=%2.0f' % (0) + '%',
+ '(%d/%d)' % (0, 0),
+ 'Post-Flop Aggression Freq'
+ )
+
+def a_freq_123_0(stat_dict, player):
+ """ Post-Flop aggression frequency (no decimals)."""
+ stat = 0.0
+ try:
+ stat = float( stat_dict[player]['aggr_1'] + stat_dict[player]['aggr_2'] + stat_dict[player]['aggr_3']) / float( stat_dict[player]['saw_1'] + stat_dict[player]['saw_2'] + stat_dict[player]['saw_3']);
+ return (stat,
+ '%2.0f' % (100*stat) + '%',
+ 'afq=%2.0f' % (100*stat) + '%',
+ 'postf_aggfq=%2.0f' % (100*stat) + '%',
+ '(%d/%d)' % ( stat_dict[player]['aggr_1']
+ + stat_dict[player]['aggr_2']
+ + stat_dict[player]['aggr_3']
+ , stat_dict[player]['saw_1']
+ + stat_dict[player]['saw_2']
+ + stat_dict[player]['saw_3']
+ ),
+ 'Post-Flop Aggression Freq'
+ )
+ except:
+ return (stat,
+ '%2.0f' % (0) + '%',
+ 'a3=%2.0f' % (0) + '%',
+ 'a_fq_3=%2.0f' % (0) + '%',
+ '(%d/%d)' % (0, 0),
+ 'Post-Flop Aggression Freq'
+ )
def cb_1(stat_dict, player):
""" Flop continuation bet."""
@@ -591,7 +688,9 @@ if __name__== "__main__":
for player in stat_dict.keys():
print "player = ", player, do_stat(stat_dict, player = player, stat = 'vpip')
+ print "player = ", player, do_stat(stat_dict, player = player, stat = 'vpip_0')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'pfr')
+ print "player = ", player, do_stat(stat_dict, player = player, stat = 'pfr_0')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'wtsd')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'saw_f')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'n')
@@ -606,6 +705,8 @@ if __name__== "__main__":
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_2')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_3')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_4')
+ print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_123')
+ print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_123_0')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_1')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_2')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_3')
@@ -613,7 +714,8 @@ if __name__== "__main__":
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_1')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_2')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_3')
- print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_4')
+ print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_4')
+ print "\n"
print "\n\nLegal stats:"
for attr in dir():
@@ -621,8 +723,8 @@ if __name__== "__main__":
if attr in ("Configuration", "Database", "GInitiallyUnowned", "gtk", "pygtk",
"player", "c", "db_connection", "do_stat", "do_tip", "stat_dict",
"h"): continue
- print attr, eval("%s.__doc__" % (attr))
+ print "%-14s %s" % (attr, eval("%s.__doc__" % (attr)))
# print " " % (attr)
- db_connection.close
+ db_connection.close_connection
diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py
old mode 100755
new mode 100644
index bec9be78..8b4af06f
--- a/pyfpdb/fpdb.py
+++ b/pyfpdb/fpdb.py
@@ -1,449 +1,449 @@
-#!/usr/bin/python
-
-#Copyright 2008 Steffen Jobbagy-Felso
-#This program is free software: you can redistribute it and/or modify
-#it under the terms of the GNU Affero General Public License as published by
-#the Free Software Foundation, version 3 of the License.
-#
-#This program is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-#GNU General Public License for more details.
-#
-#You should have received a copy of the GNU Affero General Public License
-#along with this program. If not, see .
-#In the "official" distribution you can find the license in
-#agpl-3.0.txt in the docs folder of the package.
-
-import os
-import sys
-from optparse import OptionParser
-
-
-parser = OptionParser()
-parser.add_option("-x", "--errorsToConsole", action="store_true",
- help="If passed error output will go to the console rather than .")
-(options, sys.argv) = parser.parse_args()
-
-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_."
- errorFile = open('fpdb-error-log.txt', 'w', 0)
- sys.stderr = errorFile
-
-import pygtk
-pygtk.require('2.0')
-import gtk
-
-import fpdb_db
-import fpdb_simple
-import GuiBulkImport
-import GuiTableViewer
-import GuiAutoImport
-import GuiGraphViewer
-import FpdbSQLQueries
-import Configuration
-
-class fpdb:
- def tab_clicked(self, widget, tab_name):
- """called when a tab button is clicked to activate that tab"""
- #print "start of tab_clicked"
- self.display_tab(tab_name)
- #end def tab_clicked
-
- def add_and_display_tab(self, new_tab, new_tab_name):
- """just calls the component methods"""
- self.add_tab(new_tab, new_tab_name)
- self.display_tab(new_tab_name)
- #end def add_and_display_tab
-
- def add_tab(self, new_tab, new_tab_name):
- """adds a tab, namely creates the button and displays it and appends all the relevant arrays"""
- #print "start of add_tab"
- for i in self.tab_names: #todo: check this is valid
- if i==new_tab_name:
- raise fpdb_simple.FpdbError("duplicate tab_name not permitted")
-
- self.tabs.append(new_tab)
- self.tab_names.append(new_tab_name)
-
- new_tab_sel_button=gtk.ToggleButton(new_tab_name)
- new_tab_sel_button.connect("clicked", self.tab_clicked, new_tab_name)
- self.tab_box.add(new_tab_sel_button)
- new_tab_sel_button.show()
- self.tab_buttons.append(new_tab_sel_button)
- #end def add_tab
-
- def display_tab(self, new_tab_name):
- """displays the indicated tab"""
- #print "start of display_tab, len(self.tab_names):",len(self.tab_names)
- tab_no=-1
- #if len(self.tab_names)>1:
- for i in range(len(self.tab_names)):
- #print "display_tab, new_tab_name:",new_tab_name," self.tab_names[i]:", self.tab_names[i]
- if (new_tab_name==self.tab_names[i]):
- tab_no=i
- #self.tab_buttons[i].set_active(False)
- #else:
- # tab_no=0
-
- #current_tab_no=-1
- for i in range(len(self.tab_names)):
- if self.current_tab==self.tabs[i]:
- #self.tab_buttons[i].set_active(False)
- pass
-
- if tab_no==-1:
- raise fpdb_simple.FpdbError("invalid tab_no")
- else:
- self.main_vbox.remove(self.current_tab)
- #self.current_tab.destroy()
- self.current_tab=self.tabs[tab_no]
- self.main_vbox.add(self.current_tab)
- self.tab_buttons[tab_no].set_active(True)
- self.current_tab.show()
- #end def display_tab
-
- def delete_event(self, widget, event, data=None):
- return False
- #end def delete_event
-
- def destroy(self, widget, data=None):
- self.quit(widget, data)
- #end def destroy
-
- def dia_about(self, widget, data):
- print "todo: implement dia_about"
- #end def dia_about
-
- def dia_create_del_database(self, widget, data):
- print "todo: implement dia_create_del_database"
- obtain_global_lock()
- #end def dia_create_del_database
-
- def dia_create_del_user(self, widget, data):
- print "todo: implement dia_create_del_user"
- obtain_global_lock()
- #end def dia_create_del_user
-
- def dia_database_stats(self, widget, data):
- print "todo: implement dia_database_stats"
- #string=fpdb_db.getDbStats(db, cursor)
- #end def dia_database_stats
-
- def dia_delete_db_parts(self, widget, data):
- print "todo: implement dia_delete_db_parts"
- obtain_global_lock()
- #end def dia_delete_db_parts
-
- def dia_edit_profile(self, widget=None, data=None, create_default=False, path=None):
- print "todo: implement dia_edit_profile"
- obtain_global_lock()
- #end def dia_edit_profile
-
- def dia_export_db(self, widget, data):
- print "todo: implement dia_export_db"
- obtain_global_lock()
- #end def dia_export_db
-
- def dia_get_db_root_credentials(self):
- """obtains db root credentials from user"""
- print "todo: implement dia_get_db_root_credentials"
-# user, pw=None, None
-#
-# dialog=gtk.Dialog(title="DB Credentials needed", parent=None, flags=0,
-# 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_user=gtk.Label("Username")
-# dialog.vbox.add(label_user)
-# label_user.show()
-#
-# response=dialog.run()
-# dialog.destroy()
-# return (user, pw, response)
- #end def dia_get_db_root_credentials
-
- def dia_import_db(self, widget, data):
- print "todo: implement dia_import_db"
- obtain_global_lock()
- #end def dia_import_db
-
- def dia_licensing(self, widget, data):
- print "todo: implement dia_licensing"
- #end def dia_licensing
-
- def dia_load_profile(self, widget, data):
- """Dialogue to select a file to load a profile from"""
- self.obtain_global_lock()
- chooser = gtk.FileChooserDialog(title="Please select a profile file to load",
- action=gtk.FILE_CHOOSER_ACTION_OPEN,
- buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
- chooser.set_filename(self.profile)
-
- response = chooser.run()
- chooser.destroy()
- if response == gtk.RESPONSE_OK:
- self.load_profile(chooser.get_filename())
- elif response == gtk.RESPONSE_CANCEL:
- print 'User cancelled loading profile'
- #end def dia_load_profile
-
- def dia_recreate_tables(self, widget, data):
- """Dialogue that asks user to confirm that he wants to delete and recreate the tables"""
- self.obtain_global_lock()
- dia_confirm=gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
- buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables")
- diastring=("Please confirm that you want to (re-)create the tables. If there already are tables in the database "+self.db.database+" on "+self.db.host+" they will be deleted.")
- dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted
-
- response=dia_confirm.run()
- dia_confirm.destroy()
- if response == gtk.RESPONSE_YES:
- self.db.recreate_tables()
- elif response == gtk.RESPONSE_NO:
- print 'User cancelled recreating tables'
- #end def dia_recreate_tables
-
- def dia_regression_test(self, widget, data):
- print "todo: implement dia_regression_test"
- self.obtain_global_lock()
- #end def dia_regression_test
-
- def dia_save_profile(self, widget, data):
- print "todo: implement dia_save_profile"
- #end def dia_save_profile
-
- def diaSetupWizard(self, path):
- print "todo: implement setup wizard"
- print "setup wizard not implemented - please create the default configuration file:", path
- diaSetupWizard = gtk.Dialog(title="Fatal Error - Config File Missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
-
- label = gtk.Label("Please copy the config file from the docs folder to:")
- diaSetupWizard.vbox.add(label)
- label.show()
-
- label = gtk.Label(path)
- diaSetupWizard.vbox.add(label)
- label.show()
-
- label = gtk.Label("and edit it according to the install documentation at http://fpdb.sourceforge.net")
- diaSetupWizard.vbox.add(label)
- label.show()
-
- response = diaSetupWizard.run()
- sys.exit(1)
- #end def diaSetupWizard
-
- def get_menu(self, window):
- """returns the menu for this program"""
- accel_group = gtk.AccelGroup()
- self.item_factory = gtk.ItemFactory(gtk.MenuBar, "", accel_group)
- self.item_factory.create_items(self.menu_items)
- window.add_accel_group(accel_group)
- return self.item_factory.get_widget("")
- #end def get_menu
-
- def load_profile(self):
- """Loads profile from the provided path name."""
- self.settings = {}
- if (os.sep=="/"):
- self.settings['os']="linuxmac"
- else:
- self.settings['os']="windows"
-
- self.settings.update(self.config.get_db_parameters())
- self.settings.update(self.config.get_tv_parameters())
- self.settings.update(self.config.get_import_parameters())
- self.settings.update(self.config.get_default_paths())
-
- if self.db!=None:
- self.db.disconnect()
-
- self.db = fpdb_db.fpdb_db()
- #print "end of fpdb.load_profile, databaseName:",self.settings['db-databaseName']
- self.db.connect(self.settings['db-backend'], self.settings['db-host'], self.settings['db-databaseName'], self.settings['db-user'], self.settings['db-password'])
- if self.db.wrongDbVersion:
- diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
-
- label = gtk.Label("An invalid DB version or missing tables have been detected.")
- diaDbVersionWarning.vbox.add(label)
- label.show()
-
- label = gtk.Label("This error is not necessarily fatal but it is strongly recommended that you recreate the tables by using the Database menu.")
- diaDbVersionWarning.vbox.add(label)
- label.show()
-
- label = gtk.Label("Not doing this will likely lead to misbehaviour including fpdb crashes, corrupt data etc.")
- diaDbVersionWarning.vbox.add(label)
- label.show()
-
- response = diaDbVersionWarning.run()
- diaDbVersionWarning.destroy()
-
- # Database connected to successfully, load queries to pass on to other classes
- self.querydict = FpdbSQLQueries.FpdbSQLQueries(self.db.get_backend_name())
- #end def load_profile
-
- def not_implemented(self):
- print "todo: called unimplemented menu entry (users: pls ignore this)"#remove this once more entries are implemented
- #end def not_implemented
-
- def obtain_global_lock(self):
- print "todo: implement obtain_global_lock (users: pls ignore this)"
- #end def obtain_global_lock
-
- def quit(self, widget, data):
- print "Quitting normally"
- #check if current settings differ from profile, if so offer to save or abort
- self.db.disconnect()
- gtk.main_quit()
- #end def quit_cliecked
-
- def release_global_lock(self):
- print "todo: implement release_global_lock"
- #end def release_global_lock
-
- def tab_abbreviations(self, widget, data):
- print "todo: implement tab_abbreviations"
- #end def tab_abbreviations
-
- def tab_auto_import(self, widget, data):
- """opens the auto import tab"""
- new_aimp_thread=GuiAutoImport.GuiAutoImport(self.settings, self.config)
- self.threads.append(new_aimp_thread)
- aimp_tab=new_aimp_thread.get_vbox()
- self.add_and_display_tab(aimp_tab, "Auto Import")
- #end def tab_auto_import
-
- def tab_bulk_import(self, widget, data):
- """opens a tab for bulk importing"""
- #print "start of tab_bulk_import"
- new_import_thread=GuiBulkImport.GuiBulkImport(self.db, self.settings, self.config)
- self.threads.append(new_import_thread)
- bulk_tab=new_import_thread.get_vbox()
- self.add_and_display_tab(bulk_tab, "Bulk Import")
- #end def tab_bulk_import
-
- def tab_main_help(self, widget, data):
- """Displays a tab with the main fpdb help screen"""
- #print "start of tab_main_help"
- mh_tab=gtk.Label("""Welcome to Fpdb!
-For documentation please visit our website at http://fpdb.sourceforge.net/ or check the docs directory in the fpdb folder.
-Please note that default.conf is no longer needed nor used, all configuration now happens in HUD_config.xml
-This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
- self.add_and_display_tab(mh_tab, "Help")
- #end def tab_main_help
-
- def tab_table_viewer(self, widget, data):
- """opens a table viewer tab"""
- #print "start of tab_table_viewer"
- new_tv_thread=GuiTableViewer.GuiTableViewer(self.db, self.settings)
- self.threads.append(new_tv_thread)
- tv_tab=new_tv_thread.get_vbox()
- self.add_and_display_tab(tv_tab, "Table Viewer")
- #end def tab_table_viewer
-
- def tabGraphViewer(self, widget, data):
- """opens a graph viewer tab"""
- #print "start of tabGraphViewer"
- new_gv_thread=GuiGraphViewer.GuiGraphViewer(self.db, self.settings, self.querydict, self.config)
- self.threads.append(new_gv_thread)
- gv_tab=new_gv_thread.get_vbox()
- self.add_and_display_tab(gv_tab, "Graphs")
- #end def tabGraphViewer
-
- def __init__(self):
- self.threads=[]
- self.db=None
- self.config = Configuration.Config()
- self.load_profile()
-
- self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- self.window.connect("delete_event", self.delete_event)
- self.window.connect("destroy", self.destroy)
- self.window.set_title("Free Poker DB - version: alpha9+, p143 or higher")
- self.window.set_border_width(1)
- self.window.set_size_request(1020,400)
- self.window.set_resizable(True)
-
- self.menu_items = (
- ( "/_Main", None, None, 0, "" ),
- ( "/Main/_Load Profile (broken)", "L", self.dia_load_profile, 0, None ),
- ( "/Main/_Edit Profile (todo)", "E", self.dia_edit_profile, 0, None ),
- ( "/Main/_Save Profile (todo)", None, self.dia_save_profile, 0, None ),
- ("/Main/sep1", None, None, 0, "" ),
- ("/Main/_Quit", "Q", self.quit, 0, None ),
- ("/_Import", None, None, 0, "" ),
- ("/Import/_Bulk Import", "B", self.tab_bulk_import, 0, None ),
- ("/Import/_Auto Import and HUD", "A", self.tab_auto_import, 0, None ),
- ("/Import/Auto _Rating (todo)", "R", self.not_implemented, 0, None ),
- ("/_Viewers", None, None, 0, "" ),
- ("/_Viewers/_Auto Import and HUD", "A", self.tab_auto_import, 0, None ),
- ("/Viewers/_Graphs", "G", self.tabGraphViewer, 0, None ),
- ("/Viewers/Hand _Replayer (todo)", None, self.not_implemented, 0, None ),
- ("/Viewers/Player _Details (todo)", None, self.not_implemented, 0, None ),
- ("/Viewers/_Player Stats (tabulated view) (todo)", None, self.not_implemented, 0, None ),
- ("/Viewers/Starting _Hands (todo)", None, self.not_implemented, 0, None ),
- ("/Viewers/_Session Replayer (todo)", None, self.not_implemented, 0, None ),
- ("/Viewers/Poker_table Viewer (mostly obselete)", "T", self.tab_table_viewer, 0, None ),
- #( "/Viewers/Tourney Replayer
- ( "/_Database", None, None, 0, "" ),
- ( "/Database/Create or Delete _Database (todo)", None, self.dia_create_del_database, 0, None ),
- ( "/Database/Create or Delete _User (todo)", None, self.dia_create_del_user, 0, None ),
- ( "/Database/Create or Recreate _Tables", None, self.dia_recreate_tables, 0, None ),
- ( "/Database/_Statistics (todo)", None, self.dia_database_stats, 0, None ),
- ( "/D_ebugging", None, None, 0, "" ),
- ( "/Debugging/_Delete Parts of Database (todo)", None, self.dia_delete_db_parts, 0, None ),
- ( "/Debugging/_Export DB (todo)", None, self.dia_export_db, 0, None ),
- ( "/Debugging/_Import DB (todo)", None, self.dia_import_db, 0, None ),
- ( "/Debugging/_Regression test (todo)", None, self.dia_regression_test, 0, None ),
- ( "/_Help", None, None, 0, "" ),
- ( "/Help/_Main Help", "H", self.tab_main_help, 0, None ),
- ( "/Help/_Abbrevations (todo)", None, self.tab_abbreviations, 0, None ),
- ( "/Help/sep1", None, None, 0, "" ),
- ( "/Help/A_bout (todo)", None, self.dia_about, 0, None ),
- ( "/Help/_License and Copying (todo)", None, self.dia_licensing, 0, None )
- )
-
- self.main_vbox = gtk.VBox(False, 1)
- self.main_vbox.set_border_width(1)
- self.window.add(self.main_vbox)
- self.main_vbox.show()
-
- menubar = self.get_menu(self.window)
- self.main_vbox.pack_start(menubar, False, True, 0)
- menubar.show()
- #done menubar
-
- self.tabs=[]
- self.tab_names=[]
- self.tab_buttons=[]
- self.tab_box = gtk.HBox(False,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.status_bar = gtk.Label("Status: Connected to "+self.db.get_backend_name()+" database named "+self.db.database+" on host "+self.db.host)
- self.main_vbox.pack_end(self.status_bar, False, True, 0)
- self.status_bar.show()
-
- self.window.show()
- #end def __init__
-
- def main(self):
- gtk.main()
- return 0
- #end def main
-
-if __name__ == "__main__":
- me = fpdb()
- me.main()
+#!/usr/bin/python
+
+#Copyright 2008 Steffen Jobbagy-Felso
+#This program is free software: you can redistribute it and/or modify
+#it under the terms of the GNU Affero General Public License as published by
+#the Free Software Foundation, version 3 of the License.
+#
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+#
+#You should have received a copy of the GNU Affero General Public License
+#along with this program. If not, see .
+#In the "official" distribution you can find the license in
+#agpl-3.0.txt in the docs folder of the package.
+
+import os
+import sys
+from optparse import OptionParser
+
+
+parser = OptionParser()
+parser.add_option("-x", "--errorsToConsole", action="store_true",
+ help="If passed error output will go to the console rather than .")
+(options, sys.argv) = parser.parse_args()
+
+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_."
+ errorFile = open('fpdb-error-log.txt', 'w', 0)
+ sys.stderr = errorFile
+
+import pygtk
+pygtk.require('2.0')
+import gtk
+
+import fpdb_db
+import fpdb_simple
+import GuiBulkImport
+import GuiTableViewer
+import GuiAutoImport
+import GuiGraphViewer
+import FpdbSQLQueries
+import Configuration
+
+class fpdb:
+ def tab_clicked(self, widget, tab_name):
+ """called when a tab button is clicked to activate that tab"""
+ #print "start of tab_clicked"
+ self.display_tab(tab_name)
+ #end def tab_clicked
+
+ def add_and_display_tab(self, new_tab, new_tab_name):
+ """just calls the component methods"""
+ self.add_tab(new_tab, new_tab_name)
+ self.display_tab(new_tab_name)
+ #end def add_and_display_tab
+
+ def add_tab(self, new_tab, new_tab_name):
+ """adds a tab, namely creates the button and displays it and appends all the relevant arrays"""
+ #print "start of add_tab"
+ for i in self.tab_names: #todo: check this is valid
+ if i==new_tab_name:
+ raise fpdb_simple.FpdbError("duplicate tab_name not permitted")
+
+ self.tabs.append(new_tab)
+ self.tab_names.append(new_tab_name)
+
+ new_tab_sel_button=gtk.ToggleButton(new_tab_name)
+ new_tab_sel_button.connect("clicked", self.tab_clicked, new_tab_name)
+ self.tab_box.add(new_tab_sel_button)
+ new_tab_sel_button.show()
+ self.tab_buttons.append(new_tab_sel_button)
+ #end def add_tab
+
+ def display_tab(self, new_tab_name):
+ """displays the indicated tab"""
+ #print "start of display_tab, len(self.tab_names):",len(self.tab_names)
+ tab_no=-1
+ #if len(self.tab_names)>1:
+ for i in range(len(self.tab_names)):
+ #print "display_tab, new_tab_name:",new_tab_name," self.tab_names[i]:", self.tab_names[i]
+ if (new_tab_name==self.tab_names[i]):
+ tab_no=i
+ #self.tab_buttons[i].set_active(False)
+ #else:
+ # tab_no=0
+
+ #current_tab_no=-1
+ for i in range(len(self.tab_names)):
+ if self.current_tab==self.tabs[i]:
+ #self.tab_buttons[i].set_active(False)
+ pass
+
+ if tab_no==-1:
+ raise fpdb_simple.FpdbError("invalid tab_no")
+ else:
+ self.main_vbox.remove(self.current_tab)
+ #self.current_tab.destroy()
+ self.current_tab=self.tabs[tab_no]
+ self.main_vbox.add(self.current_tab)
+ self.tab_buttons[tab_no].set_active(True)
+ self.current_tab.show()
+ #end def display_tab
+
+ def delete_event(self, widget, event, data=None):
+ return False
+ #end def delete_event
+
+ def destroy(self, widget, data=None):
+ self.quit(widget, data)
+ #end def destroy
+
+ def dia_about(self, widget, data):
+ print "todo: implement dia_about"
+ #end def dia_about
+
+ def dia_create_del_database(self, widget, data):
+ print "todo: implement dia_create_del_database"
+ obtain_global_lock()
+ #end def dia_create_del_database
+
+ def dia_create_del_user(self, widget, data):
+ print "todo: implement dia_create_del_user"
+ obtain_global_lock()
+ #end def dia_create_del_user
+
+ def dia_database_stats(self, widget, data):
+ print "todo: implement dia_database_stats"
+ #string=fpdb_db.getDbStats(db, cursor)
+ #end def dia_database_stats
+
+ def dia_delete_db_parts(self, widget, data):
+ print "todo: implement dia_delete_db_parts"
+ obtain_global_lock()
+ #end def dia_delete_db_parts
+
+ def dia_edit_profile(self, widget=None, data=None, create_default=False, path=None):
+ print "todo: implement dia_edit_profile"
+ obtain_global_lock()
+ #end def dia_edit_profile
+
+ def dia_export_db(self, widget, data):
+ print "todo: implement dia_export_db"
+ obtain_global_lock()
+ #end def dia_export_db
+
+ def dia_get_db_root_credentials(self):
+ """obtains db root credentials from user"""
+ print "todo: implement dia_get_db_root_credentials"
+# user, pw=None, None
+#
+# dialog=gtk.Dialog(title="DB Credentials needed", parent=None, flags=0,
+# 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_user=gtk.Label("Username")
+# dialog.vbox.add(label_user)
+# label_user.show()
+#
+# response=dialog.run()
+# dialog.destroy()
+# return (user, pw, response)
+ #end def dia_get_db_root_credentials
+
+ def dia_import_db(self, widget, data):
+ print "todo: implement dia_import_db"
+ obtain_global_lock()
+ #end def dia_import_db
+
+ def dia_licensing(self, widget, data):
+ print "todo: implement dia_licensing"
+ #end def dia_licensing
+
+ def dia_load_profile(self, widget, data):
+ """Dialogue to select a file to load a profile from"""
+ self.obtain_global_lock()
+ chooser = gtk.FileChooserDialog(title="Please select a profile file to load",
+ action=gtk.FILE_CHOOSER_ACTION_OPEN,
+ buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
+ chooser.set_filename(self.profile)
+
+ response = chooser.run()
+ chooser.destroy()
+ if response == gtk.RESPONSE_OK:
+ self.load_profile(chooser.get_filename())
+ elif response == gtk.RESPONSE_CANCEL:
+ print 'User cancelled loading profile'
+ #end def dia_load_profile
+
+ def dia_recreate_tables(self, widget, data):
+ """Dialogue that asks user to confirm that he wants to delete and recreate the tables"""
+ self.obtain_global_lock()
+ dia_confirm=gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
+ buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables")
+ diastring=("Please confirm that you want to (re-)create the tables. If there already are tables in the database "+self.db.database+" on "+self.db.host+" they will be deleted.")
+ dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted
+
+ response=dia_confirm.run()
+ dia_confirm.destroy()
+ if response == gtk.RESPONSE_YES:
+ self.db.recreate_tables()
+ elif response == gtk.RESPONSE_NO:
+ print 'User cancelled recreating tables'
+ #end def dia_recreate_tables
+
+ def dia_regression_test(self, widget, data):
+ print "todo: implement dia_regression_test"
+ self.obtain_global_lock()
+ #end def dia_regression_test
+
+ def dia_save_profile(self, widget, data):
+ print "todo: implement dia_save_profile"
+ #end def dia_save_profile
+
+ def diaSetupWizard(self, path):
+ print "todo: implement setup wizard"
+ print "setup wizard not implemented - please create the default configuration file:", path
+ diaSetupWizard = gtk.Dialog(title="Fatal Error - Config File Missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
+
+ label = gtk.Label("Please copy the config file from the docs folder to:")
+ diaSetupWizard.vbox.add(label)
+ label.show()
+
+ label = gtk.Label(path)
+ diaSetupWizard.vbox.add(label)
+ label.show()
+
+ label = gtk.Label("and edit it according to the install documentation at http://fpdb.sourceforge.net")
+ diaSetupWizard.vbox.add(label)
+ label.show()
+
+ response = diaSetupWizard.run()
+ sys.exit(1)
+ #end def diaSetupWizard
+
+ def get_menu(self, window):
+ """returns the menu for this program"""
+ accel_group = gtk.AccelGroup()
+ self.item_factory = gtk.ItemFactory(gtk.MenuBar, "", accel_group)
+ self.item_factory.create_items(self.menu_items)
+ window.add_accel_group(accel_group)
+ return self.item_factory.get_widget("")
+ #end def get_menu
+
+ def load_profile(self):
+ """Loads profile from the provided path name."""
+ self.settings = {}
+ if (os.sep=="/"):
+ self.settings['os']="linuxmac"
+ else:
+ self.settings['os']="windows"
+
+ self.settings.update(self.config.get_db_parameters())
+ self.settings.update(self.config.get_tv_parameters())
+ self.settings.update(self.config.get_import_parameters())
+ self.settings.update(self.config.get_default_paths())
+
+ if self.db!=None:
+ self.db.disconnect()
+
+ self.db = fpdb_db.fpdb_db()
+ #print "end of fpdb.load_profile, databaseName:",self.settings['db-databaseName']
+ self.db.connect(self.settings['db-backend'], self.settings['db-host'], self.settings['db-databaseName'], self.settings['db-user'], self.settings['db-password'])
+ if self.db.wrongDbVersion:
+ diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
+
+ label = gtk.Label("An invalid DB version or missing tables have been detected.")
+ diaDbVersionWarning.vbox.add(label)
+ label.show()
+
+ label = gtk.Label("This error is not necessarily fatal but it is strongly recommended that you recreate the tables by using the Database menu.")
+ diaDbVersionWarning.vbox.add(label)
+ label.show()
+
+ label = gtk.Label("Not doing this will likely lead to misbehaviour including fpdb crashes, corrupt data etc.")
+ diaDbVersionWarning.vbox.add(label)
+ label.show()
+
+ response = diaDbVersionWarning.run()
+ diaDbVersionWarning.destroy()
+
+ # Database connected to successfully, load queries to pass on to other classes
+ self.querydict = FpdbSQLQueries.FpdbSQLQueries(self.db.get_backend_name())
+ #end def load_profile
+
+ def not_implemented(self):
+ print "todo: called unimplemented menu entry (users: pls ignore this)"#remove this once more entries are implemented
+ #end def not_implemented
+
+ def obtain_global_lock(self):
+ print "todo: implement obtain_global_lock (users: pls ignore this)"
+ #end def obtain_global_lock
+
+ def quit(self, widget, data):
+ print "Quitting normally"
+ #check if current settings differ from profile, if so offer to save or abort
+ self.db.disconnect()
+ gtk.main_quit()
+ #end def quit_cliecked
+
+ def release_global_lock(self):
+ print "todo: implement release_global_lock"
+ #end def release_global_lock
+
+ def tab_abbreviations(self, widget, data):
+ print "todo: implement tab_abbreviations"
+ #end def tab_abbreviations
+
+ def tab_auto_import(self, widget, data):
+ """opens the auto import tab"""
+ new_aimp_thread=GuiAutoImport.GuiAutoImport(self.settings, self.config)
+ self.threads.append(new_aimp_thread)
+ aimp_tab=new_aimp_thread.get_vbox()
+ self.add_and_display_tab(aimp_tab, "Auto Import")
+ #end def tab_auto_import
+
+ def tab_bulk_import(self, widget, data):
+ """opens a tab for bulk importing"""
+ #print "start of tab_bulk_import"
+ new_import_thread=GuiBulkImport.GuiBulkImport(self.db, self.settings, self.config)
+ self.threads.append(new_import_thread)
+ bulk_tab=new_import_thread.get_vbox()
+ self.add_and_display_tab(bulk_tab, "Bulk Import")
+ #end def tab_bulk_import
+
+ def tab_main_help(self, widget, data):
+ """Displays a tab with the main fpdb help screen"""
+ #print "start of tab_main_help"
+ mh_tab=gtk.Label("""Welcome to Fpdb!
+For documentation please visit our website at http://fpdb.sourceforge.net/ or check the docs directory in the fpdb folder.
+Please note that default.conf is no longer needed nor used, all configuration now happens in HUD_config.xml
+This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
+ self.add_and_display_tab(mh_tab, "Help")
+ #end def tab_main_help
+
+ def tab_table_viewer(self, widget, data):
+ """opens a table viewer tab"""
+ #print "start of tab_table_viewer"
+ new_tv_thread=GuiTableViewer.GuiTableViewer(self.db, self.settings)
+ self.threads.append(new_tv_thread)
+ tv_tab=new_tv_thread.get_vbox()
+ self.add_and_display_tab(tv_tab, "Table Viewer")
+ #end def tab_table_viewer
+
+ def tabGraphViewer(self, widget, data):
+ """opens a graph viewer tab"""
+ #print "start of tabGraphViewer"
+ new_gv_thread=GuiGraphViewer.GuiGraphViewer(self.db, self.settings, self.querydict, self.config)
+ self.threads.append(new_gv_thread)
+ gv_tab=new_gv_thread.get_vbox()
+ self.add_and_display_tab(gv_tab, "Graphs")
+ #end def tabGraphViewer
+
+ def __init__(self):
+ self.threads=[]
+ self.db=None
+ self.config = Configuration.Config()
+ self.load_profile()
+
+ self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+ self.window.connect("delete_event", self.delete_event)
+ self.window.connect("destroy", self.destroy)
+ self.window.set_title("Free Poker DB - version: alpha9+, p143 or higher")
+ self.window.set_border_width(1)
+ self.window.set_size_request(1020,400)
+ self.window.set_resizable(True)
+
+ self.menu_items = (
+ ( "/_Main", None, None, 0, "" ),
+ ( "/Main/_Load Profile (broken)", "L", self.dia_load_profile, 0, None ),
+ ( "/Main/_Edit Profile (todo)", "E", self.dia_edit_profile, 0, None ),
+ ( "/Main/_Save Profile (todo)", None, self.dia_save_profile, 0, None ),
+ ("/Main/sep1", None, None, 0, "" ),
+ ("/Main/_Quit", "Q", self.quit, 0, None ),
+ ("/_Import", None, None, 0, "" ),
+ ("/Import/_Bulk Import", "B", self.tab_bulk_import, 0, None ),
+ ("/Import/_Auto Import and HUD", "A", self.tab_auto_import, 0, None ),
+ ("/Import/Auto _Rating (todo)", "R", self.not_implemented, 0, None ),
+ ("/_Viewers", None, None, 0, "" ),
+ ("/_Viewers/_Auto Import and HUD", "A", self.tab_auto_import, 0, None ),
+ ("/Viewers/_Graphs", "G", self.tabGraphViewer, 0, None ),
+ ("/Viewers/Hand _Replayer (todo)", None, self.not_implemented, 0, None ),
+ ("/Viewers/Player _Details (todo)", None, self.not_implemented, 0, None ),
+ ("/Viewers/_Player Stats (tabulated view) (todo)", None, self.not_implemented, 0, None ),
+ ("/Viewers/Starting _Hands (todo)", None, self.not_implemented, 0, None ),
+ ("/Viewers/_Session Replayer (todo)", None, self.not_implemented, 0, None ),
+ ("/Viewers/Poker_table Viewer (mostly obselete)", "T", self.tab_table_viewer, 0, None ),
+ #( "/Viewers/Tourney Replayer
+ ( "/_Database", None, None, 0, "" ),
+ ( "/Database/Create or Delete _Database (todo)", None, self.dia_create_del_database, 0, None ),
+ ( "/Database/Create or Delete _User (todo)", None, self.dia_create_del_user, 0, None ),
+ ( "/Database/Create or Recreate _Tables", None, self.dia_recreate_tables, 0, None ),
+ ( "/Database/_Statistics (todo)", None, self.dia_database_stats, 0, None ),
+ ( "/D_ebugging", None, None, 0, "" ),
+ ( "/Debugging/_Delete Parts of Database (todo)", None, self.dia_delete_db_parts, 0, None ),
+ ( "/Debugging/_Export DB (todo)", None, self.dia_export_db, 0, None ),
+ ( "/Debugging/_Import DB (todo)", None, self.dia_import_db, 0, None ),
+ ( "/Debugging/_Regression test (todo)", None, self.dia_regression_test, 0, None ),
+ ( "/_Help", None, None, 0, "" ),
+ ( "/Help/_Main Help", "H", self.tab_main_help, 0, None ),
+ ( "/Help/_Abbrevations (todo)", None, self.tab_abbreviations, 0, None ),
+ ( "/Help/sep1", None, None, 0, "" ),
+ ( "/Help/A_bout (todo)", None, self.dia_about, 0, None ),
+ ( "/Help/_License and Copying (todo)", None, self.dia_licensing, 0, None )
+ )
+
+ self.main_vbox = gtk.VBox(False, 1)
+ self.main_vbox.set_border_width(1)
+ self.window.add(self.main_vbox)
+ self.main_vbox.show()
+
+ menubar = self.get_menu(self.window)
+ self.main_vbox.pack_start(menubar, False, True, 0)
+ menubar.show()
+ #done menubar
+
+ self.tabs=[]
+ self.tab_names=[]
+ self.tab_buttons=[]
+ self.tab_box = gtk.HBox(False,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.status_bar = gtk.Label("Status: Connected to "+self.db.get_backend_name()+" database named "+self.db.database+" on host "+self.db.host)
+ self.main_vbox.pack_end(self.status_bar, False, True, 0)
+ self.status_bar.show()
+
+ self.window.show()
+ #end def __init__
+
+ def main(self):
+ gtk.main()
+ return 0
+ #end def main
+
+if __name__ == "__main__":
+ me = fpdb()
+ me.main()
diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py
old mode 100755
new mode 100644
diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py
old mode 100755
new mode 100644
index 3b0fb983..e2a2779e
--- a/pyfpdb/fpdb_import.py
+++ b/pyfpdb/fpdb_import.py
@@ -1,298 +1,310 @@
-#!/usr/bin/python
-
-#Copyright 2008 Steffen Jobbagy-Felso
-#This program is free software: you can redistribute it and/or modify
-#it under the terms of the GNU Affero General Public License as published by
-#the Free Software Foundation, version 3 of the License.
-#
-#This program is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-#GNU General Public License for more details.
-#
-#You should have received a copy of the GNU Affero General Public License
-#along with this program. If not, see .
-#In the "official" distribution you can find the license in
-#agpl-3.0.txt in the docs folder of the package.
-
-#see status.txt for site/games support info
-
-import sys
-
-try:
- import MySQLdb
- mysqlLibFound=True
-except:
- pass
-
-try:
- import psycopg2
- pgsqlLibFound=True
-except:
- pass
-
-import math
-import os
-import datetime
-import re
-import fpdb_simple
-import fpdb_parse_logic
-from time import time
-
-class Importer:
-
- def __init__(self, caller, settings):
- """Constructor"""
- self.settings=settings
- self.caller=caller
- self.db = None
- self.cursor = None
- self.filelist = {}
- self.dirlist = {}
- self.monitor = False
- self.updated = {} #Time last import was run {file:mtime}
- self.callHud = False
- self.lines = None
- self.faobs = None #File as one big string
- self.pos_in_file = {} # dict to remember how far we have read in the file
- #Set defaults
- if not self.settings.has_key('imp-callFpdbHud'):
- self.settings['imp-callFpdbHud'] = False
- if not self.settings.has_key('minPrint'):
- self.settings['minPrint'] = 30
- self.dbConnect()
-
- def dbConnect(self):
- #connect to DB
- if self.settings['db-backend'] == 2:
- if not mysqlLibFound:
- raise fpdb_simple.FpdbError("interface library MySQLdb not found but MySQL selected as backend - please install the library or change the config file")
- self.db = MySQLdb.connect(self.settings['db-host'], self.settings['db-user'],
- self.settings['db-password'], self.settings['db-databaseName'])
- elif self.settings['db-backend'] == 3:
- if not pgsqlLibFound:
- raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
- print self.settings
- self.db = psycopg2.connect(host = self.settings['db-host'],
- user = self.settings['db-user'],
- password = self.settings['db-password'],
- database = self.settings['db-databaseName'])
- elif self.settings['db-backend'] == 4:
- pass
- else:
- pass
- self.cursor = self.db.cursor()
-
- #Set functions
- def setCallHud(self, value):
- self.callHud = value
-
- def setMinPrint(self, value):
- self.settings['minPrint'] = int(value)
-
- def setHandCount(self, value):
- self.settings['handCount'] = int(value)
-
- def setQuiet(self, value):
- self.settings['quiet'] = value
-
- def setFailOnError(self, value):
- self.settings['failOnError'] = value
-
-# def setWatchTime(self):
-# self.updated = time()
-
- def clearFileList(self):
- self.filelist = {}
-
- #Add an individual file to filelist
- def addImportFile(self, filename, site = "default", filter = "passthrough"):
- #TODO: test it is a valid file
- self.filelist[filename] = [site] + [filter]
-
- #Add a directory of files to filelist
- #Only one import directory per site supported.
- #dirlist is a hash of lists:
- #dirlist{ 'PokerStars' => ["/path/to/import/", "filtername"] }
- def addImportDirectory(self,dir,monitor = False, site = "default", filter = "passthrough"):
- if os.path.isdir(dir):
- if monitor == True:
- self.monitor = True
- self.dirlist[site] = [dir] + [filter]
-
- for file in os.listdir(dir):
- self.addImportFile(os.path.join(dir, file), site, filter)
- else:
- print "Warning: Attempted to add: '" + str(dir) + "' as an import directory"
-
- #Run full import on filelist
- def runImport(self):
- for file in self.filelist:
- self.import_file_dict(file)
-
- #Run import on updated files, then store latest update time.
- def runUpdated(self):
- #Check for new files in directory
- #todo: make efficient - always checks for new file, should be able to use mtime of directory
- # ^^ May not work on windows
- for site in self.dirlist:
- self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1])
-
- for file in self.filelist:
- stat_info = os.stat(file)
- try:
- lastupdate = self.updated[file]
- if stat_info.st_mtime > lastupdate:
- self.import_file_dict(file)
- self.updated[file] = time()
- except:
- self.updated[file] = time()
- # This codepath only runs first time the file is found, if modified in the last
- # minute run an immediate import.
- if (time() - stat_info.st_mtime) < 60:
- self.import_file_dict(file)
-
- # This is now an internal function that should not be called directly.
- def import_file_dict(self, file):
- starttime = time()
- last_read_hand=0
- loc = 0
- if (file=="stdin"):
- inputFile=sys.stdin
- else:
- inputFile=open(file, "rU")
- try: loc = self.pos_in_file[file]
- except: pass
-
- # Read input file into class and close file
- inputFile.seek(loc)
- self.lines=fpdb_simple.removeTrailingEOL(inputFile.readlines())
- self.pos_in_file[file] = inputFile.tell()
- inputFile.close()
-
- firstline = self.lines[0]
-
- if firstline.find("Tournament Summary")!=-1:
- print "TODO: implement importing tournament summaries"
- #self.faobs = readfile(inputFile)
- #self.parseTourneyHistory()
- return 0
-
- site=fpdb_simple.recogniseSite(firstline)
- category=fpdb_simple.recogniseCategory(firstline)
-
- startpos=0
- stored=0 #counter
- duplicates=0 #counter
- partial=0 #counter
- errors=0 #counter
-
- for i in range (len(self.lines)): #main loop, iterates through the lines of a file and calls the appropriate parser method
- if (len(self.lines[i])<2):
- endpos=i
- hand=self.lines[startpos:endpos]
-
- if (len(hand[0])<2):
- hand=hand[1:]
-
- cancelled=False
- damaged=False
- if (site=="ftp"):
- for i in range (len(hand)):
- if (hand[i].endswith(" has been canceled")): #this is their typo. this is a typo, right?
- cancelled=True
-
- seat1=hand[i].find("Seat ") #todo: make this recover by skipping this line
- if (seat1!=-1):
- if (hand[i].find("Seat ", seat1+3)!=-1):
- damaged=True
-
- if (len(hand)<3):
- pass
- #todo: the above 2 lines are kind of a dirty hack, the mentioned circumstances should be handled elsewhere but that doesnt work with DOS/Win EOL. actually this doesnt work.
- elif (hand[0].endswith(" (partial)")): #partial hand - do nothing
- partial+=1
- elif (hand[1].find("Seat")==-1 and hand[2].find("Seat")==-1 and hand[3].find("Seat")==-1):#todo: should this be or instead of and?
- partial+=1
- elif (cancelled or damaged):
- partial+=1
- else: #normal processing
- isTourney=fpdb_simple.isTourney(hand[0])
- if not isTourney:
- fpdb_simple.filterAnteBlindFold(site,hand)
- hand=fpdb_simple.filterCrap(site, hand, isTourney)
- self.hand=hand
-
- try:
- handsId=fpdb_parse_logic.mainParser(self.db, self.cursor, site, category, hand)
- self.db.commit()
-
- stored+=1
- self.db.commit()
-# if settings['imp-callFpdbHud'] and self.callHud and os.sep=='/':
- if self.settings['imp-callFpdbHud'] and self.callHud:
- #print "call to HUD here. handsId:",handsId
- #pipe the Hands.id out to the HUD
- self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
- except fpdb_simple.DuplicateError:
- duplicates+=1
- except (ValueError), fe:
- errors+=1
- self.printEmailErrorMessage(errors, file, hand[0])
-
- if (self.settings['failOnError']):
- self.db.commit() #dont remove this, in case hand processing was cancelled.
- raise
- except (fpdb_simple.FpdbError), fe:
- errors+=1
- self.printEmailErrorMessage(errors, file, hand[0])
-
- #fe.printStackTrace() #todo: get stacktrace
- self.db.rollback()
-
- if (self.settings['failOnError']):
- self.db.commit() #dont remove this, in case hand processing was cancelled.
- raise
- if (self.settings['minPrint']!=0):
- if ((stored+duplicates+partial+errors)%self.settings['minPrint']==0):
- print "stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors
-
- if (self.settings['handCount']!=0):
- if ((stored+duplicates+partial+errors)>=self.settings['handCount']):
- if (not self.settings['quiet']):
- print "quitting due to reaching the amount of hands to be imported"
- print "Total stored:", stored, "duplicates:", duplicates, "partial/damaged:", partial, "errors:", errors, " time:", (time() - starttime)
- sys.exit(0)
- startpos=endpos
- print "Total stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors, " time:", (time() - starttime)
-
- if stored==0:
- if duplicates>0:
- for line_no in range(len(self.lines)):
- if self.lines[line_no].find("Game #")!=-1:
- final_game_line=self.lines[line_no]
- handsId=fpdb_simple.parseSiteHandNo(final_game_line)
- else:
- print "failed to read a single hand from file:", inputFile
- handsId=0
- #todo: this will cause return of an unstored hand number if the last hand was error or partial
- self.db.commit()
- self.handsId=handsId
- return handsId
-#end def import_file_dict
-
- def parseTourneyHistory(self):
- print "Tourney history parser stub"
- #Find tournament boundaries.
- #print self.foabs
-
-
- def printEmailErrorMessage(self, errors, filename, line):
- print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it."
- print "Filename:", filename
- print "Here is the first line so you can identify it. Please mention that the error was a ValueError:"
- print self.hand[0]
-
-
-if __name__ == "__main__":
- print "CLI for fpdb_import is now available as CliFpdb.py"
+#!/usr/bin/python
+
+#Copyright 2008 Steffen Jobbagy-Felso
+#This program is free software: you can redistribute it and/or modify
+#it under the terms of the GNU Affero General Public License as published by
+#the Free Software Foundation, version 3 of the License.
+#
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+#
+#You should have received a copy of the GNU Affero General Public License
+#along with this program. If not, see .
+#In the "official" distribution you can find the license in
+#agpl-3.0.txt in the docs folder of the package.
+
+#see status.txt for site/games support info
+
+import sys
+
+try:
+ import MySQLdb
+ mysqlLibFound=True
+except:
+ pass
+
+try:
+ import psycopg2
+ pgsqlLibFound=True
+except:
+ pass
+
+import math
+import os
+import datetime
+import re
+import fpdb_simple
+import fpdb_parse_logic
+from time import time
+
+class Importer:
+
+ def __init__(self, caller, settings, config):
+ """Constructor"""
+ self.settings=settings
+ self.caller=caller
+ self.config = config
+ self.db = None
+ self.cursor = None
+ self.filelist = {}
+ self.dirlist = {}
+ self.monitor = False
+ self.updated = {} #Time last import was run {file:mtime}
+ self.lines = None
+ self.faobs = None #File as one big string
+ self.pos_in_file = {} # dict to remember how far we have read in the file
+ #Set defaults
+ self.callHud = self.config.get_import_parameters().get("callFpdbHud")
+ if not self.settings.has_key('minPrint'):
+ self.settings['minPrint'] = 30
+ self.dbConnect()
+
+ def dbConnect(self):
+ #connect to DB
+ if self.settings['db-backend'] == 2:
+ if not mysqlLibFound:
+ raise fpdb_simple.FpdbError("interface library MySQLdb not found but MySQL selected as backend - please install the library or change the config file")
+ self.db = MySQLdb.connect(self.settings['db-host'], self.settings['db-user'],
+ self.settings['db-password'], self.settings['db-databaseName'])
+ elif self.settings['db-backend'] == 3:
+ if not pgsqlLibFound:
+ raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
+ print self.settings
+ self.db = psycopg2.connect(host = self.settings['db-host'],
+ user = self.settings['db-user'],
+ password = self.settings['db-password'],
+ database = self.settings['db-databaseName'])
+ elif self.settings['db-backend'] == 4:
+ pass
+ else:
+ pass
+ self.cursor = self.db.cursor()
+
+ #Set functions
+ def setCallHud(self, value):
+ self.callHud = value
+
+ def setMinPrint(self, value):
+ self.settings['minPrint'] = int(value)
+
+ def setHandCount(self, value):
+ self.settings['handCount'] = int(value)
+
+ def setQuiet(self, value):
+ self.settings['quiet'] = value
+
+ def setFailOnError(self, value):
+ self.settings['failOnError'] = value
+
+# def setWatchTime(self):
+# self.updated = time()
+
+ def clearFileList(self):
+ self.filelist = {}
+
+ #Add an individual file to filelist
+ def addImportFile(self, filename, site = "default", filter = "passthrough"):
+ #TODO: test it is a valid file
+ self.filelist[filename] = [site] + [filter]
+
+ #Add a directory of files to filelist
+ #Only one import directory per site supported.
+ #dirlist is a hash of lists:
+ #dirlist{ 'PokerStars' => ["/path/to/import/", "filtername"] }
+ def addImportDirectory(self, dir, monitor = False, site = "default", filter = "passthrough"):
+ if dir != "/dev/null" and dir.lower() != "none":
+ if os.path.isdir(dir):
+ if monitor == True:
+ self.monitor = True
+ self.dirlist[site] = [dir] + [filter]
+
+ for file in os.listdir(dir):
+ self.addImportFile(os.path.join(dir, file), site, filter)
+ else:
+ print "Warning: Attempted to add: '" + str(dir) + "' as an import directory\n"
+
+ #Run full import on filelist
+ def runImport(self):
+ for file in self.filelist:
+ self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
+
+ #Run import on updated files, then store latest update time.
+ def runUpdated(self):
+ #Check for new files in directory
+ #todo: make efficient - always checks for new file, should be able to use mtime of directory
+ # ^^ May not work on windows
+ for site in self.dirlist:
+ self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1])
+
+ for file in self.filelist:
+ stat_info = os.stat(file)
+ try:
+ lastupdate = self.updated[file]
+ if stat_info.st_mtime > lastupdate:
+ self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
+ self.updated[file] = time()
+ except:
+ self.updated[file] = time()
+ # This codepath only runs first time the file is found, if modified in the last
+ # minute run an immediate import.
+ if (time() - stat_info.st_mtime) < 60:
+ self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
+
+ # This is now an internal function that should not be called directly.
+ def import_file_dict(self, file, site, filter):
+ if(filter == "passthrough"):
+ self.import_fpdb_file(file, site)
+ else:
+ #Load filter, and run filtered file though main importer
+ self.import_fpdb_file(file, site)
+
+
+ def import_fpdb_file(self, file, site):
+ starttime = time()
+ last_read_hand=0
+ loc = 0
+ if (file=="stdin"):
+ inputFile=sys.stdin
+ else:
+ inputFile=open(file, "rU")
+ try: loc = self.pos_in_file[file]
+ except: pass
+
+ # Read input file into class and close file
+ inputFile.seek(loc)
+ self.lines=fpdb_simple.removeTrailingEOL(inputFile.readlines())
+ self.pos_in_file[file] = inputFile.tell()
+ inputFile.close()
+
+ try: # sometimes we seem to be getting an empty self.lines, in which case, we just want to return.
+ firstline = self.lines[0]
+ except:
+# print "import_fpdb_file", file, site, self.lines, "\n"
+ return
+
+ if firstline.find("Tournament Summary")!=-1:
+ print "TODO: implement importing tournament summaries"
+ #self.faobs = readfile(inputFile)
+ #self.parseTourneyHistory()
+ return 0
+
+ site=fpdb_simple.recogniseSite(firstline)
+ category=fpdb_simple.recogniseCategory(firstline)
+
+ startpos=0
+ stored=0 #counter
+ duplicates=0 #counter
+ partial=0 #counter
+ errors=0 #counter
+
+ for i in range (len(self.lines)): #main loop, iterates through the lines of a file and calls the appropriate parser method
+ if (len(self.lines[i])<2):
+ endpos=i
+ hand=self.lines[startpos:endpos]
+
+ if (len(hand[0])<2):
+ hand=hand[1:]
+
+ cancelled=False
+ damaged=False
+ if (site=="ftp"):
+ for i in range (len(hand)):
+ if (hand[i].endswith(" has been canceled")): #this is their typo. this is a typo, right?
+ cancelled=True
+
+ seat1=hand[i].find("Seat ") #todo: make this recover by skipping this line
+ if (seat1!=-1):
+ if (hand[i].find("Seat ", seat1+3)!=-1):
+ damaged=True
+
+ if (len(hand)<3):
+ pass
+ #todo: the above 2 lines are kind of a dirty hack, the mentioned circumstances should be handled elsewhere but that doesnt work with DOS/Win EOL. actually this doesnt work.
+ elif (hand[0].endswith(" (partial)")): #partial hand - do nothing
+ partial+=1
+ elif (hand[1].find("Seat")==-1 and hand[2].find("Seat")==-1 and hand[3].find("Seat")==-1):#todo: should this be or instead of and?
+ partial+=1
+ elif (cancelled or damaged):
+ partial+=1
+ else: #normal processing
+ isTourney=fpdb_simple.isTourney(hand[0])
+ if not isTourney:
+ fpdb_simple.filterAnteBlindFold(site,hand)
+ hand=fpdb_simple.filterCrap(site, hand, isTourney)
+ self.hand=hand
+
+ try:
+ handsId=fpdb_parse_logic.mainParser(self.db, self.cursor, site, category, hand)
+ self.db.commit()
+
+ stored+=1
+ self.db.commit()
+ if self.callHud:
+ #print "call to HUD here. handsId:",handsId
+ #pipe the Hands.id out to the HUD
+ self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
+ except fpdb_simple.DuplicateError:
+ duplicates+=1
+ except (ValueError), fe:
+ errors+=1
+ self.printEmailErrorMessage(errors, file, hand[0])
+
+ if (self.settings['failOnError']):
+ self.db.commit() #dont remove this, in case hand processing was cancelled.
+ raise
+ except (fpdb_simple.FpdbError), fe:
+ errors+=1
+ self.printEmailErrorMessage(errors, file, hand[0])
+
+ #fe.printStackTrace() #todo: get stacktrace
+ self.db.rollback()
+
+ if (self.settings['failOnError']):
+ self.db.commit() #dont remove this, in case hand processing was cancelled.
+ raise
+ if (self.settings['minPrint']!=0):
+ if ((stored+duplicates+partial+errors)%self.settings['minPrint']==0):
+ print "stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors
+
+ if (self.settings['handCount']!=0):
+ if ((stored+duplicates+partial+errors)>=self.settings['handCount']):
+ if (not self.settings['quiet']):
+ print "quitting due to reaching the amount of hands to be imported"
+ print "Total stored:", stored, "duplicates:", duplicates, "partial/damaged:",
+ partial, "errors:", errors, " time: %5.3f" % (time() - starttime)
+ sys.exit(0)
+ startpos=endpos
+ print "Total stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors, " time: %5.3f" % (time() - starttime)
+
+ if stored==0:
+ if duplicates>0:
+ for line_no in range(len(self.lines)):
+ if self.lines[line_no].find("Game #")!=-1:
+ final_game_line=self.lines[line_no]
+ handsId=fpdb_simple.parseSiteHandNo(final_game_line)
+ else:
+ print "failed to read a single hand from file:", inputFile
+ handsId=0
+ #todo: this will cause return of an unstored hand number if the last hand was error or partial
+ self.db.commit()
+ self.handsId=handsId
+ return handsId
+#end def import_file_dict
+
+ def parseTourneyHistory(self):
+ print "Tourney history parser stub"
+ #Find tournament boundaries.
+ #print self.foabs
+
+
+ def printEmailErrorMessage(self, errors, filename, line):
+ print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it."
+ print "Filename:", filename
+ print "Here is the first line so you can identify it. Please mention that the error was a ValueError:"
+ print self.hand[0]
+
+
+if __name__ == "__main__":
+ print "CLI for fpdb_import is now available as CliFpdb.py"
diff --git a/pyfpdb/fpdb_parse_logic.py b/pyfpdb/fpdb_parse_logic.py
index ec9a53f6..d704d811 100644
--- a/pyfpdb/fpdb_parse_logic.py
+++ b/pyfpdb/fpdb_parse_logic.py
@@ -46,7 +46,7 @@ def mainParser(db, cursor, site, category, hand):
#print "found small blind line:",smallBlindLine
break
#print "small blind line:",smallBlindLine
- gametypeID=fpdb_simple.recogniseGametypeID(cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
+ gametypeID=fpdb_simple.recogniseGametypeID(db, cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
if isTourney:
if site!="ps":
raise fpdb_simple.FpdbError("tourneys are only supported on PS right now")
@@ -142,18 +142,18 @@ def mainParser(db, cursor, site, category, hand):
payin_amounts=fpdb_simple.calcPayin(len(names), buyin, fee)
if base=="hold":
- result = fpdb_save_to_db.tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
+ result = fpdb_save_to_db.tourney_holdem_omaha(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
elif base=="stud":
- result = fpdb_save_to_db.tourney_stud(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
+ result = fpdb_save_to_db.tourney_stud(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
else:
raise fpdb_simple.FpdbError ("unrecognised category")
else:
if base=="hold":
- result = fpdb_save_to_db.ring_holdem_omaha(cursor, base, category, siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
+ result = fpdb_save_to_db.ring_holdem_omaha(db, cursor, base, category, siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
elif base=="stud":
- result = fpdb_save_to_db.ring_stud(cursor, base, category, siteHandNo, gametypeID,
+ result = fpdb_save_to_db.ring_stud(db, cursor, base, category, siteHandNo, gametypeID,
handStartTime, names, playerIDs, startCashes, antes, cardValues,
cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
else:
diff --git a/pyfpdb/fpdb_save_to_db.py b/pyfpdb/fpdb_save_to_db.py
index af6ab09d..d548eca5 100644
--- a/pyfpdb/fpdb_save_to_db.py
+++ b/pyfpdb/fpdb_save_to_db.py
@@ -21,13 +21,13 @@
import fpdb_simple
#stores a stud/razz hand into the database
-def ring_stud(cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
+def ring_stud(db, cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
- hands_id=fpdb_simple.storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
+ hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
#print "before calling store_hands_players_stud, antes:", antes
- hands_players_ids=fpdb_simple.store_hands_players_stud(cursor, hands_id, player_ids,
+ hands_players_ids=fpdb_simple.store_hands_players_stud(db, cursor, hands_id, player_ids,
start_cashes, antes, card_values, card_suits, winnings, rakes, seatNos)
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
@@ -36,14 +36,14 @@ def ring_stud(cursor, base, category, site_hand_no, gametype_id, hand_start_time
return hands_id
#end def ring_stud
-def ring_holdem_omaha(cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
+def ring_holdem_omaha(db, cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
"""stores a holdem/omaha hand into the database"""
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
fpdb_simple.fill_board_cards(board_values, board_suits)
- hands_id=fpdb_simple.storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
+ hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
- hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos)
+ hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos)
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
@@ -53,7 +53,7 @@ def ring_holdem_omaha(cursor, base, category, site_hand_no, gametype_id, hand_st
return hands_id
#end def ring_holdem_omaha
-def tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId, siteId, #end of tourney specific params
+def tourney_holdem_omaha(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId, siteId, #end of tourney specific params
site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
"""stores a tourney holdem/omaha hand into the database"""
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
@@ -62,9 +62,9 @@ def tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knoc
tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourney_start)
tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings)
- hands_id=fpdb_simple.storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
+ hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
- hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha_tourney(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids)
+ hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha_tourney(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids)
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
@@ -74,7 +74,7 @@ def tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knoc
return hands_id
#end def tourney_holdem_omaha
-def tourney_stud(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId,
+def tourney_stud(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId,
siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
#stores a tourney stud/razz hand into the database
fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits)
@@ -83,9 +83,9 @@ def tourney_stud(cursor, base, category, siteTourneyNo, buyin, fee, knockout, en
tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, playerIds, payin_amounts, ranks, winnings)
- hands_id=fpdb_simple.storeHands(cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats)
+ hands_id=fpdb_simple.storeHands(db, cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats)
- hands_players_ids=fpdb_simple.store_hands_players_stud_tourney(cursor, hands_id, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, seatNos, tourneys_players_ids)
+ hands_players_ids=fpdb_simple.store_hands_players_stud_tourney(db, cursor, hands_id, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, seatNos, tourneys_players_ids)
fpdb_simple.storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData)
diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py
index d1b191de..ecd9def8 100644
--- a/pyfpdb/fpdb_simple.py
+++ b/pyfpdb/fpdb_simple.py
@@ -484,7 +484,8 @@ def isActionLine(line):
#returns whether this is a duplicate
def isAlreadyInDB(cursor, gametypeID, siteHandNo):
- cursor.execute ("SELECT id FROM Hands WHERE gametypeId=%s AND siteHandNo=%s", (gametypeID, siteHandNo))
+ #print "isAlreadyInDB gtid,shand:",gametypeID, siteHandNo
+ cursor.execute ("SELECT id FROM Hands WHERE gametypeId=%s AND siteHandNo=%s", (gametypeID, siteHandNo))
result=cursor.fetchall()
if (len(result)>=1):
raise DuplicateError ("dupl")
@@ -1021,7 +1022,7 @@ def recogniseCategory(line):
#end def recogniseCategory
#returns the int for the gametype_id for the given line
-def recogniseGametypeID(cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy
+def recogniseGametypeID(db, cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy
#if (topline.find("HORSE")!=-1):
# raise FpdbError("recogniseGametypeID: HORSE is not yet supported.")
@@ -1072,7 +1073,10 @@ def recogniseGametypeID(cursor, topline, smallBlindLine, site_id, category, isTo
else:
cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
result=cursor.fetchone()
- #print "tried SELECTing gametypes.id, result:",result
+ #print "recgt1 result=",result
+ #ret=result[0]
+ #print "recgt1 ret=",ret
+ #print "tried SELECTing gametypes.id, result:",result
try:
len(result)
@@ -1105,17 +1109,19 @@ def recogniseGametypeID(cursor, topline, smallBlindLine, site_id, category, isTo
cursor.execute("""INSERT INTO Gametypes
(siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_blind, big_blind, small_bet, big_bet))
- cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
+ #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
else:
cursor.execute("""INSERT INTO Gametypes
(siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind
- cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
+ #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
- result=cursor.fetchone()
+ result=(db.insert_id(),)
+ #print "recgt2 result=",result
#print "created new gametypes.id:",result
- return result[0]
+ #print "recgt3: result=", result
+ return result[0]
#end def recogniseGametypeID
def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon):
@@ -1248,15 +1254,16 @@ def store_board_cards(cursor, hands_id, board_values, board_suits):
board_values[4], board_suits[4]))
#end def store_board_cards
-def storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats):
+def storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats):
#stores into table hands
cursor.execute ("INSERT INTO Hands (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats) VALUES (%s, %s, %s, %s, %s, %s, %s)", (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.datetime.today(), maxSeats))
#todo: find a better way of doing this...
- cursor.execute("SELECT id FROM Hands WHERE siteHandNo=%s AND gametypeId=%s", (site_hand_no, gametype_id))
- return cursor.fetchall()[0][0]
+ #cursor.execute("SELECT id FROM Hands WHERE siteHandNo=%s AND gametypeId=%s", (site_hand_no, gametype_id))
+ #return cursor.fetchall()[0][0]
+ return db.insert_id() # mysql only
#end def storeHands
-def store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos):
+def store_hands_players_holdem_omaha(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos):
result=[]
if (category=="holdem"):
for i in range (len(player_ids)):
@@ -1268,8 +1275,9 @@ def store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, sta
(hands_id, player_ids[i], start_cashes[i], positions[i],
card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
winnings[i], rakes[i], seatNos[i]))
- cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
- result.append(cursor.fetchall()[0][0])
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( db.insert_id() ) # mysql only
elif (category=="omahahi" or category=="omahahilo"):
for i in range (len(player_ids)):
cursor.execute ("""INSERT INTO HandsPlayers
@@ -1281,14 +1289,15 @@ def store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, sta
card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
winnings[i], rakes[i], seatNos[i]))
- cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
- result.append(cursor.fetchall()[0][0])
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( db.insert_id() ) # mysql only
else:
raise FpdbError("invalid category")
return result
#end def store_hands_players_holdem_omaha
-def store_hands_players_stud(cursor, hands_id, player_ids, start_cashes, antes,
+def store_hands_players_stud(db, cursor, hands_id, player_ids, start_cashes, antes,
card_values, card_suits, winnings, rakes, seatNos):
#stores hands_players rows for stud/razz games. returns an array of the resulting IDs
result=[]
@@ -1307,12 +1316,14 @@ def store_hands_players_stud(cursor, hands_id, player_ids, start_cashes, antes,
card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
card_values[i][6], card_suits[i][6], winnings[i], rakes[i], seatNos[i]))
- cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
- result.append(cursor.fetchall()[0][0])
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( db.insert_id() ) # mysql only
return result
#end def store_hands_players_stud
-def store_hands_players_holdem_omaha_tourney(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
+def store_hands_players_holdem_omaha_tourney(db, cursor, category, hands_id, player_ids,
+ start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
#stores hands_players for tourney holdem/omaha hands
result=[]
for i in range (len(player_ids)):
@@ -1338,13 +1349,14 @@ def store_hands_players_holdem_omaha_tourney(cursor, category, hands_id, player_
winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
else:
raise FpdbError ("invalid card_values length:"+str(len(card_values[0])))
- cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
- result.append(cursor.fetchall()[0][0])
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( db.insert_id() ) # mysql only
return result
#end def store_hands_players_holdem_omaha_tourney
-def store_hands_players_stud_tourney(cursor, hands_id, player_ids, start_cashes,
+def store_hands_players_stud_tourney(db, cursor, hands_id, player_ids, start_cashes,
antes, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
#stores hands_players for tourney stud/razz hands
result=[]
@@ -1362,8 +1374,9 @@ def store_hands_players_stud_tourney(cursor, hands_id, player_ids, start_cashes,
card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
- cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
- result.append(cursor.fetchall()[0][0])
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( db.insert_id() ) # mysql only
return result
#end def store_hands_players_stud_tourney
@@ -1949,9 +1962,9 @@ def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
for player in range (len(playerIds)):
if base=="hold":
- cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player]))
+ cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player]))
else:
- cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats=%s", (gametypeId, playerIds[player], len(playerIds)))
+ cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s", (gametypeId, playerIds[player], len(playerIds)))
row=cursor.fetchone()
#print "gametypeId:", gametypeId, "playerIds[player]",playerIds[player], "len(playerIds):",len(playerIds), "row:",row
@@ -2097,7 +2110,7 @@ def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
#end def storeHudCache
def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime):
- cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId=%s", (siteTourneyNo, tourneyTypeId))
+ cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
tmp=cursor.fetchone()
#print "tried SELECTing tourneys.id, result:",tmp
@@ -2107,7 +2120,7 @@ def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, sta
cursor.execute("""INSERT INTO Tourneys
(tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)
VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime))
- cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId=%s", (siteTourneyNo, tourneyTypeId))
+ cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
tmp=cursor.fetchone()
#print "created new tourneys.id:",tmp
return tmp[0]
@@ -2121,7 +2134,7 @@ def store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks,
#print "ranks:",ranks
#print "winnings:",winnings
for i in range (len(player_ids)):
- cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId=%s", (tourney_id, player_ids[i]))
+ cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", (tourney_id, player_ids[i]))
tmp=cursor.fetchone()
#print "tried SELECTing tourneys_players.id:",tmp
@@ -2132,7 +2145,7 @@ def store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks,
(tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""",
(tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i]))
- cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId=%s",
+ cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s",
(tourney_id, player_ids[i]))
tmp=cursor.fetchone()
#print "created new tourneys_players.id:",tmp
From 3f86c54b17b30c95d0f7154779037c79de8f15c9 Mon Sep 17 00:00:00 2001
From: eblade
Date: Tue, 2 Dec 2008 10:14:38 -0500
Subject: [PATCH 03/32] add "NA" to fold to steal stats for 0/0's
---
pyfpdb/Stats.py | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/pyfpdb/Stats.py b/pyfpdb/Stats.py
index 5ca42fe8..db2ada2e 100644
--- a/pyfpdb/Stats.py
+++ b/pyfpdb/Stats.py
@@ -261,12 +261,11 @@ def f_SB_steal(stat_dict, player):
)
except:
return (stat,
- '%3.1f' % (0) + '%',
- 'fSB=%3.1f' % (0) + '%',
- 'fSB_s=%3.1f' % (0) + '%',
- '(%d/%d)' % (0, 0),
- '% folded SB to steal'
- )
+ 'NA',
+ 'fSB=NA',
+ 'fSB_s=NA',
+ '0/0',
+ '% folded SB to steal')
def f_BB_steal(stat_dict, player):
""" Folded BB to steal."""
@@ -282,12 +281,11 @@ def f_BB_steal(stat_dict, player):
)
except:
return (stat,
- '%3.1f' % (0) + '%',
- 'fBB=%3.1f' % (0) + '%',
- 'fBB_s=%3.1f' % (0) + '%',
- '(%d/%d)' % (0, 0),
- '% folded BB to steal'
- )
+ 'NA',
+ 'fBB=NA',
+ 'fBB_s=NA',
+ '0/0',
+ '% folded BB to steal')
def three_B_0(stat_dict, player):
""" Three bet preflop/3rd."""
From 567d585a54af580aac54eb9faa0566ba8e52b116 Mon Sep 17 00:00:00 2001
From: sqlcoder
Date: Tue, 2 Dec 2008 23:28:06 +0000
Subject: [PATCH 04/32] script to update index choices
---
pyfpdb/upd_indexes.sql | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100755 pyfpdb/upd_indexes.sql
diff --git a/pyfpdb/upd_indexes.sql b/pyfpdb/upd_indexes.sql
new file mode 100755
index 00000000..e79f4bd4
--- /dev/null
+++ b/pyfpdb/upd_indexes.sql
@@ -0,0 +1,27 @@
+
+# script to update indexes on mysql (+other?) database
+
+select '1. Dropping indexes' as ' ';
+select 'Can''t drop messages indicate index already gone' as ' ';
+
+ALTER TABLE `fpdb`.`Settings` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`Sites` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`Gametypes` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`Players` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`Autorates` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`Hands` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`BoardCards` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`TourneyTypes` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`Tourneys` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`TourneysPlayers` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`HandsPlayers` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`HandsActions` DROP INDEX `id`;
+ALTER TABLE `fpdb`.`HudCache` DROP INDEX `id`;
+
+select '2. Adding extra indexes on useful fields' as ' ';
+select 'Duplicate key name messages indicate new indexes already there' as ' ';
+
+ALTER TABLE `fpdb`.`tourneys` ADD INDEX `siteTourneyNo`(`siteTourneyNo`);
+ALTER TABLE `fpdb`.`hands` ADD INDEX `siteHandNo`(`siteHandNo`);
+ALTER TABLE `fpdb`.`players` ADD INDEX `name`(`name`);
+
From cd858d6ade8fe2d0e72d9eb3f0d1eedbadab1c7f Mon Sep 17 00:00:00 2001
From: eblade
Date: Wed, 3 Dec 2008 03:25:49 -0500
Subject: [PATCH 05/32] add "debug stat windows" to hud menu .. doesn't do
anything useful yet, as i'm trying to figure out what part to actually debug
---
pyfpdb/Hud.py | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py
index 2960db30..3914f5ca 100644
--- a/pyfpdb/Hud.py
+++ b/pyfpdb/Hud.py
@@ -92,14 +92,22 @@ class Hud:
self.menu.append(self.item1)
self.item1.connect("activate", self.kill_hud)
self.item1.show()
+
self.item2 = gtk.MenuItem('Save Layout')
self.menu.append(self.item2)
self.item2.connect("activate", self.save_layout)
self.item2.show()
+
self.item3 = gtk.MenuItem('Reposition Stats')
self.menu.append(self.item3)
self.item3.connect("activate", self.reposition_windows)
self.item3.show()
+
+ self.item4 = gtk.MenuItem('Debug Stat Windows')
+ self.menu.append(self.item4)
+ self.item4.connect("activate", self.debug_stat_windows)
+ self.item4.show()
+
self.ebox.connect_object("button-press-event", self.on_button_press, self.menu)
self.main_window.show_all()
@@ -132,6 +140,12 @@ class Hud:
for w in self.stat_windows:
self.stat_windows[w].window.move(self.stat_windows[w].x,
self.stat_windows[w].y)
+
+ def debug_stat_windows(self, *args):
+ print self.table, "\n", self.main_window.window.get_transient_for()
+ for w in self.stat_windows:
+ print self.stat_windows[w].window.window.get_transient_for()
+
def save_layout(self, *args):
new_layout = [(0, 0)] * self.max
# todo: have the hud track the poker table's window position regularly, don't forget to update table.x and table.y.
From 3be6453b4282ee2777d00ec8ac607de8f4dd8e35 Mon Sep 17 00:00:00 2001
From: Ray
Date: Wed, 3 Dec 2008 12:01:37 -0500
Subject: [PATCH 06/32] Minor bug in import parameters.
---
pyfpdb/Configuration.py | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py
index 91d74ff1..3bcaaa91 100755
--- a/pyfpdb/Configuration.py
+++ b/pyfpdb/Configuration.py
@@ -444,9 +444,9 @@ class Config:
def get_import_parameters(self):
imp = {}
try:
- imp['callFpdbHud'] = self.callFpdbHud
- imp['interval'] = self.interval
- imp['hhArchiveBase'] = self.hhArchiveBase
+ imp['callFpdbHud'] = self.imp.callFpdbHud
+ imp['interval'] = self.imp.interval
+ imp['hhArchiveBase'] = self.imp.hhArchiveBase
except: # Default params
imp['callFpdbHud'] = True
imp['interval'] = 10
@@ -613,9 +613,7 @@ if __name__== "__main__":
print "----------- END POPUP WINDOW FORMATS -----------"
print "\n----------- IMPORT -----------"
- tmp = c.get_import_parameters()
- for param in tmp:
- print " " + str(param) + ": " + str(tmp[param])
+ print c.imp
print "----------- END IMPORT -----------"
print "\n----------- TABLE VIEW -----------"
From 7063e03d6e8df06fe41cca9734f04cd35e9d31f0 Mon Sep 17 00:00:00 2001
From: Ray
Date: Wed, 3 Dec 2008 12:48:04 -0500
Subject: [PATCH 07/32] futile attempt to fix mystery crash
---
pyfpdb/Mucked.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyfpdb/Mucked.py b/pyfpdb/Mucked.py
index 6f1fadd0..45fe66bd 100644
--- a/pyfpdb/Mucked.py
+++ b/pyfpdb/Mucked.py
@@ -289,7 +289,7 @@ class Stud_cards:
def clear(self):
for r in range(0, self.rows):
- self.grid_contents[(1, r)].set_text(" ")
+ self.grid_contents[(1, r)].set_text(" ")
for c in range(0, 7):
self.seen_cards[(c, r)].set_from_pixbuf(self.card_images[('B', 'S')])
self.eb[(c, r)].set_tooltip_text('')
From 01861450653ce4fd9f1d1155b326270ea689e55d Mon Sep 17 00:00:00 2001
From: eblade
Date: Wed, 3 Dec 2008 13:35:19 -0500
Subject: [PATCH 08/32] remove no-longer-needed "topify_window" for
Stat_Window, removed some lines that were commented out due to no longer
being needed, etc. Seems to fix the windows randomly re-attaching in Win32.
---
pyfpdb/Hud.py | 31 +------------------------------
1 file changed, 1 insertion(+), 30 deletions(-)
diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py
index 3914f5ca..80ec9a82 100644
--- a/pyfpdb/Hud.py
+++ b/pyfpdb/Hud.py
@@ -386,41 +386,12 @@ class Stat_Window:
font = pango.FontDescription("Sans 7")
self.label[r][c].modify_font(font)
-# if not os.name == 'nt': # seems to be a bug in opacity on windows
self.window.set_opacity(parent.colors['hudopacity'])
-# self.window.realize()
self.window.move(self.x, self.y)
-# self.window.show_all()
-# set_keep_above(1) for windows
- if os.name == 'nt': self.topify_window(self.window)
+
self.window.hide()
- def topify_window(self, window):
- """Set the specified gtk window to stayontop in MS Windows."""
-
- def windowEnumerationHandler(hwnd, resultList):
- '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
- resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
-
- unique_name = 'unique name for finding this window'
- real_name = window.get_title()
- window.set_title(unique_name)
- tl_windows = []
- win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
-
- for w in tl_windows:
- if w[1] == unique_name:
-
- #win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE)
-
-# style = win32gui.GetWindowLong(w[0], win32con.GWL_EXSTYLE)
-# style |= win32con.WS_EX_TOOLWINDOW
-# style &= ~win32con.WS_EX_APPWINDOW
-# win32gui.SetWindowLong(w[0], win32con.GWL_EXSTYLE, style)
- win32gui.ShowWindow(w[0], win32con.SW_SHOW)
- window.set_title(real_name)
-
def destroy(*args): # call back for terminating the main eventloop
gtk.main_quit()
From 160db086897efe737700378065cef7f3a977dc6e Mon Sep 17 00:00:00 2001
From: sqlcoder
Date: Wed, 3 Dec 2008 23:14:03 +0000
Subject: [PATCH 09/32] calc totalprofit for hud
---
pyfpdb/fpdb_parse_logic.py | 15 ++++++++++++---
pyfpdb/fpdb_simple.py | 31 +++++++++++++++++++++++++------
2 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/pyfpdb/fpdb_parse_logic.py b/pyfpdb/fpdb_parse_logic.py
index d704d811..6652ba1f 100644
--- a/pyfpdb/fpdb_parse_logic.py
+++ b/pyfpdb/fpdb_parse_logic.py
@@ -131,9 +131,13 @@ def mainParser(db, cursor, site, category, hand):
totalWinnings+=winnings[i]
if base=="hold":
- hudImportData=fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes, allIns, actionTypeByNo, winnings, totalWinnings, positions)
+ hudImportData=fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
+ , allIns, actionTypeByNo, winnings, totalWinnings, positions
+ , actionTypes, actionAmounts)
else:
- hudImportData=fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes, allIns, actionTypeByNo, winnings, totalWinnings, None)
+ hudImportData=fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
+ , allIns, actionTypeByNo, winnings, totalWinnings, None
+ , actionTypes, actionAmounts)
if isTourney:
ranks=[]
@@ -151,7 +155,12 @@ def mainParser(db, cursor, site, category, hand):
raise fpdb_simple.FpdbError ("unrecognised category")
else:
if base=="hold":
- result = fpdb_save_to_db.ring_holdem_omaha(db, cursor, base, category, siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
+ result = fpdb_save_to_db.ring_holdem_omaha(db, cursor, base, category, siteHandNo
+ ,gametypeID, handStartTime, names, playerIDs
+ ,startCashes, positions, cardValues, cardSuits
+ ,boardValues, boardSuits, winnings, rakes
+ ,actionTypes, allIns, actionAmounts, actionNos
+ ,hudImportData, maxSeats, tableName, seatNos)
elif base=="stud":
result = fpdb_save_to_db.ring_stud(db, cursor, base, category, siteHandNo, gametypeID,
handStartTime, names, playerIDs, startCashes, antes, cardValues,
diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py
index ecd9def8..571223c4 100644
--- a/pyfpdb/fpdb_simple.py
+++ b/pyfpdb/fpdb_simple.py
@@ -1241,7 +1241,8 @@ def storeActions(cursor, handsPlayersIds, actionTypes, allIns, actionAmounts, ac
for i in range (len(actionTypes)): #iterate through streets
for j in range (len(actionTypes[i])): #iterate through names
for k in range (len(actionTypes[i][j])): #iterate through individual actions of that player on that street
- cursor.execute ("INSERT INTO HandsActions (handPlayerId, street, actionNo, action, allIn, amount) VALUES (%s, %s, %s, %s, %s, %s)", (handsPlayersIds[j], i, actionNos[i][j][k], actionTypes[i][j][k], allIns[i][j][k], actionAmounts[i][j][k]))
+ cursor.execute ("INSERT INTO HandsActions (handPlayerId, street, actionNo, action, allIn, amount) VALUES (%s, %s, %s, %s, %s, %s)"
+ , (handsPlayersIds[j], i, actionNos[i][j][k], actionTypes[i][j][k], allIns[i][j][k], actionAmounts[i][j][k]))
#end def storeActions
def store_board_cards(cursor, hands_id, board_values, board_suits):
@@ -1380,8 +1381,12 @@ def store_hands_players_stud_tourney(db, cursor, hands_id, player_ids, start_cas
return result
#end def store_hands_players_stud_tourney
-def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo, winnings, totalWinnings, positions):
- """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"""
+def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo
+ ,winnings, totalWinnings, positions, actionTypes, actionAmounts):
+ """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=[]
@@ -1901,8 +1906,14 @@ def generateHudCacheData(player_ids, base, category, action_types, allIns, actio
street3CheckCallRaiseDone=[]
street4CheckCallRaiseChance=[]
street4CheckCallRaiseDone=[]
- for player in range (len(player_ids)):
- myTotalProfit=0
+ #print "b4 totprof calc, len(playerIds)=", len(player_ids)
+ for pl in range (len(player_ids)):
+ #print "pl=", pl
+ myTotalProfit=winnings[pl] # still need to deduct costs
+ for i in range (len(actionTypes)): #iterate through streets
+ #for j in range (len(actionTypes[i])): #iterate through names (using pl loop above)
+ for k in range (len(actionTypes[i][pl])): #iterate through individual actions of that player on that street
+ myTotalProfit -= actionAmounts[i][pl][k]
myStreet1CheckCallRaiseChance=False
myStreet1CheckCallRaiseDone=False
@@ -1913,7 +1924,9 @@ def generateHudCacheData(player_ids, base, category, action_types, allIns, actio
myStreet4CheckCallRaiseChance=False
myStreet4CheckCallRaiseDone=False
+ #print "myTotalProfit=", myTotalProfit
totalProfit.append(myTotalProfit)
+ #print "totalProfit[]=", totalProfit
street1CheckCallRaiseChance.append(myStreet1CheckCallRaiseChance)
street1CheckCallRaiseDone.append(myStreet1CheckCallRaiseDone)
@@ -1925,6 +1938,7 @@ def generateHudCacheData(player_ids, base, category, action_types, allIns, actio
street4CheckCallRaiseDone.append(myStreet4CheckCallRaiseDone)
result['totalProfit']=totalProfit
+ #print "res[totalProfit]=", result['totalProfit']
result['street1CheckCallRaiseChance']=street1CheckCallRaiseChance
result['street1CheckCallRaiseDone']=street1CheckCallRaiseDone
@@ -1960,6 +1974,8 @@ def generateFoldToCB(street, playerIDs, didStreetCB, streetCBDone, foldToStreetC
def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
# if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
+ #print "storeHudCache, len(playerIds)=", len(playerIds), " len(vpip)=" \
+ #, len(hudImportData['street0VPI']), " len(totprof)=", len(hudImportData['totalProfit'])
for player in range (len(playerIds)):
if base=="hold":
cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player]))
@@ -2044,7 +2060,10 @@ def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
if hudImportData['foldToStreet4CBChance'][player]: row[50]+=1
if hudImportData['foldToStreet4CBDone'][player]: row[51]+=1
- row[52]+=hudImportData['totalProfit'][player]
+ #print "player=", player
+ #print "len(totalProfit)=", len(hudImportData['totalProfit'])
+ if hudImportData['totalProfit'][player]:
+ row[52]+=hudImportData['totalProfit'][player]
if hudImportData['street1CheckCallRaiseChance'][player]: row[53]+=1
if hudImportData['street1CheckCallRaiseDone'][player]: row[54]+=1
From 1e9263f202bedbaf6ae78c333b7bd37566e61a32 Mon Sep 17 00:00:00 2001
From: Ray
Date: Fri, 5 Dec 2008 12:51:19 -0500
Subject: [PATCH 10/32] Fix width of left column.
---
pyfpdb/Mucked.py | 1 +
1 file changed, 1 insertion(+)
mode change 100644 => 100755 pyfpdb/Mucked.py
diff --git a/pyfpdb/Mucked.py b/pyfpdb/Mucked.py
old mode 100644
new mode 100755
index 45fe66bd..e220bf32
--- a/pyfpdb/Mucked.py
+++ b/pyfpdb/Mucked.py
@@ -170,6 +170,7 @@ class Stud_cards:
for r in range(0, self.rows):
self.grid_contents[( 0, r)] = gtk.Label("%d" % (r + 1))
self.grid_contents[( 1, r)] = gtk.Label("player %d" % (r + 1))
+ self.grid_contents[( 1, r)].set_property("width-chars", 12)
self.grid_contents[( 4, r)] = gtk.Label("-")
self.grid_contents[( 9, r)] = gtk.Label("-")
self.grid_contents[( 2, r)] = self.eb[( 0, r)]
From 3eb1a1dd0bd8e552e8b45c9c0debb827e70d06e0 Mon Sep 17 00:00:00 2001
From: Mika Bostrom
Date: Sat, 6 Dec 2008 13:41:39 +0200
Subject: [PATCH 11/32] Start to clean up psycopg2.connect() and surroundings
---
pyfpdb/fpdb_db.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py
index 8165211c..8435fc96 100755
--- a/pyfpdb/fpdb_db.py
+++ b/pyfpdb/fpdb_db.py
@@ -43,7 +43,10 @@ class fpdb_db:
self.db=MySQLdb.connect(host = host, user = user, passwd = password, db = database)
elif backend==self.PGSQL:
import psycopg2
- self.db = psycopg2.connect(host = host, user = user, password = password, database = database)
+ self.db = psycopg2.connect(host = host,
+ user = user,
+ password = password,
+ database = database)
else:
raise fpdb_simple.FpdbError("unrecognised database backend:"+backend)
self.cursor=self.db.cursor()
From 0f05d0886eb6c22743f0504155b4a34f41778a99 Mon Sep 17 00:00:00 2001
From: Mika Bostrom
Date: Sat, 6 Dec 2008 14:10:50 +0200
Subject: [PATCH 12/32] Modify local HUD_config.xml, clean some places and
change DB type to postgresql
---
pyfpdb/HUD_config.xml | 229 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 229 insertions(+)
create mode 100644 pyfpdb/HUD_config.xml
diff --git a/pyfpdb/HUD_config.xml b/pyfpdb/HUD_config.xml
new file mode 100644
index 00000000..d640794d
--- /dev/null
+++ b/pyfpdb/HUD_config.xml
@@ -0,0 +1,229 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From c9700fc1a7baeafdffa01fa6f266a6a100e6bef3 Mon Sep 17 00:00:00 2001
From: Mika Bostrom
Date: Sat, 6 Dec 2008 14:34:44 +0200
Subject: [PATCH 13/32] Some debugs
---
pyfpdb/fpdb.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py
index bec9be78..02829523 100755
--- a/pyfpdb/fpdb.py
+++ b/pyfpdb/fpdb.py
@@ -263,7 +263,11 @@ class fpdb:
self.db = fpdb_db.fpdb_db()
#print "end of fpdb.load_profile, databaseName:",self.settings['db-databaseName']
- self.db.connect(self.settings['db-backend'], self.settings['db-host'], self.settings['db-databaseName'], self.settings['db-user'], self.settings['db-password'])
+ self.db.connect(self.settings['db-backend'],
+ self.settings['db-host'],
+ self.settings['db-databaseName'],
+ self.settings['db-user'],
+ self.settings['db-password'])
if self.db.wrongDbVersion:
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
From 7ecfac543756d1926a6eb9df02c2a4a0c0abb751 Mon Sep 17 00:00:00 2001
From: Mika Bostrom
Date: Sat, 6 Dec 2008 14:40:04 +0200
Subject: [PATCH 14/32] Retab/whitespace demangle fpdb_db.py
---
pyfpdb/fpdb_db.py | 281 +++++++++++++++++++++++-----------------------
1 file changed, 141 insertions(+), 140 deletions(-)
diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py
index 8435fc96..b750b440 100755
--- a/pyfpdb/fpdb_db.py
+++ b/pyfpdb/fpdb_db.py
@@ -21,159 +21,160 @@ import fpdb_simple
import FpdbSQLQueries
class fpdb_db:
- def __init__(self):
- """Simple constructor, doesnt really do anything"""
- self.db=None
- self.cursor=None
- self.sql = {}
- self.MYSQL_INNODB=2
- self.PGSQL=3
- self.SQLITE=4
- #end def __init__
-
- def connect(self, backend, host, database, user, password):
- """Connects a database with the given parameters"""
- self.backend=backend
- self.host=host
- self.database=database
- self.user=user
- self.password=password
- if backend==self.MYSQL_INNODB:
- import MySQLdb
- self.db=MySQLdb.connect(host = host, user = user, passwd = password, db = database)
- elif backend==self.PGSQL:
- import psycopg2
- self.db = psycopg2.connect(host = host,
+ def __init__(self):
+ """Simple constructor, doesnt really do anything"""
+ self.db=None
+ self.cursor=None
+ self.sql = {}
+ self.MYSQL_INNODB=2
+ self.PGSQL=3
+ self.SQLITE=4
+ #end def __init__
+
+ def connect(self, backend, host, database, user, password):
+ """Connects a database with the given parameters"""
+ print backend, host, database, user, password
+ self.backend=backend
+ self.host=host
+ self.database=database
+ self.user=user
+ self.password=password
+ if backend==self.MYSQL_INNODB:
+ import MySQLdb
+ self.db=MySQLdb.connect(host = host, user = user, passwd = password, db = database)
+ elif backend==self.PGSQL:
+ import psycopg2
+ self.db = psycopg2.connect(host = host,
user = user,
password = password,
database = database)
- else:
- raise fpdb_simple.FpdbError("unrecognised database backend:"+backend)
- self.cursor=self.db.cursor()
- self.cursor.execute('SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED')
- # Set up query dictionary as early in the connection process as we can.
- self.sql = FpdbSQLQueries.FpdbSQLQueries(self.get_backend_name())
- self.wrongDbVersion=False
- try:
- self.cursor.execute("SELECT * FROM Settings")
- settings=self.cursor.fetchone()
- if settings[0]!=118:
- print "outdated or too new database version - please recreate tables"
- self.wrongDbVersion=True
- except:# _mysql_exceptions.ProgrammingError:
- print "failed to read settings table - please recreate tables"
- self.wrongDbVersion=True
- #end def connect
+ else:
+ raise fpdb_simple.FpdbError("unrecognised database backend:"+backend)
+ self.cursor=self.db.cursor()
+ self.cursor.execute('SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED')
+ # Set up query dictionary as early in the connection process as we can.
+ self.sql = FpdbSQLQueries.FpdbSQLQueries(self.get_backend_name())
+ self.wrongDbVersion=False
+ try:
+ self.cursor.execute("SELECT * FROM Settings")
+ settings=self.cursor.fetchone()
+ if settings[0]!=118:
+ print "outdated or too new database version - please recreate tables"
+ self.wrongDbVersion=True
+ except:# _mysql_exceptions.ProgrammingError:
+ print "failed to read settings table - please recreate tables"
+ self.wrongDbVersion=True
+ #end def connect
- def disconnect(self, due_to_error=False):
- """Disconnects the DB"""
- if due_to_error:
- self.db.rollback()
- else:
- self.db.commit()
- self.cursor.close()
- self.db.close()
- #end def disconnect
-
- def reconnect(self, due_to_error=False):
- """Reconnects the DB"""
- #print "started fpdb_db.reconnect"
- self.disconnect(due_to_error)
- self.connect(self.backend, self.host, self.database, self.user, self.password)
+ def disconnect(self, due_to_error=False):
+ """Disconnects the DB"""
+ if due_to_error:
+ self.db.rollback()
+ else:
+ self.db.commit()
+ self.cursor.close()
+ self.db.close()
+ #end def disconnect
+
+ def reconnect(self, due_to_error=False):
+ """Reconnects the DB"""
+ #print "started fpdb_db.reconnect"
+ self.disconnect(due_to_error)
+ self.connect(self.backend, self.host, self.database, self.user, self.password)
- def create_tables(self):
- #todo: should detect and fail gracefully if tables already exist.
- self.cursor.execute(self.sql.query['createSettingsTable'])
- self.cursor.execute(self.sql.query['createSitesTable'])
- self.cursor.execute(self.sql.query['createGametypesTable'])
- self.cursor.execute(self.sql.query['createPlayersTable'])
- self.cursor.execute(self.sql.query['createAutoratesTable'])
- self.cursor.execute(self.sql.query['createHandsTable'])
- self.cursor.execute(self.sql.query['createBoardCardsTable'])
- self.cursor.execute(self.sql.query['createTourneyTypesTable'])
- self.cursor.execute(self.sql.query['createTourneysTable'])
- self.cursor.execute(self.sql.query['createTourneysPlayersTable'])
- self.cursor.execute(self.sql.query['createHandsPlayersTable'])
- self.cursor.execute(self.sql.query['createHandsActionsTable'])
- self.cursor.execute(self.sql.query['createHudCacheTable'])
- self.cursor.execute(self.sql.query['addTourneyIndex'])
- self.cursor.execute(self.sql.query['addHandsIndex'])
- self.cursor.execute(self.sql.query['addPlayersIndex'])
- self.fillDefaultData()
- self.db.commit()
+ def create_tables(self):
+ #todo: should detect and fail gracefully if tables already exist.
+ self.cursor.execute(self.sql.query['createSettingsTable'])
+ self.cursor.execute(self.sql.query['createSitesTable'])
+ self.cursor.execute(self.sql.query['createGametypesTable'])
+ self.cursor.execute(self.sql.query['createPlayersTable'])
+ self.cursor.execute(self.sql.query['createAutoratesTable'])
+ self.cursor.execute(self.sql.query['createHandsTable'])
+ self.cursor.execute(self.sql.query['createBoardCardsTable'])
+ self.cursor.execute(self.sql.query['createTourneyTypesTable'])
+ self.cursor.execute(self.sql.query['createTourneysTable'])
+ self.cursor.execute(self.sql.query['createTourneysPlayersTable'])
+ self.cursor.execute(self.sql.query['createHandsPlayersTable'])
+ self.cursor.execute(self.sql.query['createHandsActionsTable'])
+ self.cursor.execute(self.sql.query['createHudCacheTable'])
+ self.cursor.execute(self.sql.query['addTourneyIndex'])
+ self.cursor.execute(self.sql.query['addHandsIndex'])
+ self.cursor.execute(self.sql.query['addPlayersIndex'])
+ self.fillDefaultData()
+ self.db.commit()
#end def disconnect
-
- def drop_tables(self):
- """Drops the fpdb tables from the current db"""
+
+ def drop_tables(self):
+ """Drops the fpdb tables from the current db"""
- if(self.get_backend_name() == 'MySQL InnoDB'):
- #Databases with FOREIGN KEY support need this switched of before you can drop tables
- self.drop_referencial_integrity()
+ if(self.get_backend_name() == 'MySQL InnoDB'):
+ #Databases with FOREIGN KEY support need this switched of before you can drop tables
+ self.drop_referencial_integrity()
- # Query the DB to see what tables exist
- self.cursor.execute(self.sql.query['list_tables'])
- for table in self.cursor:
- self.cursor.execute(self.sql.query['drop_table'] + table[0])
- elif(self.get_backend_name() == 'PostgreSQL'):
- self.db.commit()# I have no idea why this makes the query work--REB 07OCT2008
- self.cursor.execute(self.sql.query['list_tables'])
- tables = self.cursor.fetchall()
- for table in tables:
- self.cursor.execute(self.sql.query['drop_table'] + table[0] + ' cascade')
- elif(self.get_backend_name() == 'SQLite'):
- #todo: sqlite version here
- print "Empty function here"
+ # Query the DB to see what tables exist
+ self.cursor.execute(self.sql.query['list_tables'])
+ for table in self.cursor:
+ self.cursor.execute(self.sql.query['drop_table'] + table[0])
+ elif(self.get_backend_name() == 'PostgreSQL'):
+ self.db.commit()# I have no idea why this makes the query work--REB 07OCT2008
+ self.cursor.execute(self.sql.query['list_tables'])
+ tables = self.cursor.fetchall()
+ for table in tables:
+ self.cursor.execute(self.sql.query['drop_table'] + table[0] + ' cascade')
+ elif(self.get_backend_name() == 'SQLite'):
+ #todo: sqlite version here
+ print "Empty function here"
- self.db.commit()
- #end def drop_tables
+ self.db.commit()
+ #end def drop_tables
- def drop_referencial_integrity(self):
- """Update all tables to remove foreign keys"""
+ def drop_referencial_integrity(self):
+ """Update all tables to remove foreign keys"""
- self.cursor.execute(self.sql.query['list_tables'])
- result = self.cursor.fetchall()
+ self.cursor.execute(self.sql.query['list_tables'])
+ result = self.cursor.fetchall()
- for i in range(len(result)):
- self.cursor.execute("SHOW CREATE TABLE " + result[i][0])
- inner = self.cursor.fetchall()
+ for i in range(len(result)):
+ self.cursor.execute("SHOW CREATE TABLE " + result[i][0])
+ inner = self.cursor.fetchall()
- for j in range(len(inner)):
- # result[i][0] - Table name
- # result[i][1] - CREATE TABLE parameters
- #Searching for CONSTRAINT `tablename_ibfk_1`
- for m in re.finditer('(ibfk_[0-9]+)', inner[j][1]):
- key = "`" + inner[j][0] + "_" + m.group() + "`"
- self.cursor.execute("ALTER TABLE " + inner[j][0] + " DROP FOREIGN KEY " + key)
+ for j in range(len(inner)):
+ # result[i][0] - Table name
+ # result[i][1] - CREATE TABLE parameters
+ #Searching for CONSTRAINT `tablename_ibfk_1`
+ for m in re.finditer('(ibfk_[0-9]+)', inner[j][1]):
+ key = "`" + inner[j][0] + "_" + m.group() + "`"
+ self.cursor.execute("ALTER TABLE " + inner[j][0] + " DROP FOREIGN KEY " + key)
self.db.commit()
#end drop_referencial_inegrity
-
- def get_backend_name(self):
- """Returns the name of the currently used backend"""
- if self.backend==2:
- return "MySQL InnoDB"
- elif self.backend==3:
- return "PostgreSQL"
- else:
- raise fpdb_simple.FpdbError("invalid backend")
- #end def get_backend_name
-
- def get_db_info(self):
- return (self.host, self.database, self.user, self.password)
- #end def get_db_info
-
- def fillDefaultData(self):
- self.cursor.execute("INSERT INTO Settings VALUES (118);")
- self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Full Tilt Poker', 'USD');")
- self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'PokerStars', 'USD');")
- self.cursor.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);")
- #end def fillDefaultData
-
- def recreate_tables(self):
- """(Re-)creates the tables of the current DB"""
-
- self.drop_tables()
- self.create_tables()
- self.db.commit()
- print "Finished recreating tables"
- #end def recreate_tables
+
+ def get_backend_name(self):
+ """Returns the name of the currently used backend"""
+ if self.backend==2:
+ return "MySQL InnoDB"
+ elif self.backend==3:
+ return "PostgreSQL"
+ else:
+ raise fpdb_simple.FpdbError("invalid backend")
+ #end def get_backend_name
+
+ def get_db_info(self):
+ return (self.host, self.database, self.user, self.password)
+ #end def get_db_info
+
+ def fillDefaultData(self):
+ self.cursor.execute("INSERT INTO Settings VALUES (118);")
+ self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Full Tilt Poker', 'USD');")
+ self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'PokerStars', 'USD');")
+ self.cursor.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);")
+ #end def fillDefaultData
+
+ def recreate_tables(self):
+ """(Re-)creates the tables of the current DB"""
+
+ self.drop_tables()
+ self.create_tables()
+ self.db.commit()
+ print "Finished recreating tables"
+ #end def recreate_tables
#end class fpdb_db
From dfb8a06686f3da5f6d5e505bf3bf1118e53b44db Mon Sep 17 00:00:00 2001
From: Mika Bostrom
Date: Sat, 6 Dec 2008 15:07:37 +0200
Subject: [PATCH 15/32] Allow to connect to local PostgreSQL via domain socket
---
pyfpdb/fpdb_db.py | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py
index b750b440..2663224e 100755
--- a/pyfpdb/fpdb_db.py
+++ b/pyfpdb/fpdb_db.py
@@ -31,23 +31,33 @@ class fpdb_db:
self.SQLITE=4
#end def __init__
- def connect(self, backend, host, database, user, password):
+ def connect(self, backend=None, host=None, database=None,
+ user=None, password=None):
"""Connects a database with the given parameters"""
- print backend, host, database, user, password
+ if backend is None:
+ raise FpdbError('Database backend not defined')
self.backend=backend
self.host=host
- self.database=database
self.user=user
self.password=password
+ self.database=database
if backend==self.MYSQL_INNODB:
import MySQLdb
self.db=MySQLdb.connect(host = host, user = user, passwd = password, db = database)
elif backend==self.PGSQL:
import psycopg2
- self.db = psycopg2.connect(host = host,
+ # If DB connection is made over TCP, then the variables
+ # host, user and password are required
+ if self.host or self.user:
+ self.db = psycopg2.connect(host = host,
user = user,
password = password,
database = database)
+ # For local domain-socket connections, only DB name is
+ # needed, and everything else is in fact undefined and/or
+ # flat out wrong
+ else:
+ self.db = psycopg2.connect(database = database)
else:
raise fpdb_simple.FpdbError("unrecognised database backend:"+backend)
self.cursor=self.db.cursor()
From 6070066f8a09588b91021e4cfd7deaddb10708de Mon Sep 17 00:00:00 2001
From: Mika Bostrom
Date: Sat, 6 Dec 2008 15:16:55 +0200
Subject: [PATCH 16/32] obtain_global_lock() is a method, not top-level
function
---
pyfpdb/fpdb.py | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py
index 02829523..6362c004 100755
--- a/pyfpdb/fpdb.py
+++ b/pyfpdb/fpdb.py
@@ -117,12 +117,12 @@ class fpdb:
def dia_create_del_database(self, widget, data):
print "todo: implement dia_create_del_database"
- obtain_global_lock()
+ self.obtain_global_lock()
#end def dia_create_del_database
def dia_create_del_user(self, widget, data):
print "todo: implement dia_create_del_user"
- obtain_global_lock()
+ self.obtain_global_lock()
#end def dia_create_del_user
def dia_database_stats(self, widget, data):
@@ -132,17 +132,17 @@ class fpdb:
def dia_delete_db_parts(self, widget, data):
print "todo: implement dia_delete_db_parts"
- obtain_global_lock()
+ self.obtain_global_lock()
#end def dia_delete_db_parts
def dia_edit_profile(self, widget=None, data=None, create_default=False, path=None):
print "todo: implement dia_edit_profile"
- obtain_global_lock()
+ self.obtain_global_lock()
#end def dia_edit_profile
def dia_export_db(self, widget, data):
print "todo: implement dia_export_db"
- obtain_global_lock()
+ self.obtain_global_lock()
#end def dia_export_db
def dia_get_db_root_credentials(self):
@@ -167,7 +167,7 @@ class fpdb:
def dia_import_db(self, widget, data):
print "todo: implement dia_import_db"
- obtain_global_lock()
+ self.obtain_global_lock()
#end def dia_import_db
def dia_licensing(self, widget, data):
From 19c0328955c339f502ae76e2c25fab25bed30f09 Mon Sep 17 00:00:00 2001
From: Mika Bostrom
Date: Sat, 6 Dec 2008 21:14:39 +0200
Subject: [PATCH 17/32] Change syntax for CREATE INDEX... for postgresql
---
pyfpdb/FpdbSQLQueries.py | 8 +-
pyfpdb/HUD_config.xml | 229 ---------------------------------------
2 files changed, 4 insertions(+), 233 deletions(-)
delete mode 100644 pyfpdb/HUD_config.xml
diff --git a/pyfpdb/FpdbSQLQueries.py b/pyfpdb/FpdbSQLQueries.py
index 11826018..c56e6de3 100644
--- a/pyfpdb/FpdbSQLQueries.py
+++ b/pyfpdb/FpdbSQLQueries.py
@@ -577,7 +577,7 @@ class FpdbSQLQueries:
self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)"""
elif(self.dbname == 'PostgreSQL'):
# FIXME: This query has a different syntax
- self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)"""
+ self.query['addTourneyIndex'] = """CREATE INDEX siteTourneyNo ON Tourneys (siteTourneyNo)"""
elif(self.dbname == 'SQLite'):
self.query['addHandsIndex'] = """ """
@@ -585,7 +585,7 @@ class FpdbSQLQueries:
self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
elif(self.dbname == 'PostgreSQL'):
# FIXME: This query has a different syntax
- self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
+ self.query['addHandsIndex'] = """CREATE INDEX siteHandNo ON Hands (siteHandNo)"""
elif(self.dbname == 'SQLite'):
self.query['addHandsIndex'] = """ """
@@ -593,9 +593,9 @@ class FpdbSQLQueries:
self.query['addPlayersIndex'] = """ALTER TABLE Players ADD INDEX name(name)"""
elif(self.dbname == 'PostgreSQL'):
# FIXME: This query has a different syntax
- self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
+ self.query['addPlayersIndex'] = """CREATE INDEX name ON Players (name)"""
elif(self.dbname == 'SQLite'):
- self.query['addHandsIndex'] = """ """
+ self.query['addPlayersIndex'] = """ """
################################
# Queries used in GuiGraphViewer
diff --git a/pyfpdb/HUD_config.xml b/pyfpdb/HUD_config.xml
deleted file mode 100644
index d640794d..00000000
--- a/pyfpdb/HUD_config.xml
+++ /dev/null
@@ -1,229 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
From 415eb4a3c62dbf648c3c10dc8ee8ff9abb3ac5d8 Mon Sep 17 00:00:00 2001
From: Mika Bostrom
Date: Sat, 6 Dec 2008 21:50:40 +0200
Subject: [PATCH 18/32] Retab/whitespace demangly fpdb_import.py
---
pyfpdb/fpdb_import.py | 502 +++++++++++++++++++++---------------------
1 file changed, 252 insertions(+), 250 deletions(-)
diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py
index 0ff8179c..7ce53edd 100755
--- a/pyfpdb/fpdb_import.py
+++ b/pyfpdb/fpdb_import.py
@@ -20,16 +20,16 @@
import sys
try:
- import MySQLdb
- mysqlLibFound=True
+ import MySQLdb
+ mysqlLibFound=True
except:
- pass
-
+ pass
+
try:
- import psycopg2
- pgsqlLibFound=True
+ import psycopg2
+ pgsqlLibFound=True
except:
- pass
+ pass
import traceback
import math
@@ -42,274 +42,276 @@ from time import time
class Importer:
- def __init__(self, caller, settings, config):
- """Constructor"""
- self.settings=settings
- self.caller=caller
- self.config = config
- self.db = None
- self.cursor = None
- self.filelist = {}
- self.dirlist = {}
- self.monitor = False
- self.updated = {} #Time last import was run {file:mtime}
- self.lines = None
- self.faobs = None #File as one big string
- self.pos_in_file = {} # dict to remember how far we have read in the file
- #Set defaults
- self.callHud = self.config.get_import_parameters().get("callFpdbHud")
- if not self.settings.has_key('minPrint'):
- self.settings['minPrint'] = 30
- self.dbConnect()
+ def __init__(self, caller, settings, config):
+ """Constructor"""
+ self.settings=settings
+ self.caller=caller
+ self.config = config
+ self.db = None
+ self.cursor = None
+ self.filelist = {}
+ self.dirlist = {}
+ self.monitor = False
+ self.updated = {} #Time last import was run {file:mtime}
+ self.lines = None
+ self.faobs = None #File as one big string
+ self.pos_in_file = {} # dict to remember how far we have read in the file
+ #Set defaults
+ self.callHud = self.config.get_import_parameters().get("callFpdbHud")
+ if not self.settings.has_key('minPrint'):
+ self.settings['minPrint'] = 30
+ self.dbConnect()
- def dbConnect(self):
- #connect to DB
- if self.settings['db-backend'] == 2:
- if not mysqlLibFound:
- raise fpdb_simple.FpdbError("interface library MySQLdb not found but MySQL selected as backend - please install the library or change the config file")
- self.db = MySQLdb.connect(self.settings['db-host'], self.settings['db-user'],
- self.settings['db-password'], self.settings['db-databaseName'])
- elif self.settings['db-backend'] == 3:
- if not pgsqlLibFound:
- raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
- print self.settings
- self.db = psycopg2.connect(host = self.settings['db-host'],
- user = self.settings['db-user'],
- password = self.settings['db-password'],
- database = self.settings['db-databaseName'])
- elif self.settings['db-backend'] == 4:
- pass
- else:
- pass
- self.cursor = self.db.cursor()
+ # XXX: Why is this here, when fpdb_db.connect() already does the
+ # same?
+ def dbConnect(self):
+ #connect to DB
+ if self.settings['db-backend'] == 2:
+ if not mysqlLibFound:
+ raise fpdb_simple.FpdbError("interface library MySQLdb not found but MySQL selected as backend - please install the library or change the config file")
+ self.db = MySQLdb.connect(self.settings['db-host'], self.settings['db-user'],
+ self.settings['db-password'], self.settings['db-databaseName'])
+ elif self.settings['db-backend'] == 3:
+ if not pgsqlLibFound:
+ raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
+ print self.settings
+ self.db = psycopg2.connect(host = self.settings['db-host'],
+ user = self.settings['db-user'],
+ password = self.settings['db-password'],
+ database = self.settings['db-databaseName'])
+ elif self.settings['db-backend'] == 4:
+ pass
+ else:
+ pass
+ self.cursor = self.db.cursor()
- #Set functions
- def setCallHud(self, value):
- self.callHud = value
+ #Set functions
+ def setCallHud(self, value):
+ self.callHud = value
- def setMinPrint(self, value):
- self.settings['minPrint'] = int(value)
+ def setMinPrint(self, value):
+ self.settings['minPrint'] = int(value)
- def setHandCount(self, value):
- self.settings['handCount'] = int(value)
+ def setHandCount(self, value):
+ self.settings['handCount'] = int(value)
- def setQuiet(self, value):
- self.settings['quiet'] = value
+ def setQuiet(self, value):
+ self.settings['quiet'] = value
- def setFailOnError(self, value):
- self.settings['failOnError'] = value
+ def setFailOnError(self, value):
+ self.settings['failOnError'] = value
-# def setWatchTime(self):
-# self.updated = time()
+# def setWatchTime(self):
+# self.updated = time()
- def clearFileList(self):
- self.filelist = {}
+ def clearFileList(self):
+ self.filelist = {}
- #Add an individual file to filelist
- def addImportFile(self, filename, site = "default", filter = "passthrough"):
- #TODO: test it is a valid file
- self.filelist[filename] = [site] + [filter]
+ #Add an individual file to filelist
+ def addImportFile(self, filename, site = "default", filter = "passthrough"):
+ #TODO: test it is a valid file
+ self.filelist[filename] = [site] + [filter]
- #Add a directory of files to filelist
- #Only one import directory per site supported.
- #dirlist is a hash of lists:
- #dirlist{ 'PokerStars' => ["/path/to/import/", "filtername"] }
- def addImportDirectory(self,dir,monitor = False, site = "default", filter = "passthrough"):
- if os.path.isdir(dir):
- if monitor == True:
- self.monitor = True
- self.dirlist[site] = [dir] + [filter]
+ #Add a directory of files to filelist
+ #Only one import directory per site supported.
+ #dirlist is a hash of lists:
+ #dirlist{ 'PokerStars' => ["/path/to/import/", "filtername"] }
+ def addImportDirectory(self,dir,monitor = False, site = "default", filter = "passthrough"):
+ if os.path.isdir(dir):
+ if monitor == True:
+ self.monitor = True
+ self.dirlist[site] = [dir] + [filter]
- for file in os.listdir(dir):
- self.addImportFile(os.path.join(dir, file), site, filter)
- else:
- print "Warning: Attempted to add: '" + str(dir) + "' as an import directory"
+ for file in os.listdir(dir):
+ self.addImportFile(os.path.join(dir, file), site, filter)
+ else:
+ print "Warning: Attempted to add: '" + str(dir) + "' as an import directory"
- #Run full import on filelist
- def runImport(self):
- for file in self.filelist:
- self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
+ #Run full import on filelist
+ def runImport(self):
+ for file in self.filelist:
+ self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
- #Run import on updated files, then store latest update time.
- def runUpdated(self):
- #Check for new files in directory
- #todo: make efficient - always checks for new file, should be able to use mtime of directory
- # ^^ May not work on windows
- for site in self.dirlist:
- self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1])
+ #Run import on updated files, then store latest update time.
+ def runUpdated(self):
+ #Check for new files in directory
+ #todo: make efficient - always checks for new file, should be able to use mtime of directory
+ # ^^ May not work on windows
+ for site in self.dirlist:
+ self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1])
- for file in self.filelist:
- stat_info = os.stat(file)
- try:
- lastupdate = self.updated[file]
- if stat_info.st_mtime > lastupdate:
- self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
- self.updated[file] = time()
- except:
- self.updated[file] = time()
- # This codepath only runs first time the file is found, if modified in the last
- # minute run an immediate import.
- if (time() - stat_info.st_mtime) < 60:
- self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
+ for file in self.filelist:
+ stat_info = os.stat(file)
+ try:
+ lastupdate = self.updated[file]
+ if stat_info.st_mtime > lastupdate:
+ self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
+ self.updated[file] = time()
+ except:
+ self.updated[file] = time()
+ # This codepath only runs first time the file is found, if modified in the last
+ # minute run an immediate import.
+ if (time() - stat_info.st_mtime) < 60:
+ self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
- # This is now an internal function that should not be called directly.
- def import_file_dict(self, file, site, filter):
- if(filter == "passthrough"):
- self.import_fpdb_file(file, site)
- else:
- #Load filter, and run filtered file though main importer
- self.import_fpdb_file(file, site)
+ # This is now an internal function that should not be called directly.
+ def import_file_dict(self, file, site, filter):
+ if(filter == "passthrough"):
+ self.import_fpdb_file(file, site)
+ else:
+ #Load filter, and run filtered file though main importer
+ self.import_fpdb_file(file, site)
- def import_fpdb_file(self, file, site):
- starttime = time()
- last_read_hand=0
- loc = 0
- if (file=="stdin"):
- inputFile=sys.stdin
- else:
- inputFile=open(file, "rU")
- try: loc = self.pos_in_file[file]
- except: pass
+ def import_fpdb_file(self, file, site):
+ starttime = time()
+ last_read_hand=0
+ loc = 0
+ if (file=="stdin"):
+ inputFile=sys.stdin
+ else:
+ inputFile=open(file, "rU")
+ try: loc = self.pos_in_file[file]
+ except: pass
- # Read input file into class and close file
- inputFile.seek(loc)
- self.lines=fpdb_simple.removeTrailingEOL(inputFile.readlines())
- self.pos_in_file[file] = inputFile.tell()
- inputFile.close()
+ # Read input file into class and close file
+ inputFile.seek(loc)
+ self.lines=fpdb_simple.removeTrailingEOL(inputFile.readlines())
+ self.pos_in_file[file] = inputFile.tell()
+ inputFile.close()
- try: # sometimes we seem to be getting an empty self.lines, in which case, we just want to return.
- firstline = self.lines[0]
- except:
-# print "import_fpdb_file", file, site, self.lines, "\n"
- return
+ try: # sometimes we seem to be getting an empty self.lines, in which case, we just want to return.
+ firstline = self.lines[0]
+ except:
+# print "import_fpdb_file", file, site, self.lines, "\n"
+ return
- if firstline.find("Tournament Summary")!=-1:
- print "TODO: implement importing tournament summaries"
- #self.faobs = readfile(inputFile)
- #self.parseTourneyHistory()
- return 0
-
- site=fpdb_simple.recogniseSite(firstline)
- category=fpdb_simple.recogniseCategory(firstline)
+ if firstline.find("Tournament Summary")!=-1:
+ print "TODO: implement importing tournament summaries"
+ #self.faobs = readfile(inputFile)
+ #self.parseTourneyHistory()
+ return 0
+
+ site=fpdb_simple.recogniseSite(firstline)
+ category=fpdb_simple.recogniseCategory(firstline)
- startpos=0
- stored=0 #counter
- duplicates=0 #counter
- partial=0 #counter
- errors=0 #counter
+ startpos=0
+ stored=0 #counter
+ duplicates=0 #counter
+ partial=0 #counter
+ errors=0 #counter
- for i in range (len(self.lines)): #main loop, iterates through the lines of a file and calls the appropriate parser method
- if (len(self.lines[i])<2):
- endpos=i
- hand=self.lines[startpos:endpos]
-
- if (len(hand[0])<2):
- hand=hand[1:]
-
- cancelled=False
- damaged=False
- if (site=="ftp"):
- for i in range (len(hand)):
- if (hand[i].endswith(" has been canceled")): #this is their typo. this is a typo, right?
- cancelled=True
-
- seat1=hand[i].find("Seat ") #todo: make this recover by skipping this line
- if (seat1!=-1):
- if (hand[i].find("Seat ", seat1+3)!=-1):
- damaged=True
-
- if (len(hand)<3):
- pass
- #todo: the above 2 lines are kind of a dirty hack, the mentioned circumstances should be handled elsewhere but that doesnt work with DOS/Win EOL. actually this doesnt work.
- elif (hand[0].endswith(" (partial)")): #partial hand - do nothing
- partial+=1
- elif (hand[1].find("Seat")==-1 and hand[2].find("Seat")==-1 and hand[3].find("Seat")==-1):#todo: should this be or instead of and?
- partial+=1
- elif (cancelled or damaged):
- partial+=1
- else: #normal processing
- isTourney=fpdb_simple.isTourney(hand[0])
- if not isTourney:
- fpdb_simple.filterAnteBlindFold(site,hand)
- hand=fpdb_simple.filterCrap(site, hand, isTourney)
- self.hand=hand
-
- try:
- handsId=fpdb_parse_logic.mainParser(self.db, self.cursor, site, category, hand)
- self.db.commit()
-
- stored+=1
- self.db.commit()
- if self.callHud:
- #print "call to HUD here. handsId:",handsId
- #pipe the Hands.id out to the HUD
- self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
- except fpdb_simple.DuplicateError:
- duplicates+=1
- except (ValueError), fe:
- errors+=1
- self.printEmailErrorMessage(errors, file, hand)
-
- if (self.settings['failOnError']):
- self.db.commit() #dont remove this, in case hand processing was cancelled.
- raise
- except (fpdb_simple.FpdbError), fe:
- errors+=1
- self.printEmailErrorMessage(errors, file, hand)
+ for i in range (len(self.lines)): #main loop, iterates through the lines of a file and calls the appropriate parser method
+ if (len(self.lines[i])<2):
+ endpos=i
+ hand=self.lines[startpos:endpos]
+
+ if (len(hand[0])<2):
+ hand=hand[1:]
+
+ cancelled=False
+ damaged=False
+ if (site=="ftp"):
+ for i in range (len(hand)):
+ if (hand[i].endswith(" has been canceled")): #this is their typo. this is a typo, right?
+ cancelled=True
+
+ seat1=hand[i].find("Seat ") #todo: make this recover by skipping this line
+ if (seat1!=-1):
+ if (hand[i].find("Seat ", seat1+3)!=-1):
+ damaged=True
+
+ if (len(hand)<3):
+ pass
+ #todo: the above 2 lines are kind of a dirty hack, the mentioned circumstances should be handled elsewhere but that doesnt work with DOS/Win EOL. actually this doesnt work.
+ elif (hand[0].endswith(" (partial)")): #partial hand - do nothing
+ partial+=1
+ elif (hand[1].find("Seat")==-1 and hand[2].find("Seat")==-1 and hand[3].find("Seat")==-1):#todo: should this be or instead of and?
+ partial+=1
+ elif (cancelled or damaged):
+ partial+=1
+ else: #normal processing
+ isTourney=fpdb_simple.isTourney(hand[0])
+ if not isTourney:
+ fpdb_simple.filterAnteBlindFold(site,hand)
+ hand=fpdb_simple.filterCrap(site, hand, isTourney)
+ self.hand=hand
+
+ try:
+ handsId=fpdb_parse_logic.mainParser(self.db, self.cursor, site, category, hand)
+ self.db.commit()
+
+ stored+=1
+ self.db.commit()
+ if self.callHud:
+ #print "call to HUD here. handsId:",handsId
+ #pipe the Hands.id out to the HUD
+ self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
+ except fpdb_simple.DuplicateError:
+ duplicates+=1
+ except (ValueError), fe:
+ errors+=1
+ self.printEmailErrorMessage(errors, file, hand)
+
+ if (self.settings['failOnError']):
+ self.db.commit() #dont remove this, in case hand processing was cancelled.
+ raise
+ except (fpdb_simple.FpdbError), fe:
+ errors+=1
+ self.printEmailErrorMessage(errors, file, hand)
- #fe.printStackTrace() #todo: get stacktrace
- self.db.rollback()
-
- if (self.settings['failOnError']):
- self.db.commit() #dont remove this, in case hand processing was cancelled.
- raise
- if (self.settings['minPrint']!=0):
- if ((stored+duplicates+partial+errors)%self.settings['minPrint']==0):
- print "stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors
-
- if (self.settings['handCount']!=0):
- if ((stored+duplicates+partial+errors)>=self.settings['handCount']):
- if (not self.settings['quiet']):
- print "quitting due to reaching the amount of hands to be imported"
- print "Total stored:", stored, "duplicates:", duplicates, "partial/damaged:", partial, "errors:", errors, " time:", (time() - starttime)
- sys.exit(0)
- startpos=endpos
- print "Total stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors, " time:", (time() - starttime)
-
- if stored==0:
- if duplicates>0:
- for line_no in range(len(self.lines)):
- if self.lines[line_no].find("Game #")!=-1:
- final_game_line=self.lines[line_no]
- handsId=fpdb_simple.parseSiteHandNo(final_game_line)
- else:
- print "failed to read a single hand from file:", inputFile
- handsId=0
- #todo: this will cause return of an unstored hand number if the last hand was error or partial
- self.db.commit()
- self.handsId=handsId
- return handsId
+ #fe.printStackTrace() #todo: get stacktrace
+ self.db.rollback()
+
+ if (self.settings['failOnError']):
+ self.db.commit() #dont remove this, in case hand processing was cancelled.
+ raise
+ if (self.settings['minPrint']!=0):
+ if ((stored+duplicates+partial+errors)%self.settings['minPrint']==0):
+ print "stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors
+
+ if (self.settings['handCount']!=0):
+ if ((stored+duplicates+partial+errors)>=self.settings['handCount']):
+ if (not self.settings['quiet']):
+ print "quitting due to reaching the amount of hands to be imported"
+ print "Total stored:", stored, "duplicates:", duplicates, "partial/damaged:", partial, "errors:", errors, " time:", (time() - starttime)
+ sys.exit(0)
+ startpos=endpos
+ print "Total stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors, " time:", (time() - starttime)
+
+ if stored==0:
+ if duplicates>0:
+ for line_no in range(len(self.lines)):
+ if self.lines[line_no].find("Game #")!=-1:
+ final_game_line=self.lines[line_no]
+ handsId=fpdb_simple.parseSiteHandNo(final_game_line)
+ else:
+ print "failed to read a single hand from file:", inputFile
+ handsId=0
+ #todo: this will cause return of an unstored hand number if the last hand was error or partial
+ self.db.commit()
+ self.handsId=handsId
+ return handsId
#end def import_file_dict
- def parseTourneyHistory(self):
- print "Tourney history parser stub"
- #Find tournament boundaries.
- #print self.foabs
-
+ def parseTourneyHistory(self):
+ print "Tourney history parser stub"
+ #Find tournament boundaries.
+ #print self.foabs
+
- def printEmailErrorMessage(self, errors, filename, line):
- traceback.print_exc(file=sys.stderr)
- print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it."
- print "Filename:", filename
- print "Here is the first line so you can identify it. Please mention that the error was a ValueError:"
- print self.hand[0]
- print "Hand logged to hand-errors.txt"
- logfile = open('hand-errors.txt', 'a')
- for s in self.hand:
- logfile.write(str(s) + "\n")
- logfile.write("\n")
- logfile.close()
+ def printEmailErrorMessage(self, errors, filename, line):
+ traceback.print_exc(file=sys.stderr)
+ print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it."
+ print "Filename:", filename
+ print "Here is the first line so you can identify it. Please mention that the error was a ValueError:"
+ print self.hand[0]
+ print "Hand logged to hand-errors.txt"
+ logfile = open('hand-errors.txt', 'a')
+ for s in self.hand:
+ logfile.write(str(s) + "\n")
+ logfile.write("\n")
+ logfile.close()
if __name__ == "__main__":
- print "CLI for fpdb_import is now available as CliFpdb.py"
+ print "CLI for fpdb_import is now available as CliFpdb.py"
From 90e348946f23e6c215526f3248e88fe99c3cd895 Mon Sep 17 00:00:00 2001
From: Mika Bostrom
Date: Sat, 6 Dec 2008 21:59:58 +0200
Subject: [PATCH 19/32] First step at fixing the bulk importer with postgres
---
pyfpdb/fpdb_import.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py
index 7ce53edd..fd2a321f 100755
--- a/pyfpdb/fpdb_import.py
+++ b/pyfpdb/fpdb_import.py
@@ -75,10 +75,15 @@ class Importer:
if not pgsqlLibFound:
raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
print self.settings
- self.db = psycopg2.connect(host = self.settings['db-host'],
+ if not self.settings.has_key('db-host') or \
+ not self.settings.has_key('db-user'):
+ self.db = psycopg2.connect(host = self.settings['db-host'],
user = self.settings['db-user'],
password = self.settings['db-password'],
database = self.settings['db-databaseName'])
+ else:
+ dbname = self.settings['db-databaseName']
+ self.db = psycopg2.connect(database = dbname)
elif self.settings['db-backend'] == 4:
pass
else:
From 977e954574799b6f02d36ba2d21975273d0735f2 Mon Sep 17 00:00:00 2001
From: Worros
Date: Sun, 7 Dec 2008 17:06:01 +0900
Subject: [PATCH 20/32] Fixups to GuiPlayerStats
Now sets up and obeys the radio buttons more correctly.
Also reads the names from the text box, and replaces in
the sql query.
---
pyfpdb/FpdbSQLQueries.py | 13 +++++++------
pyfpdb/GuiPlayerStats.py | 34 +++++++++++++++++++++++++---------
2 files changed, 32 insertions(+), 15 deletions(-)
diff --git a/pyfpdb/FpdbSQLQueries.py b/pyfpdb/FpdbSQLQueries.py
index c56e6de3..40d0ae6f 100644
--- a/pyfpdb/FpdbSQLQueries.py
+++ b/pyfpdb/FpdbSQLQueries.py
@@ -576,7 +576,6 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)"""
elif(self.dbname == 'PostgreSQL'):
- # FIXME: This query has a different syntax
self.query['addTourneyIndex'] = """CREATE INDEX siteTourneyNo ON Tourneys (siteTourneyNo)"""
elif(self.dbname == 'SQLite'):
self.query['addHandsIndex'] = """ """
@@ -584,7 +583,6 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
elif(self.dbname == 'PostgreSQL'):
- # FIXME: This query has a different syntax
self.query['addHandsIndex'] = """CREATE INDEX siteHandNo ON Hands (siteHandNo)"""
elif(self.dbname == 'SQLite'):
self.query['addHandsIndex'] = """ """
@@ -592,7 +590,6 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['addPlayersIndex'] = """ALTER TABLE Players ADD INDEX name(name)"""
elif(self.dbname == 'PostgreSQL'):
- # FIXME: This query has a different syntax
self.query['addPlayersIndex'] = """CREATE INDEX name ON Players (name)"""
elif(self.dbname == 'SQLite'):
self.query['addPlayersIndex'] = """ """
@@ -633,6 +630,11 @@ class FpdbSQLQueries:
WHERE Players.name = %s AND HandsPlayers.handId = %s
AND Players.siteId = %s AND (tourneysPlayersId IS NULL)"""
+ if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
+ self.query['getPlayerId'] = """SELECT id from Players where name = %s"""
+ elif(self.dbname == 'SQLite'):
+ self.query['getPlayerId'] = """SELECT id from Players where name = %s"""
+
if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
self.query['getRingProfitAllHandsPlayerIdSite'] = """
SELECT hp.handId, hp.winnings, SUM(ha.amount), hp.winnings - SUM(ha.amount)
@@ -702,8 +704,7 @@ class FpdbSQLQueries:
from Gametypes gt
inner join Sites s on s.Id = gt.siteId
inner join HudCache hc on hc.gameTypeId = gt.Id
- where gt.limittype = 'nl'
- and hc.playerId in (3) # use here?
+ where hc.playerId in
# use here ?
group by hc.gametypeId
) stats
@@ -716,7 +717,7 @@ class FpdbSQLQueries:
from HandsPlayers hp
inner join Hands h ON h.id = hp.handId
inner join HandsActions ha ON ha.handPlayerId = hp.id
- where hp.playerId in (3) # use here?
+ where hp.playerId in
# use here ?
and hp.tourneysPlayersId IS NULL
group by hp.handId, h.gameTypeId, hp.position, hp.winnings
diff --git a/pyfpdb/GuiPlayerStats.py b/pyfpdb/GuiPlayerStats.py
index b6733984..7d689228 100644
--- a/pyfpdb/GuiPlayerStats.py
+++ b/pyfpdb/GuiPlayerStats.py
@@ -31,7 +31,9 @@ class GuiPlayerStats (threading.Thread):
return self.main_hbox
def toggleCallback(self, widget, data=None):
- print "%s was toggled %s" % (data, ("OFF", "ON")[widget.get_active()])
+# print "%s was toggled %s" % (data, ("OFF", "ON")[widget.get_active()])
+ self.activesite = data
+ print "DEBUG: activesite set to %s" %(self.activesite)
def refreshStats(self, widget, data):
try: self.stats_table.destroy()
@@ -39,7 +41,14 @@ class GuiPlayerStats (threading.Thread):
self.fillStatsFrame(self.stats_frame)
def fillStatsFrame(self, vbox):
- self.cursor.execute(self.sql.query['playerStats'])
+ # Get currently active site and grab playerid
+ tmp = self.sql.query['playerStats']
+
+ result = self.cursor.execute(self.sql.query['getPlayerId'], self.heroes[self.activesite])
+ result = self.db.cursor.fetchall()
+ pid = result[0][0]
+ tmp = tmp.replace("", "(" + str(pid) + ")")
+ self.cursor.execute(tmp)
result = self.db.cursor.fetchall()
cols = 18
rows = len(result)+1 # +1 for title row
@@ -61,7 +70,6 @@ class GuiPlayerStats (threading.Thread):
for row in range(rows-1):
for col in range(cols):
- print "result[%s][%s]: %s" %(row-1, col, result[row-1][col])
if(row%2 == 0):
bgcolor = "white"
else:
@@ -92,10 +100,15 @@ class GuiPlayerStats (threading.Thread):
hbox.show()
def createPlayerLine(self, hbox, site, player):
- button = gtk.RadioButton(None, site + " id:")
+ if(self.buttongroup == None):
+ button = gtk.RadioButton(None, site + " id:")
+ button.set_active(True)
+ self.buttongroup = button
+ self.activesite = site
+ else:
+ button = gtk.RadioButton(self.buttongroup, site + " id:")
hbox.pack_start(button, True, True, 0)
button.connect("toggled", self.toggleCallback, site)
-# button.set_active(True)
button.show()
pname = gtk.Entry()
@@ -119,6 +132,9 @@ class GuiPlayerStats (threading.Thread):
self.sql = querylist
+ self.activesite = None
+ self.buttongroup = None
+
self.heroes = {}
self.stat_table = None
self.stats_frame = None
@@ -138,11 +154,11 @@ class GuiPlayerStats (threading.Thread):
statsFrame = gtk.Frame("Stats:")
statsFrame.set_label_align(0.0, 0.0)
statsFrame.show()
- vbox = gtk.VBox(False, 0)
- vbox.show()
+ self.stats_frame = gtk.VBox(False, 0)
+ self.stats_frame.show()
- self.fillStatsFrame(vbox)
- statsFrame.add(vbox)
+ self.fillStatsFrame(self.stats_frame)
+ statsFrame.add(self.stats_frame)
self.main_hbox.pack_start(playerFrame)
self.main_hbox.pack_start(statsFrame)
From edd3d3ec0769660b7916811ea24e4454a8ddae39 Mon Sep 17 00:00:00 2001
From: Worros
Date: Sun, 7 Dec 2008 17:35:37 +0900
Subject: [PATCH 21/32] White space churn to RegressionTester
---
pyfpdb/RegressionTest.py | 114 +++++++++++++++++++--------------------
1 file changed, 57 insertions(+), 57 deletions(-)
diff --git a/pyfpdb/RegressionTest.py b/pyfpdb/RegressionTest.py
index 26588ba0..2b09d248 100644
--- a/pyfpdb/RegressionTest.py
+++ b/pyfpdb/RegressionTest.py
@@ -35,72 +35,72 @@ import unittest
class TestSequenceFunctions(unittest.TestCase):
- def setUp(self):
- """Configure MySQL settings/database and establish connection"""
- self.c = Configuration.Config()
- self.mysql_settings={ 'db-host':"localhost",
- 'db-backend':2,
- 'db-databaseName':"fpdbtest",
- 'db-user':"fpdb",
- 'db-password':"fpdb"}
- self.mysql_db = fpdb_db.fpdb_db()
- self.mysql_db.connect(self.mysql_settings['db-backend'], self.mysql_settings['db-host'],
- self.mysql_settings['db-databaseName'], self.mysql_settings['db-user'],
- self.mysql_settings['db-password'])
- self.mysqldict = FpdbSQLQueries.FpdbSQLQueries('MySQL InnoDB')
- self.mysqlimporter = fpdb_import.Importer(self, self.mysql_settings, self.c)
- self.mysqlimporter.setCallHud(False)
+ def setUp(self):
+ """Configure MySQL settings/database and establish connection"""
+ self.c = Configuration.Config()
+ self.mysql_settings={ 'db-host':"localhost",
+ 'db-backend':2,
+ 'db-databaseName':"fpdbtest",
+ 'db-user':"fpdb",
+ 'db-password':"fpdb"}
+ self.mysql_db = fpdb_db.fpdb_db()
+ self.mysql_db.connect(self.mysql_settings['db-backend'], self.mysql_settings['db-host'],
+ self.mysql_settings['db-databaseName'], self.mysql_settings['db-user'],
+ self.mysql_settings['db-password'])
+ self.mysqldict = FpdbSQLQueries.FpdbSQLQueries('MySQL InnoDB')
+ self.mysqlimporter = fpdb_import.Importer(self, self.mysql_settings, self.c)
+ self.mysqlimporter.setCallHud(False)
-# """Configure Postgres settings/database and establish connection"""
-# self.pg_settings={ 'db-host':"localhost", 'db-backend':3, 'db-databaseName':"fpdbtest", 'db-user':"fpdb", 'db-password':"fpdb"}
-# self.pg_db = fpdb_db.fpdb_db()
-# self.pg_db.connect(self.pg_settings['db-backend'], self.pg_settings['db-host'],
-# self.pg_settings['db-databaseName'], self.pg_settings['db-user'],
-# self.pg_settings['db-password'])
-# self.pgdict = FpdbSQLQueries.FpdbSQLQueries('PostgreSQL')
+# """Configure Postgres settings/database and establish connection"""
+# self.pg_settings={ 'db-host':"localhost", 'db-backend':3, 'db-databaseName':"fpdbtest", 'db-user':"fpdb", 'db-password':"fpdb"}
+# self.pg_db = fpdb_db.fpdb_db()
+# self.pg_db.connect(self.pg_settings['db-backend'], self.pg_settings['db-host'],
+# self.pg_settings['db-databaseName'], self.pg_settings['db-user'],
+# self.pg_settings['db-password'])
+# self.pgdict = FpdbSQLQueries.FpdbSQLQueries('PostgreSQL')
- def testDatabaseConnection(self):
- """Test all supported DBs"""
- self.result = self.mysql_db.cursor.execute(self.mysqldict.query['list_tables'])
- self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
+ def testDatabaseConnection(self):
+ """Test all supported DBs"""
+ self.result = self.mysql_db.cursor.execute(self.mysqldict.query['list_tables'])
+ self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
-# self.result = self.pg_db.cursor.execute(self.pgdict.query['list_tables'])
-# self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
+# self.result = self.pg_db.cursor.execute(self.pgdict.query['list_tables'])
+# self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
- def testMySQLRecreateTables(self):
- """Test droping then recreating fpdb table schema"""
- self.mysql_db.recreate_tables()
- self.result = self.mysql_db.cursor.execute("SHOW TABLES")
- self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
+ def testMySQLRecreateTables(self):
+ """Test droping then recreating fpdb table schema"""
+ self.mysql_db.recreate_tables()
+ self.result = self.mysql_db.cursor.execute("SHOW TABLES")
+ self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
- def testPokerStarsHHDate(self):
- latest = "PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET]"
- previous = "PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/08/17 - 01:14:43 (ET)"
- older1 = "PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/09/07 06:23:14 ET"
+ def testPokerStarsHHDate(self):
+ latest = "PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET]"
+ previous = "PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/08/17 - 01:14:43 (ET)"
+ older1 = "PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/09/07 06:23:14 ET"
- result = fpdb_simple.parseHandStartTime(older1, "ps")
- self.failUnless(result==datetime.datetime(2008,9,7,11,23,14),
- "Date incorrect, expected: 2008-09-07 11:23:14 got: " + str(result))
- result = fpdb_simple.parseHandStartTime(latest, "ps")
- self.failUnless(result==datetime.datetime(2008,11,12,15,00,48),
- "Date incorrect, expected: 2008-11-12 15:00:48 got: " + str(result))
- result = fpdb_simple.parseHandStartTime(previous, "ps")
- self.failUnless(result==datetime.datetime(2008,8,17,6,14,43),
- "Date incorrect, expected: 2008-08-17 01:14:43 got: " + str(result))
+ result = fpdb_simple.parseHandStartTime(older1, "ps")
+ self.failUnless(result==datetime.datetime(2008,9,7,11,23,14),
+ "Date incorrect, expected: 2008-09-07 11:23:14 got: " + str(result))
+ result = fpdb_simple.parseHandStartTime(latest, "ps")
+ self.failUnless(result==datetime.datetime(2008,11,12,15,00,48),
+ "Date incorrect, expected: 2008-11-12 15:00:48 got: " + str(result))
+ result = fpdb_simple.parseHandStartTime(previous, "ps")
+ self.failUnless(result==datetime.datetime(2008,8,17,6,14,43),
+ "Date incorrect, expected: 2008-08-17 01:14:43 got: " + str(result))
- def testImportHandHistoryFiles(self):
- """Test import of single HH file"""
- self.mysqlimporter.addImportFile("regression-test-files/hand-histories/ps-lhe-ring-3hands.txt")
- self.mysqlimporter.runImport()
- self.mysqlimporter.addImportDirectory("regression-test-files/hand-histories")
- self.mysqlimporter.runImport()
+ def testImportHandHistoryFiles(self):
+ """Test import of single HH file"""
+ self.mysqlimporter.addImportFile("regression-test-files/hand-histories/ps-lhe-ring-3hands.txt")
+ self.mysqlimporter.runImport()
+ self.mysqlimporter.addImportDirectory("regression-test-files/hand-histories")
+ self.mysqlimporter.runImport()
-# def testPostgresSQLRecreateTables(self):
-# """Test droping then recreating fpdb table schema"""
-# self.pg_db.recreate_tables()
-# self.result = self.pg_db.cursor.execute(self.pgdict.query['list_tables'])
-# self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
+# def testPostgresSQLRecreateTables(self):
+# """Test droping then recreating fpdb table schema"""
+# self.pg_db.recreate_tables()
+# self.result = self.pg_db.cursor.execute(self.pgdict.query['list_tables'])
+# self.failUnless(self.result==13, "Number of tables in database incorrect. Expected 13 got " + str(self.result))
if __name__ == '__main__':
unittest.main()
From ec01f7ae4011f3046e25f8e90804bb11c57b6afd Mon Sep 17 00:00:00 2001
From: sqlcoder
Date: Sun, 7 Dec 2008 17:23:38 +0000
Subject: [PATCH 22/32] move code closer to carl's repo
---
pyfpdb/FpdbSQLQueries.py | 1305 ++++++++++++++++++++++----------------
pyfpdb/fpdb_db.py | 247 ++++----
2 files changed, 885 insertions(+), 667 deletions(-)
diff --git a/pyfpdb/FpdbSQLQueries.py b/pyfpdb/FpdbSQLQueries.py
index 9b791f5d..b3dbf8c7 100644
--- a/pyfpdb/FpdbSQLQueries.py
+++ b/pyfpdb/FpdbSQLQueries.py
@@ -26,585 +26,616 @@ import os
class FpdbSQLQueries:
- def __init__(self, db):
- self.query = {}
- self.dbname = db
+ def __init__(self, db):
+ self.query = {}
+ self.dbname = db
-#Boilerplate code.
-# if(self.dbname == 'MySQL InnoDB'):
-# self.query[''] = """ """
-# elif(self.dbname == 'PostgreSQL'):
-# elif(self.dbname == 'SQLite'):
+ ################################
+ # List tables
+ ################################
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['list_tables'] = """SHOW TABLES"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['list_tables'] = """SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"""
+ elif(self.dbname == 'SQLite'):
+ self.query['list_tables'] = """ """
+
+ ##################################################################
+ # Drop Tables - MySQL, PostgreSQL and SQLite all share same syntax
+ ##################################################################
+
+ if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL') or (self.dbname == 'SQLite'):
+ self.query['drop_table'] = """DROP TABLE IF EXISTS """
- ################################
- # List tables
- ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['list_tables'] = """SHOW TABLES"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['list_tables'] = """SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"""
- elif(self.dbname == 'SQLite'):
- self.query['list_tables'] = """ """
+ ################################
+ # Create Tables
+ ################################
- ##################################################################
- # Drop Tables - MySQL, PostgreSQL and SQLite all share same syntax
- ##################################################################
+ ################################
+ # Create Settings
+ ################################
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createSettingsTable'] = """CREATE TABLE Settings (
+ version SMALLINT NOT NULL)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createSettingsTable'] = """CREATE TABLE Settings (version SMALLINT)"""
- if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL') or (self.dbname == 'SQLite'):
- self.query['drop_table'] = """DROP TABLE IF EXISTS """
-
-
- ################################
- # Create Tables
- ################################
-
- ################################
- # Create Settings
- ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createSettingsTable'] = """CREATE TABLE Settings (
- version SMALLINT NOT NULL)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createSettingsTable'] = """CREATE TABLE Settings (version SMALLINT)"""
-
- elif(self.dbname == 'SQLite'):
+ elif(self.dbname == 'SQLite'):
#Probably doesn't work.
- self.query['createSettingsTable'] = """ """
+ self.query['createSettingsTable'] = """ """
- ################################
- # Create Sites
- ################################
+ ################################
+ # Create Sites
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createSitesTable'] = """CREATE TABLE Sites (
- id SMALLINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- name varchar(32) NOT NULL,
- currency char(3) NOT NULL)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createSitesTable'] = """CREATE TABLE Sites (
- id SERIAL UNIQUE, PRIMARY KEY (id),
- name varchar(32),
- currency char(3))"""
- elif(self.dbname == 'SQLite'):
- self.query['createSitesTable'] = """ """
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createSitesTable'] = """CREATE TABLE Sites (
+ id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ name varchar(32) NOT NULL,
+ currency char(3) NOT NULL)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createSitesTable'] = """CREATE TABLE Sites (
+ id SERIAL, PRIMARY KEY (id),
+ name varchar(32),
+ currency char(3))"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createSitesTable'] = """ """
- ################################
- # Create Gametypes
- ################################
+ ################################
+ # Create Gametypes
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
- id SMALLINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
- type char(4) NOT NULL,
- base char(4) NOT NULL,
- category varchar(9) NOT NULL,
- limitType char(2) NOT NULL,
- hiLo char(1) NOT NULL,
- smallBlind int,
- bigBlind int,
- smallBet int NOT NULL,
- bigBet int NOT NULL)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
- id SERIAL UNIQUE, PRIMARY KEY (id),
- siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
- type char(4),
- base char(4),
- category varchar(9),
- limitType char(2),
- hiLo char(1),
- smallBlind int,
- bigBlind int,
- smallBet int,
- bigBet int)"""
- elif(self.dbname == 'SQLite'):
- self.query['createGametypesTable'] = """ """
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
+ id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
+ type char(4) NOT NULL,
+ base char(4) NOT NULL,
+ category varchar(9) NOT NULL,
+ limitType char(2) NOT NULL,
+ hiLo char(1) NOT NULL,
+ smallBlind int,
+ bigBlind int,
+ smallBet int NOT NULL,
+ bigBet int NOT NULL)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
+ id SERIAL, PRIMARY KEY (id),
+ siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
+ type char(4),
+ base char(4),
+ category varchar(9),
+ limitType char(2),
+ hiLo char(1),
+ smallBlind int,
+ bigBlind int,
+ smallBet int,
+ bigBet int)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createGametypesTable'] = """ """
- ################################
- # Create Players
- ################################
+ ################################
+ # Create Players
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createPlayersTable'] = """CREATE TABLE Players (
- id INT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- name VARCHAR(32) CHARACTER SET utf8 NOT NULL,
- siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
- comment text,
- commentTs DATETIME)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createPlayersTable'] = """CREATE TABLE Players (
- id SERIAL UNIQUE, PRIMARY KEY (id),
- name VARCHAR(32),
- siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
- comment text,
- commentTs timestamp without time zone)"""
- elif(self.dbname == 'SQLite'):
- self.query['createPlayersTable'] = """ """
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createPlayersTable'] = """CREATE TABLE Players (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ name VARCHAR(32) CHARACTER SET utf8 NOT NULL,
+ siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
+ comment text,
+ commentTs DATETIME)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createPlayersTable'] = """CREATE TABLE Players (
+ id SERIAL, PRIMARY KEY (id),
+ name VARCHAR(32),
+ siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
+ comment text,
+ commentTs timestamp without time zone)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createPlayersTable'] = """ """
- ################################
- # Create Autorates
- ################################
+ ################################
+ # Create Autorates
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
- gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
- description varchar(50) NOT NULL,
- shortDesc char(8) NOT NULL,
- ratingTime DATETIME NOT NULL,
- handCount int NOT NULL)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
- playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
- gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
- description varchar(50),
- shortDesc char(8),
- ratingTime timestamp without time zone,
- handCount int)"""
- elif(self.dbname == 'SQLite'):
- self.query['createAutoratesTable'] = """ """
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
+ gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
+ description varchar(50) NOT NULL,
+ shortDesc char(8) NOT NULL,
+ ratingTime DATETIME NOT NULL,
+ handCount int NOT NULL)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
+ id BIGSERIAL, PRIMARY KEY (id),
+ playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
+ gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
+ description varchar(50),
+ shortDesc char(8),
+ ratingTime timestamp without time zone,
+ handCount int)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createAutoratesTable'] = """ """
- ################################
- # Create Hands
- ################################
+ ################################
+ # Create Hands
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createHandsTable'] = """CREATE TABLE Hands (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- tableName VARCHAR(20) NOT NULL,
- siteHandNo BIGINT NOT NULL,
- gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
- handStart DATETIME NOT NULL,
- importTime DATETIME NOT NULL,
- seats SMALLINT NOT NULL,
- maxSeats SMALLINT NOT NULL,
- comment TEXT,
- commentTs DATETIME)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createHandsTable'] = """CREATE TABLE Hands (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
- tableName VARCHAR(20),
- siteHandNo BIGINT,
- gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
- handStart timestamp without time zone,
- importTime timestamp without time zone,
- seats SMALLINT,
- maxSeats SMALLINT,
- comment TEXT,
- commentTs timestamp without time zone)"""
- elif(self.dbname == 'SQLite'):
- self.query['createHandsTable'] = """ """
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createHandsTable'] = """CREATE TABLE Hands (
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ tableName VARCHAR(20) NOT NULL,
+ siteHandNo BIGINT NOT NULL,
+ gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
+ handStart DATETIME NOT NULL,
+ importTime DATETIME NOT NULL,
+ seats SMALLINT NOT NULL,
+ maxSeats SMALLINT NOT NULL,
+ comment TEXT,
+ commentTs DATETIME)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createHandsTable'] = """CREATE TABLE Hands (
+ id BIGSERIAL, PRIMARY KEY (id),
+ tableName VARCHAR(20),
+ siteHandNo BIGINT,
+ gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
+ handStart timestamp without time zone,
+ importTime timestamp without time zone,
+ seats SMALLINT,
+ maxSeats SMALLINT,
+ comment TEXT,
+ commentTs timestamp without time zone)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createHandsTable'] = """ """
- ################################
- # Create Gametypes
- ################################
+ ################################
+ # Create Gametypes
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createBoardCardsTable'] = """CREATE TABLE BoardCards (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- handId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
- card1Value smallint NOT NULL,
- card1Suit char(1) NOT NULL,
- card2Value smallint NOT NULL,
- card2Suit char(1) NOT NULL,
- card3Value smallint NOT NULL,
- card3Suit char(1) NOT NULL,
- card4Value smallint NOT NULL,
- card4Suit char(1) NOT NULL,
- card5Value smallint NOT NULL,
- card5Suit char(1) NOT NULL)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createBoardCardsTable'] = """CREATE TABLE BoardCards (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
- handId BIGINT, FOREIGN KEY (handId) REFERENCES Hands(id),
- card1Value smallint,
- card1Suit char(1),
- card2Value smallint,
- card2Suit char(1),
- card3Value smallint,
- card3Suit char(1),
- card4Value smallint,
- card4Suit char(1),
- card5Value smallint,
- card5Suit char(1))"""
- elif(self.dbname == 'SQLite'):
- self.query['createBoardCardsTable'] = """ """
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createBoardCardsTable'] = """CREATE TABLE BoardCards (
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ handId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
+ card1Value smallint NOT NULL,
+ card1Suit char(1) NOT NULL,
+ card2Value smallint NOT NULL,
+ card2Suit char(1) NOT NULL,
+ card3Value smallint NOT NULL,
+ card3Suit char(1) NOT NULL,
+ card4Value smallint NOT NULL,
+ card4Suit char(1) NOT NULL,
+ card5Value smallint NOT NULL,
+ card5Suit char(1) NOT NULL)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createBoardCardsTable'] = """CREATE TABLE BoardCards (
+ id BIGSERIAL, PRIMARY KEY (id),
+ handId BIGINT, FOREIGN KEY (handId) REFERENCES Hands(id),
+ card1Value smallint,
+ card1Suit char(1),
+ card2Value smallint,
+ card2Suit char(1),
+ card3Value smallint,
+ card3Suit char(1),
+ card4Value smallint,
+ card4Suit char(1),
+ card5Value smallint,
+ card5Suit char(1))"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createBoardCardsTable'] = """ """
- ################################
- # Create TourneyTypes
- ################################
+ ################################
+ # Create TourneyTypes
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
- id SMALLINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
- buyin INT NOT NULL,
- fee INT NOT NULL,
- knockout INT NOT NULL,
- rebuyOrAddon BOOLEAN NOT NULL)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
- id SERIAL, PRIMARY KEY (id),
- siteId INT, FOREIGN KEY (siteId) REFERENCES Sites(id),
- buyin INT,
- fee INT,
- knockout INT,
- rebuyOrAddon BOOLEAN)"""
- elif(self.dbname == 'SQLite'):
- self.query['createTourneyTypesTable'] = """ """
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
+ id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
+ buyin INT NOT NULL,
+ fee INT NOT NULL,
+ knockout INT NOT NULL,
+ rebuyOrAddon BOOLEAN NOT NULL)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
+ id SERIAL, PRIMARY KEY (id),
+ siteId INT, FOREIGN KEY (siteId) REFERENCES Sites(id),
+ buyin INT,
+ fee INT,
+ knockout INT,
+ rebuyOrAddon BOOLEAN)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createTourneyTypesTable'] = """ """
- ################################
- # Create Tourneys
- ################################
+ ################################
+ # Create Tourneys
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
- id INT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- tourneyTypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
- siteTourneyNo BIGINT NOT NULL,
- entries INT NOT NULL,
- prizepool INT NOT NULL,
- startTime DATETIME NOT NULL,
- comment TEXT,
- commentTs DATETIME)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
- id SERIAL UNIQUE, PRIMARY KEY (id),
- tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
- siteTourneyNo BIGINT,
- entries INT,
- prizepool INT,
- startTime timestamp without time zone,
- comment TEXT,
- commentTs timestamp without time zone)"""
- elif(self.dbname == 'SQLite'):
- self.query['createTourneysTable'] = """ """
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ tourneyTypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
+ siteTourneyNo BIGINT NOT NULL,
+ entries INT NOT NULL,
+ prizepool INT NOT NULL,
+ startTime DATETIME NOT NULL,
+ comment TEXT,
+ commentTs DATETIME)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
+ id SERIAL, PRIMARY KEY (id),
+ tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
+ siteTourneyNo BIGINT,
+ entries INT,
+ prizepool INT,
+ startTime timestamp without time zone,
+ comment TEXT,
+ commentTs timestamp without time zone)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createTourneysTable'] = """ """
- ################################
- # Create HandsPlayers
- ################################
+ ################################
+ # Create HandsPlayers
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- handId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
- playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
- startCash INT NOT NULL,
- position CHAR(1),
- seatNo SMALLINT NOT NULL,
- ante INT,
-
- card1Value smallint NOT NULL,
- card1Suit char(1) NOT NULL,
- card2Value smallint NOT NULL,
- card2Suit char(1) NOT NULL,
- card3Value smallint,
- card3Suit char(1),
- card4Value smallint,
- card4Suit char(1),
- card5Value smallint,
- card5Suit char(1),
- card6Value smallint,
- card6Suit char(1),
- card7Value smallint,
- card7Suit char(1),
-
- winnings int NOT NULL,
- rake int NOT NULL,
- comment text,
- commentTs DATETIME,
-
- tourneysPlayersId BIGINT UNSIGNED, FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
- handId BIGINT, FOREIGN KEY (handId) REFERENCES Hands(id),
- playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
- startCash INT,
- position CHAR(1),
- seatNo SMALLINT,
- ante INT,
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ handId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
+ playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
+ startCash INT NOT NULL,
+ position CHAR(1),
+ seatNo SMALLINT NOT NULL,
+ ante INT,
+
+ card1Value smallint NOT NULL,
+ card1Suit char(1) NOT NULL,
+ card2Value smallint NOT NULL,
+ card2Suit char(1) NOT NULL,
+ card3Value smallint,
+ card3Suit char(1),
+ card4Value smallint,
+ card4Suit char(1),
+ card5Value smallint,
+ card5Suit char(1),
+ card6Value smallint,
+ card6Suit char(1),
+ card7Value smallint,
+ card7Suit char(1),
+
+ winnings int NOT NULL,
+ rake int NOT NULL,
+ comment text,
+ commentTs DATETIME,
+
+ tourneysPlayersId BIGINT UNSIGNED, FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
+ id BIGSERIAL, PRIMARY KEY (id),
+ handId BIGINT, FOREIGN KEY (handId) REFERENCES Hands(id),
+ playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
+ startCash INT,
+ position CHAR(1),
+ seatNo SMALLINT,
+ ante INT,
- card1Value smallint,
- card1Suit char(1),
- card2Value smallint,
- card2Suit char(1),
- card3Value smallint,
- card3Suit char(1),
- card4Value smallint,
- card4Suit char(1),
- card5Value smallint,
- card5Suit char(1),
- card6Value smallint,
- card6Suit char(1),
- card7Value smallint,
- card7Suit char(1),
+ card1Value smallint,
+ card1Suit char(1),
+ card2Value smallint,
+ card2Suit char(1),
+ card3Value smallint,
+ card3Suit char(1),
+ card4Value smallint,
+ card4Suit char(1),
+ card5Value smallint,
+ card5Suit char(1),
+ card6Value smallint,
+ card6Suit char(1),
+ card7Value smallint,
+ card7Suit char(1),
- winnings int,
- rake int,
- comment text,
- commentTs timestamp without time zone,
- tourneysPlayersId BIGINT, FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))"""
- elif(self.dbname == 'SQLite'):
- self.query['createHandsPlayersTable'] = """ """
+ winnings int,
+ rake int,
+ comment text,
+ commentTs timestamp without time zone,
+ tourneysPlayersId BIGINT, FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createHandsPlayersTable'] = """ """
- ################################
- # Create TourneysPlayers
- ################################
+ ################################
+ # Create TourneysPlayers
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- tourneyId INT UNSIGNED NOT NULL, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id),
- playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
- payinAmount INT NOT NULL,
- rank INT NOT NULL,
- winnings INT NOT NULL,
- comment TEXT,
- commentTs DATETIME)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
- tourneyId INT, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id),
- playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
- payinAmount INT,
- rank INT,
- winnings INT,
- comment TEXT,
- commentTs timestamp without time zone)"""
- elif(self.dbname == 'SQLite'):
- self.query['createTourneysPlayersTable'] = """ """
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers (
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ tourneyId INT UNSIGNED NOT NULL, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id),
+ playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
+ payinAmount INT NOT NULL,
+ rank INT NOT NULL,
+ winnings INT NOT NULL,
+ comment TEXT,
+ commentTs DATETIME)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers (
+ id BIGSERIAL, PRIMARY KEY (id),
+ tourneyId INT, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id),
+ playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
+ payinAmount INT,
+ rank INT,
+ winnings INT,
+ comment TEXT,
+ commentTs timestamp without time zone)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createTourneysPlayersTable'] = """ """
- ################################
- # Create HandsActions
- ################################
+ ################################
+ # Create HandsActions
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- handPlayerId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handPlayerId) REFERENCES HandsPlayers(id),
- street SMALLINT NOT NULL,
- actionNo SMALLINT NOT NULL,
- action CHAR(5) NOT NULL,
- allIn BOOLEAN NOT NULL,
- amount INT NOT NULL,
- comment TEXT,
- commentTs DATETIME)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
- handPlayerId BIGINT, FOREIGN KEY (handPlayerId) REFERENCES HandsPlayers(id),
- street SMALLINT,
- actionNo SMALLINT,
- action CHAR(5),
- allIn BOOLEAN,
- amount INT,
- comment TEXT,
- commentTs timestamp without time zone)"""
- elif(self.dbname == 'SQLite'):
- self.query['createHandsActionsTable'] = """ """
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ handPlayerId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handPlayerId) REFERENCES HandsPlayers(id),
+ street SMALLINT NOT NULL,
+ actionNo SMALLINT NOT NULL,
+ action CHAR(5) NOT NULL,
+ allIn BOOLEAN NOT NULL,
+ amount INT NOT NULL,
+ comment TEXT,
+ commentTs DATETIME)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
+ id BIGSERIAL, PRIMARY KEY (id),
+ handPlayerId BIGINT, FOREIGN KEY (handPlayerId) REFERENCES HandsPlayers(id),
+ street SMALLINT,
+ actionNo SMALLINT,
+ action CHAR(5),
+ allIn BOOLEAN,
+ amount INT,
+ comment TEXT,
+ commentTs timestamp without time zone)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createHandsActionsTable'] = """ """
- ################################
- # Create HudCache
- ################################
+ ################################
+ # Create HudCache
+ ################################
- if(self.dbname == 'MySQL InnoDB'):
- self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
- gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
- playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
- activeSeats SMALLINT NOT NULL,
- position CHAR(1),
- tourneyTypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
-
- HDs INT NOT NULL,
- street0VPI INT NOT NULL,
- street0Aggr INT NOT NULL,
- street0_3B4BChance INT NOT NULL,
- street0_3B4BDone INT NOT NULL,
-
- street1Seen INT NOT NULL,
- street2Seen INT NOT NULL,
- street3Seen INT NOT NULL,
- street4Seen INT NOT NULL,
- sawShowdown INT NOT NULL,
-
- street1Aggr INT NOT NULL,
- street2Aggr INT NOT NULL,
- street3Aggr INT NOT NULL,
- street4Aggr INT NOT NULL,
-
- otherRaisedStreet1 INT NOT NULL,
- otherRaisedStreet2 INT NOT NULL,
- otherRaisedStreet3 INT NOT NULL,
- otherRaisedStreet4 INT NOT NULL,
- foldToOtherRaisedStreet1 INT NOT NULL,
- foldToOtherRaisedStreet2 INT NOT NULL,
- foldToOtherRaisedStreet3 INT NOT NULL,
- foldToOtherRaisedStreet4 INT NOT NULL,
- wonWhenSeenStreet1 FLOAT NOT NULL,
- wonAtSD FLOAT NOT NULL,
-
- stealAttemptChance INT NOT NULL,
- stealAttempted INT NOT NULL,
- foldBbToStealChance INT NOT NULL,
- foldedBbToSteal INT NOT NULL,
- foldSbToStealChance INT NOT NULL,
- foldedSbToSteal INT NOT NULL,
-
- street1CBChance INT NOT NULL,
- street1CBDone INT NOT NULL,
- street2CBChance INT NOT NULL,
- street2CBDone INT NOT NULL,
- street3CBChance INT NOT NULL,
- street3CBDone INT NOT NULL,
- street4CBChance INT NOT NULL,
- street4CBDone INT NOT NULL,
-
- foldToStreet1CBChance INT NOT NULL,
- foldToStreet1CBDone INT NOT NULL,
- foldToStreet2CBChance INT NOT NULL,
- foldToStreet2CBDone INT NOT NULL,
- foldToStreet3CBChance INT NOT NULL,
- foldToStreet3CBDone INT NOT NULL,
- foldToStreet4CBChance INT NOT NULL,
- foldToStreet4CBDone INT NOT NULL,
-
- totalProfit INT NOT NULL,
-
- street1CheckCallRaiseChance INT NOT NULL,
- street1CheckCallRaiseDone INT NOT NULL,
- street2CheckCallRaiseChance INT NOT NULL,
- street2CheckCallRaiseDone INT NOT NULL,
- street3CheckCallRaiseChance INT NOT NULL,
- street3CheckCallRaiseDone INT NOT NULL,
- street4CheckCallRaiseChance INT NOT NULL,
- street4CheckCallRaiseDone INT NOT NULL)
- ENGINE=INNODB"""
- elif(self.dbname == 'PostgreSQL'):
- self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
- gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
- playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
- activeSeats SMALLINT,
- position CHAR(1),
- tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
+ playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
+ activeSeats SMALLINT NOT NULL,
+ position CHAR(1),
+ tourneyTypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
+
+ HDs INT NOT NULL,
+ street0VPI INT NOT NULL,
+ street0Aggr INT NOT NULL,
+ street0_3B4BChance INT NOT NULL,
+ street0_3B4BDone INT NOT NULL,
+
+ street1Seen INT NOT NULL,
+ street2Seen INT NOT NULL,
+ street3Seen INT NOT NULL,
+ street4Seen INT NOT NULL,
+ sawShowdown INT NOT NULL,
+
+ street1Aggr INT NOT NULL,
+ street2Aggr INT NOT NULL,
+ street3Aggr INT NOT NULL,
+ street4Aggr INT NOT NULL,
+
+ otherRaisedStreet1 INT NOT NULL,
+ otherRaisedStreet2 INT NOT NULL,
+ otherRaisedStreet3 INT NOT NULL,
+ otherRaisedStreet4 INT NOT NULL,
+ foldToOtherRaisedStreet1 INT NOT NULL,
+ foldToOtherRaisedStreet2 INT NOT NULL,
+ foldToOtherRaisedStreet3 INT NOT NULL,
+ foldToOtherRaisedStreet4 INT NOT NULL,
+ wonWhenSeenStreet1 FLOAT NOT NULL,
+ wonAtSD FLOAT NOT NULL,
+
+ stealAttemptChance INT NOT NULL,
+ stealAttempted INT NOT NULL,
+ foldBbToStealChance INT NOT NULL,
+ foldedBbToSteal INT NOT NULL,
+ foldSbToStealChance INT NOT NULL,
+ foldedSbToSteal INT NOT NULL,
+
+ street1CBChance INT NOT NULL,
+ street1CBDone INT NOT NULL,
+ street2CBChance INT NOT NULL,
+ street2CBDone INT NOT NULL,
+ street3CBChance INT NOT NULL,
+ street3CBDone INT NOT NULL,
+ street4CBChance INT NOT NULL,
+ street4CBDone INT NOT NULL,
+
+ foldToStreet1CBChance INT NOT NULL,
+ foldToStreet1CBDone INT NOT NULL,
+ foldToStreet2CBChance INT NOT NULL,
+ foldToStreet2CBDone INT NOT NULL,
+ foldToStreet3CBChance INT NOT NULL,
+ foldToStreet3CBDone INT NOT NULL,
+ foldToStreet4CBChance INT NOT NULL,
+ foldToStreet4CBDone INT NOT NULL,
+
+ totalProfit INT NOT NULL,
+
+ street1CheckCallRaiseChance INT NOT NULL,
+ street1CheckCallRaiseDone INT NOT NULL,
+ street2CheckCallRaiseChance INT NOT NULL,
+ street2CheckCallRaiseDone INT NOT NULL,
+ street3CheckCallRaiseChance INT NOT NULL,
+ street3CheckCallRaiseDone INT NOT NULL,
+ street4CheckCallRaiseChance INT NOT NULL,
+ street4CheckCallRaiseDone INT NOT NULL)
+ ENGINE=INNODB"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
+ id BIGSERIAL, PRIMARY KEY (id),
+ gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
+ playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
+ activeSeats SMALLINT,
+ position CHAR(1),
+ tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
- HDs INT,
- street0VPI INT,
- street0Aggr INT,
- street0_3B4BChance INT,
- street0_3B4BDone INT,
- street1Seen INT,
- street2Seen INT,
- street3Seen INT,
- street4Seen INT,
- sawShowdown INT,
- street1Aggr INT,
- street2Aggr INT,
- street3Aggr INT,
- street4Aggr INT,
- otherRaisedStreet1 INT,
- otherRaisedStreet2 INT,
- otherRaisedStreet3 INT,
- otherRaisedStreet4 INT,
- foldToOtherRaisedStreet1 INT,
- foldToOtherRaisedStreet2 INT,
- foldToOtherRaisedStreet3 INT,
- foldToOtherRaisedStreet4 INT,
- wonWhenSeenStreet1 FLOAT,
- wonAtSD FLOAT,
+ HDs INT,
+ street0VPI INT,
+ street0Aggr INT,
+ street0_3B4BChance INT,
+ street0_3B4BDone INT,
+ street1Seen INT,
+ street2Seen INT,
+ street3Seen INT,
+ street4Seen INT,
+ sawShowdown INT,
+ street1Aggr INT,
+ street2Aggr INT,
+ street3Aggr INT,
+ street4Aggr INT,
+ otherRaisedStreet1 INT,
+ otherRaisedStreet2 INT,
+ otherRaisedStreet3 INT,
+ otherRaisedStreet4 INT,
+ foldToOtherRaisedStreet1 INT,
+ foldToOtherRaisedStreet2 INT,
+ foldToOtherRaisedStreet3 INT,
+ foldToOtherRaisedStreet4 INT,
+ wonWhenSeenStreet1 FLOAT,
+ wonAtSD FLOAT,
- stealAttemptChance INT,
- stealAttempted INT,
- foldBbToStealChance INT,
- foldedBbToSteal INT,
- foldSbToStealChance INT,
- foldedSbToSteal INT,
+ stealAttemptChance INT,
+ stealAttempted INT,
+ foldBbToStealChance INT,
+ foldedBbToSteal INT,
+ foldSbToStealChance INT,
+ foldedSbToSteal INT,
- street1CBChance INT,
- street1CBDone INT,
- street2CBChance INT,
- street2CBDone INT,
- street3CBChance INT,
- street3CBDone INT,
- street4CBChance INT,
- street4CBDone INT,
+ street1CBChance INT,
+ street1CBDone INT,
+ street2CBChance INT,
+ street2CBDone INT,
+ street3CBChance INT,
+ street3CBDone INT,
+ street4CBChance INT,
+ street4CBDone INT,
- foldToStreet1CBChance INT,
- foldToStreet1CBDone INT,
- foldToStreet2CBChance INT,
- foldToStreet2CBDone INT,
- foldToStreet3CBChance INT,
- foldToStreet3CBDone INT,
- foldToStreet4CBChance INT,
- foldToStreet4CBDone INT,
+ foldToStreet1CBChance INT,
+ foldToStreet1CBDone INT,
+ foldToStreet2CBChance INT,
+ foldToStreet2CBDone INT,
+ foldToStreet3CBChance INT,
+ foldToStreet3CBDone INT,
+ foldToStreet4CBChance INT,
+ foldToStreet4CBDone INT,
- totalProfit INT,
+ totalProfit INT,
- street1CheckCallRaiseChance INT,
- street1CheckCallRaiseDone INT,
- street2CheckCallRaiseChance INT,
- street2CheckCallRaiseDone INT,
- street3CheckCallRaiseChance INT,
- street3CheckCallRaiseDone INT,
- street4CheckCallRaiseChance INT,
- street4CheckCallRaiseDone INT)"""
- elif(self.dbname == 'SQLite'):
- self.query['createHudCacheTable'] = """ """
+ street1CheckCallRaiseChance INT,
+ street1CheckCallRaiseDone INT,
+ street2CheckCallRaiseChance INT,
+ street2CheckCallRaiseDone INT,
+ street3CheckCallRaiseChance INT,
+ street3CheckCallRaiseDone INT,
+ street4CheckCallRaiseChance INT,
+ street4CheckCallRaiseDone INT)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['createHudCacheTable'] = """ """
- ################################
- # Queries used in GuiGraphViewer
- ################################
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)"""
+ elif(self.dbname == 'PostgreSQL'):
+ # FIXME: This query has a different syntax
+ self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['addHandsIndex'] = """ """
+
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
+ elif(self.dbname == 'PostgreSQL'):
+ # FIXME: This query has a different syntax
+ self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['addHandsIndex'] = """ """
+
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['addPlayersIndex'] = """ALTER TABLE Players ADD INDEX name(name)"""
+ elif(self.dbname == 'PostgreSQL'):
+ # FIXME: This query has a different syntax
+ self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
+ elif(self.dbname == 'SQLite'):
+ self.query['addHandsIndex'] = """ """
+
+ ################################
+ # Queries used in GuiGraphViewer
+ ################################
- # Returns all cash game handIds and the money won(winnings is the final pot)
- # by the playerId for a single site.
- if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
- self.query['getRingWinningsAllGamesPlayerIdSite'] = """SELECT handId, winnings FROM HandsPlayers
- INNER JOIN Players ON HandsPlayers.playerId = Players.id
- INNER JOIN Hands ON Hands.id = HandsPlayers.handId
- WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)
- ORDER BY handStart"""
- elif(self.dbname == 'SQLite'):
- #Probably doesn't work.
- self.query['getRingWinningsAllGamesPlayerIdSite'] = """SELECT handId, winnings FROM HandsPlayers
- INNER JOIN Players ON HandsPlayers.playerId = Players.id
- INNER JOIN Hands ON Hands.id = HandsPlayers.handId
- WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)
- ORDER BY handStart"""
+ # Returns all cash game handIds and the money won(winnings is the final pot)
+ # by the playerId for a single site.
+ if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
+ self.query['getRingWinningsAllGamesPlayerIdSite'] = """SELECT handId, winnings FROM HandsPlayers
+ INNER JOIN Players ON HandsPlayers.playerId = Players.id
+ INNER JOIN Hands ON Hands.id = HandsPlayers.handId
+ WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)
+ ORDER BY handStart"""
+ elif(self.dbname == 'SQLite'):
+ #Probably doesn't work.
+ self.query['getRingWinningsAllGamesPlayerIdSite'] = """SELECT handId, winnings FROM HandsPlayers
+ INNER JOIN Players ON HandsPlayers.playerId = Players.id
+ INNER JOIN Hands ON Hands.id = HandsPlayers.handId
+ WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)
+ ORDER BY handStart"""
- # Returns the profit for all hands, Total pot - money invested by playerId
- if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
- self.query['getRingProfitAllHandsPlayerIdSite'] = """
- SELECT hp.handId, hp.winnings, SUM(ha.amount) costs, hp.winnings - SUM(ha.amount) profit
+ # Returns the profit for a given ring game handId, Total pot - money invested by playerId
+ if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
+ self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
+ INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
+ INNER JOIN Players ON HandsPlayers.playerId = Players.id
+ WHERE Players.name = %s AND HandsPlayers.handId = %s
+ AND Players.siteId = %s AND (tourneysPlayersId IS NULL)"""
+ elif(self.dbname == 'SQLite'):
+ #Probably doesn't work.
+ self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
+ INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
+ INNER JOIN Players ON HandsPlayers.playerId = Players.id
+ WHERE Players.name = %s AND HandsPlayers.handId = %s
+ AND Players.siteId = %s AND (tourneysPlayersId IS NULL)"""
+
+ if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
+ self.query['getRingProfitAllHandsPlayerIdSite'] = """
+ SELECT hp.handId, hp.winnings, SUM(ha.amount), hp.winnings - SUM(ha.amount)
FROM HandsPlayers hp
INNER JOIN Players pl ON hp.playerId = pl.id
INNER JOIN Hands h ON h.id = hp.handId
@@ -612,12 +643,12 @@ class FpdbSQLQueries:
WHERE pl.name = %s
AND pl.siteId = %s
AND hp.tourneysPlayersId IS NULL
- group by hp.handId, hp.winnings, h.handStart
+ GROUP BY hp.handId, hp.winnings, h.handStart
ORDER BY h.handStart"""
- elif(self.dbname == 'SQLite'):
- #May not work.
- self.query['getRingProfitAllHandsPlayerIdSite'] = """
- SELECT hp.handId, hp.winnings, SUM(ha.amount) costs, hp.winnings - SUM(ha.amount) profit
+ elif(self.dbname == 'SQLite'):
+ #Probably doesn't work.
+ self.query['getRingProfitAllHandsPlayerIdSite'] = """
+ SELECT hp.handId, hp.winnings, SUM(ha.amount), hp.winnings - SUM(ha.amount)
FROM HandsPlayers hp
INNER JOIN Players pl ON hp.playerId = pl.id
INNER JOIN Hands h ON h.id = hp.handId
@@ -625,24 +656,206 @@ class FpdbSQLQueries:
WHERE pl.name = %s
AND pl.siteId = %s
AND hp.tourneysPlayersId IS NULL
- group by hp.handId, hp.winnings, h.handStart
+ GROUP BY hp.handId, hp.winnings, h.handStart
ORDER BY h.handStart"""
- # Returns the profit for a given ring game handId, Total pot - money invested by playerId - WRONG, returns players costs
- if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
- self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
- INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
- INNER JOIN Players ON HandsPlayers.playerId = Players.id
- WHERE Players.name = %s AND HandsPlayers.handId = %s
- AND Players.siteId = %s AND (tourneysPlayersId IS NULL)"""
- elif(self.dbname == 'SQLite'):
- #Probably doesn't work.
- self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
- INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
- INNER JOIN Players ON HandsPlayers.playerId = Players.id
- WHERE Players.name = %s AND HandsPlayers.handId = %s
- AND Players.siteId = %s AND (tourneysPlayersId IS NULL)"""
+ # Returns the profit for a given ring game handId, Total pot - money invested by playerId - WRONG, returns players costs
+ if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
+ self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
+ INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
+ INNER JOIN Players ON HandsPlayers.playerId = Players.id
+ WHERE Players.name = %s AND HandsPlayers.handId = %s
+ AND Players.siteId = %s AND (tourneysPlayersId IS NULL)"""
+ elif(self.dbname == 'SQLite'):
+ #Probably doesn't work.
+ self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
+ INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
+ INNER JOIN Players ON HandsPlayers.playerId = Players.id
+ WHERE Players.name = %s AND HandsPlayers.handId = %s
+ AND Players.siteId = %s AND (tourneysPlayersId IS NULL)"""
+ # Returns a list of the tables in the database
+ if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
+ self.query['getTableList'] = """
+ SELECT table_name
+ FROM information_schema.tables
+ WHERE table_type = 'BASE TABLE'
+ AND table_schema = %s
+ """
+ elif(self.dbname == 'getTableList'):
+ #Probably doesn't work.
+ self.query['getTableList'] = """
+ SELECT table_name
+ FROM information_schema.tables
+ WHERE table_type = 'BASE TABLE'
+ AND table_schema = %s
+ """
+
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['playerStats'] = """
+ SELECT stats.gametypeId
+ ,stats.base
+ ,stats.limitType
+ ,stats.name
+ ,format(stats.bigBlind/100,2) as BigBlind
+ ,stats.n
+ ,stats.vpip
+ ,stats.pfr
+ ,stats.saw_f
+ ,stats.sawsd
+ ,stats.wtsdwsf
+ ,stats.wmsd
+ ,stats.FlAFq
+ ,stats.TuAFq
+ ,stats.RvAFq
+ ,stats.PFAFq
+ ,hprof2.sum_profit/100 as Net
+ ,(hprof2.sum_profit/stats.bigBlind)/(stats.n/100) as BBlPer100
+ FROM
+ (select # stats from hudcache
+ gt.base
+ ,upper(gt.limitType) limitType
+ ,s.name
+ ,gt.bigBlind
+ ,hc.gametypeId
+ ,sum(HDs) as n
+ ,round(100*sum(street0VPI)/sum(HDs)) as vpip
+ ,round(100*sum(street0Aggr)/sum(HDs)) as pfr
+ ,round(100*sum(street1Seen)/sum(HDs)) AS saw_f
+ ,round(100*sum(sawShowdown)/sum(HDs)) AS sawsd
+ ,round(100*sum(sawShowdown)/sum(street1Seen)) AS wtsdwsf
+ ,round(100*sum(wonAtSD)/sum(sawShowdown)) AS wmsd
+ ,round(100*sum(street1Aggr)/sum(street1Seen)) AS FlAFq
+ ,round(100*sum(street2Aggr)/sum(street2Seen)) AS TuAFq
+ ,round(100*sum(street3Aggr)/sum(street3Seen)) AS RvAFq
+ ,round(100*(sum(street1Aggr)+sum(street2Aggr)+sum(street3Aggr))
+ /(sum(street1Seen)+sum(street2Seen)+sum(street3Seen))) AS PFAFq
+ from Gametypes gt
+ inner join Sites s on s.Id = gt.siteId
+ inner join HudCache hc on hc.gameTypeId = gt.Id
+ where gt.limittype = 'nl'
+ and hc.playerId in (3) # use here?
+ # use here ?
+ group by hc.gametypeId
+ ) stats
+ inner join
+ ( select # profit from handsplayers/handsactions
+ hprof.gameTypeId, sum(hprof.profit) sum_profit
+ from
+ (select hp.handId, h.gameTypeId, hp.winnings, SUM(ha.amount)
+ costs, hp.winnings - SUM(ha.amount) profit
+ from HandsPlayers hp
+ inner join Hands h ON h.id = hp.handId
+ inner join HandsActions ha ON ha.handPlayerId = hp.id
+ where hp.playerId in (3) # use here?
+ # use here ?
+ and hp.tourneysPlayersId IS NULL
+ group by hp.handId, h.gameTypeId, hp.position, hp.winnings
+ ) hprof
+ group by hprof.gameTypeId
+ ) hprof2
+ on hprof2.gameTypeId = stats.gameTypeId
+ order by stats.base, stats.limittype, stats.bigBlind"""
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['playerStats'] = """ """
+ elif(self.dbname == 'SQLite'):
+ self.query['playerStats'] = """ """
+
+ if(self.dbname == 'MySQL InnoDB'):
+ self.query['playerStatsByPosition'] = """
+ SELECT stats.gametypeId
+ ,stats.base
+ ,stats.limitType
+ ,stats.name
+ ,format(stats.bigBlind/100,2) as BigBlind
+ ,p.name
+ ,stats.pl_position
+ ,stats.n
+ ,stats.vpip
+ ,stats.pfr
+ ,stats.saw_f
+ ,stats.sawsd
+ ,stats.wtsdwsf
+ ,stats.wmsd
+ ,stats.FlAFq
+ ,stats.TuAFq
+ ,stats.RvAFq
+ ,stats.PFAFq
+ ,hprof2.sum_profit/100 as Net
+ ,(hprof2.sum_profit/stats.bigBlind)/(stats.n/100) as BBlPer100
+ # ... any other stats you want to add
+ FROM
+ (select # stats from hudcache
+ hc.playerId
+ ,gt.base
+ ,upper(gt.limitType) as limitType
+ ,s.name
+ ,gt.bigBlind
+ ,hc.gametypeId
+ ,case when hc.position = 'B' then -2
+ when hc.position = 'S' then -1
+ when hc.position = 'D' then 0
+ when hc.position = 'C' then 1
+ when hc.position = 'M' then 2
+ when hc.position = 'E' then 5
+ else 9
+ end as pl_position
+ ,sum(HDs) as n
+ ,round(100*sum(street0VPI)/sum(HDs)) as vpip
+ ,round(100*sum(street0Aggr)/sum(HDs)) as pfr
+ ,round(100*sum(street1Seen)/sum(HDs)) AS saw_f
+ ,round(100*sum(sawShowdown)/sum(HDs)) AS sawsd
+ ,round(100*sum(sawShowdown)/sum(street1Seen)) AS wtsdwsf
+ ,round(100*sum(wonAtSD)/sum(sawShowdown)) AS wmsd
+ ,round(100*sum(street1Aggr)/sum(street1Seen)) AS FlAFq
+ ,round(100*sum(street2Aggr)/sum(street2Seen)) AS TuAFq
+ ,round(100*sum(street3Aggr)/sum(street3Seen)) AS RvAFq
+ ,round(100*(sum(street1Aggr)+sum(street2Aggr)+sum(street3Aggr))
+ /(sum(street1Seen)+sum(street2Seen)+sum(street3Seen))) AS PFAFq
+ from Gametypes gt
+ inner join Sites s on (s.Id = gt.siteId)
+ inner join HudCache hc on (hc.gameTypeId = gt.Id)
+ where gt.limittype = 'nl'
+ and hc.playerId in (3) # always specify player for position stats
+ # use here
+ # use here
+ group by hc.playerId, hc.gametypeId, pl_position
+ ) stats
+ inner join
+ ( select # profit from handsplayers/handsactions
+ hprof.playerId
+ , hprof.gameTypeId
+ , case when hprof.position = 'B' then -2
+ when hprof.position = 'S' then -1
+ when hprof.position in ('3','4') then 2
+ when hprof.position in ('6','7') then 5
+ else hprof.position
+ end as pl_position
+ , sum(hprof.profit) as sum_profit
+ from
+ (select hp.playerId, hp.handId, h.gameTypeId, hp.position, hp.winnings
+ , SUM(ha.amount) costs, hp.winnings - SUM(ha.amount) profit
+ from HandsPlayers hp
+ inner join Hands h ON (h.id = hp.handId)
+ inner join HandsActions ha ON (ha.handPlayerId = hp.id)
+ where hp.playerId in (3) # always specify player for position stats
+ # use here
+ # use here
+ and hp.tourneysPlayersId IS NULL
+ group by hp.playerId, hp.handId, h.gameTypeId, hp.position, hp.winnings
+ ) hprof
+ group by hprof.playerId, hprof.gameTypeId, pl_position
+ ) hprof2
+ on ( hprof2.gameTypeId = stats.gameTypeId
+ and hprof2.pl_position = stats.pl_position)
+ inner join Players p on (p.id = stats.playerId)
+ where 1 = 1
+ order by stats.base, stats.limittype, stats.bigBlind, stats.pl_position, BBlPer100 desc
+ """
+ elif(self.dbname == 'PostgreSQL'):
+ self.query['playerStatsByPosition'] = """ """
+ elif(self.dbname == 'SQLite'):
+ self.query['playerStatsByPosition'] = """ """
if __name__== "__main__":
from optparse import OptionParser
diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py
index 92a5ed86..1c5c97bb 100644
--- a/pyfpdb/fpdb_db.py
+++ b/pyfpdb/fpdb_db.py
@@ -21,65 +21,67 @@ import fpdb_simple
import FpdbSQLQueries
class fpdb_db:
- def __init__(self):
- """Simple constructor, doesnt really do anything"""
- self.db=None
- self.cursor=None
- self.sql = {}
- self.MYSQL_INNODB=2
- self.PGSQL=3
- self.SQLITE=4
- #end def __init__
-
- def connect(self, backend, host, database, user, password):
- """Connects a database with the given parameters"""
- self.backend=backend
- self.host=host
- self.database=database
- self.user=user
- self.password=password
- if backend==self.MYSQL_INNODB:
- import MySQLdb
- self.db=MySQLdb.connect(host = host, user = user, passwd = password, db = database)
- elif backend==self.PGSQL:
- import psycopg2
- self.db = psycopg2.connect(host = host, user = user, password = password, database = database)
- else:
- raise fpdb_simple.FpdbError("unrecognised database backend:"+backend)
- self.cursor=self.db.cursor()
- # Set up query dictionary as early in the connection process as we can.
+ def __init__(self):
+ """Simple constructor, doesnt really do anything"""
+ self.db=None
+ self.cursor=None
+ self.sql = {}
+ self.MYSQL_INNODB=2
+ self.PGSQL=3
+ self.SQLITE=4
+ #end def __init__
+
+ def connect(self, backend, host, database, user, password):
+ """Connects a database with the given parameters"""
+ self.backend=backend
+ self.host=host
+ self.database=database
+ self.user=user
+ self.password=password
+ if backend==self.MYSQL_INNODB:
+ import MySQLdb
+ self.db=MySQLdb.connect(host = host, user = user, passwd = password, db = database)
+ elif backend==self.PGSQL:
+ import psycopg2
+ self.db = psycopg2.connect(host = host, user = user, password = password, database = database)
+ else:
+ raise fpdb_simple.FpdbError("unrecognised database backend:"+backend)
+ self.cursor=self.db.cursor()
+ self.cursor.execute('SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED')
+
+ # Set up query dictionary as early in the connection process as we can.
self.sql = FpdbSQLQueries.FpdbSQLQueries(self.get_backend_name())
- self.wrongDbVersion=False
- try:
- self.cursor.execute("SELECT * FROM Settings")
- settings=self.cursor.fetchone()
- if settings[0]!=118:
- print "outdated or too new database version - please recreate tables"
- self.wrongDbVersion=True
- except:# _mysql_exceptions.ProgrammingError:
- print "failed to read settings table - please recreate tables"
- self.wrongDbVersion=True
- #end def connect
+ self.wrongDbVersion=False
+ try:
+ self.cursor.execute("SELECT * FROM Settings")
+ settings=self.cursor.fetchone()
+ if settings[0]!=118:
+ print "outdated or too new database version - please recreate tables"
+ self.wrongDbVersion=True
+ except:# _mysql_exceptions.ProgrammingError:
+ print "failed to read settings table - please recreate tables"
+ self.wrongDbVersion=True
+ #end def connect
- def disconnect(self, due_to_error=False):
- """Disconnects the DB"""
- if due_to_error:
- self.db.rollback()
- else:
- self.db.commit()
- self.cursor.close()
- self.db.close()
- #end def disconnect
-
- def reconnect(self, due_to_error=False):
- """Reconnects the DB"""
- #print "started fpdb_db.reconnect"
- self.disconnect(due_to_error)
- self.connect(self.backend, self.host, self.database, self.user, self.password)
+ def disconnect(self, due_to_error=False):
+ """Disconnects the DB"""
+ if due_to_error:
+ self.db.rollback()
+ else:
+ self.db.commit()
+ self.cursor.close()
+ self.db.close()
+ #end def disconnect
+
+ def reconnect(self, due_to_error=False):
+ """Reconnects the DB"""
+ #print "started fpdb_db.reconnect"
+ self.disconnect(due_to_error)
+ self.connect(self.backend, self.host, self.database, self.user, self.password)
- def create_tables(self):
- #todo: should detect and fail gracefully if tables already exist.
- self.cursor.execute(self.sql.query['createSettingsTable'])
+ def create_tables(self):
+ #todo: should detect and fail gracefully if tables already exist.
+ self.cursor.execute(self.sql.query['createSettingsTable'])
self.cursor.execute(self.sql.query['createSitesTable'])
self.cursor.execute(self.sql.query['createGametypesTable'])
self.cursor.execute(self.sql.query['createPlayersTable'])
@@ -92,81 +94,84 @@ class fpdb_db:
self.cursor.execute(self.sql.query['createHandsPlayersTable'])
self.cursor.execute(self.sql.query['createHandsActionsTable'])
self.cursor.execute(self.sql.query['createHudCacheTable'])
- self.fillDefaultData()
+ self.cursor.execute(self.sql.query['addTourneyIndex'])
+ self.cursor.execute(self.sql.query['addHandsIndex'])
+ self.cursor.execute(self.sql.query['addPlayersIndex'])
+ self.fillDefaultData()
self.db.commit()
#end def disconnect
-
- def drop_tables(self):
- """Drops the fpdb tables from the current db"""
+
+ def drop_tables(self):
+ """Drops the fpdb tables from the current db"""
- if(self.get_backend_name() == 'MySQL InnoDB'):
- #Databases with FOREIGN KEY support need this switched of before you can drop tables
- self.drop_referencial_integrity()
+ if(self.get_backend_name() == 'MySQL InnoDB'):
+ #Databases with FOREIGN KEY support need this switched of before you can drop tables
+ self.drop_referencial_integrity()
- # Query the DB to see what tables exist
- self.cursor.execute(self.sql.query['list_tables'])
- for table in self.cursor:
- self.cursor.execute(self.sql.query['drop_table'] + table[0])
- elif(self.get_backend_name() == 'PostgreSQL'):
- self.db.commit()# I have no idea why this makes the query work--REB 07OCT2008
- self.cursor.execute(self.sql.query['list_tables'])
- tables = self.cursor.fetchall()
- for table in tables:
- self.cursor.execute(self.sql.query['drop_table'] + table[0] + ' cascade')
- elif(self.get_backend_name() == 'SQLite'):
- #todo: sqlite version here
- print "Empty function here"
+ # Query the DB to see what tables exist
+ self.cursor.execute(self.sql.query['list_tables'])
+ for table in self.cursor:
+ self.cursor.execute(self.sql.query['drop_table'] + table[0])
+ elif(self.get_backend_name() == 'PostgreSQL'):
+ self.db.commit()# I have no idea why this makes the query work--REB 07OCT2008
+ self.cursor.execute(self.sql.query['list_tables'])
+ tables = self.cursor.fetchall()
+ for table in tables:
+ self.cursor.execute(self.sql.query['drop_table'] + table[0] + ' cascade')
+ elif(self.get_backend_name() == 'SQLite'):
+ #todo: sqlite version here
+ print "Empty function here"
self.db.commit()
- #end def drop_tables
+ #end def drop_tables
- def drop_referencial_integrity(self):
- """Update all tables to remove foreign keys"""
+ def drop_referencial_integrity(self):
+ """Update all tables to remove foreign keys"""
- self.cursor.execute(self.sql.query['list_tables'])
- result = self.cursor.fetchall()
+ self.cursor.execute(self.sql.query['list_tables'])
+ result = self.cursor.fetchall()
- for i in range(len(result)):
- self.cursor.execute("SHOW CREATE TABLE " + result[i][0])
- inner = self.cursor.fetchall()
+ for i in range(len(result)):
+ self.cursor.execute("SHOW CREATE TABLE " + result[i][0])
+ inner = self.cursor.fetchall()
- for j in range(len(inner)):
- # result[i][0] - Table name
- # result[i][1] - CREATE TABLE parameters
- #Searching for CONSTRAINT `tablename_ibfk_1`
- for m in re.finditer('(ibfk_[0-9]+)', inner[j][1]):
- key = "`" + inner[j][0] + "_" + m.group() + "`"
- self.cursor.execute("ALTER TABLE " + inner[j][0] + " DROP FOREIGN KEY " + key)
+ for j in range(len(inner)):
+ # result[i][0] - Table name
+ # result[i][1] - CREATE TABLE parameters
+ #Searching for CONSTRAINT `tablename_ibfk_1`
+ for m in re.finditer('(ibfk_[0-9]+)', inner[j][1]):
+ key = "`" + inner[j][0] + "_" + m.group() + "`"
+ self.cursor.execute("ALTER TABLE " + inner[j][0] + " DROP FOREIGN KEY " + key)
self.db.commit()
#end drop_referencial_inegrity
-
- def get_backend_name(self):
- """Returns the name of the currently used backend"""
- if self.backend==2:
- return "MySQL InnoDB"
- elif self.backend==3:
- return "PostgreSQL"
- else:
- raise fpdb_simple.FpdbError("invalid backend")
- #end def get_backend_name
-
- def get_db_info(self):
- return (self.host, self.database, self.user, self.password)
- #end def get_db_info
-
- def fillDefaultData(self):
- self.cursor.execute("INSERT INTO Settings VALUES (118);")
- self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Full Tilt Poker', 'USD');")
- self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'PokerStars', 'USD');")
- self.cursor.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);")
- #end def fillDefaultData
-
- def recreate_tables(self):
- """(Re-)creates the tables of the current DB"""
-
- self.drop_tables()
- self.create_tables()
- self.db.commit()
- print "Finished recreating tables"
- #end def recreate_tables
+
+ def get_backend_name(self):
+ """Returns the name of the currently used backend"""
+ if self.backend==2:
+ return "MySQL InnoDB"
+ elif self.backend==3:
+ return "PostgreSQL"
+ else:
+ raise fpdb_simple.FpdbError("invalid backend")
+ #end def get_backend_name
+
+ def get_db_info(self):
+ return (self.host, self.database, self.user, self.password)
+ #end def get_db_info
+
+ def fillDefaultData(self):
+ self.cursor.execute("INSERT INTO Settings VALUES (118);")
+ self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Full Tilt Poker', 'USD');")
+ self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'PokerStars', 'USD');")
+ self.cursor.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);")
+ #end def fillDefaultData
+
+ def recreate_tables(self):
+ """(Re-)creates the tables of the current DB"""
+
+ self.drop_tables()
+ self.create_tables()
+ self.db.commit()
+ print "Finished recreating tables"
+ #end def recreate_tables
#end class fpdb_db
From 3ea95acb0cb63da7a1780c13dc4210f2fcf7e2f7 Mon Sep 17 00:00:00 2001
From: sqlcoder
Date: Mon, 8 Dec 2008 00:55:03 +0000
Subject: [PATCH 23/32] add db param to allow insert_id() matching
fpdb_parse_logic.py
---
pyfpdb/fpdb_simple.py | 4332 +++++++++++++++++++++--------------------
1 file changed, 2173 insertions(+), 2159 deletions(-)
diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py
index 01247651..11a2a1ea 100755
--- a/pyfpdb/fpdb_simple.py
+++ b/pyfpdb/fpdb_simple.py
@@ -1,2159 +1,2173 @@
-#!/usr/bin/python
-
-#Copyright 2008 Steffen Jobbagy-Felso
-#This program is free software: you can redistribute it and/or modify
-#it under the terms of the GNU Affero General Public License as published by
-#the Free Software Foundation, version 3 of the License.
-#
-#This program is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-#GNU General Public License for more details.
-#
-#You should have received a copy of the GNU Affero General Public License
-#along with this program. If not, see .
-#In the "official" distribution you can find the license in
-#agpl-3.0.txt in the docs folder of the package.
-
-#This file contains simple functions for fpdb
-
-import datetime
-import re
-
-PS=1
-FTP=2
-
-class DuplicateError(Exception):
- def __init__(self, value):
- self.value = value
- def __str__(self):
- return repr(self.value)
-
-class FpdbError(Exception):
- def __init__(self, value):
- self.value = value
- def __str__(self):
- return repr(self.value)
-
-#returns an array of the total money paid. intending to add rebuys/addons here
-def calcPayin(count, buyin, fee):
- result=[]
- for i in range(count):
- result.append (buyin+fee)
- return result
-#end def calcPayin
-
-def checkPositions(positions):
- """verifies that these positions are valid"""
- for i in range (len(positions)):
- pos=positions[i]
- try:#todo: use type recognition instead of error
- if (len(pos)!=1):
- raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+pos) #dont need to str() here
- except TypeError:#->not string->is int->fine
- pass
-
- ### RHH modified to allow for "position 9" here (pos==9 is when you're a dead hand before the BB
- ### eric - position 8 could be valid - if only one blind is posted, but there's still 10 people, ie a sitout is present, and the small is dead...
- if not (pos == "B" or pos == "S" or (pos >= 0 and pos <= 9)):
- raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+str(pos))
-#end def fpdb_simple.checkPositions
-
-#classifies each line for further processing in later code. Manipulates the passed arrays.
-def classifyLines(hand, category, lineTypes, lineStreets):
- currentStreet="predeal"
- done=False #set this to true once we reach the last relevant line (the summary, except rake, is all repeats)
- for i in range (len(hand)):
- if (done):
- if (hand[i].find("[")==-1 or hand[i].find("mucked [")==-1):
- lineTypes.append("ignore")
- else: #it's storing a mucked card
- lineTypes.append("cards")
- elif (hand[i].startswith("Dealt to")):
- lineTypes.append("cards")
- elif (i==0):
- lineTypes.append("header")
- elif (hand[i].startswith("Seat ") and ((hand[i].find("in chips")!=-1) or (hand[i].find("($")!=-1))):
- lineTypes.append("name")
- elif (isActionLine(hand[i])):
- lineTypes.append("action")
- if (hand[i].find(" posts ")!=-1 or hand[i].find(" posts the ")!=-1):#need to set this here so the "action" of posting blinds is registered properly
- currentStreet="preflop"
- elif (isWinLine(hand[i])):
- lineTypes.append("win")
- elif (hand[i].startswith("Total pot ") and hand[i].find("Rake")!=-1):
- lineTypes.append("rake")
- done=True
- elif (hand[i]=="*** SHOW DOWN ***" or hand[i]=="*** SUMMARY ***"):
- lineTypes.append("ignore")
- #print "in classifyLine, showdown or summary"
- elif (hand[i].find(" antes ")!=-1 or hand[i].find(" posts the ante ")!=-1):
- lineTypes.append("ante")
- elif (hand[i].startswith("*** FLOP *** [")):
- lineTypes.append("cards")
- currentStreet="flop"
- elif (hand[i].startswith("*** TURN *** [")):
- lineTypes.append("cards")
- currentStreet="turn"
- elif (hand[i].startswith("*** RIVER *** [")):
- lineTypes.append("cards")
- currentStreet="river"
- elif (hand[i].startswith("*** 3")):
- lineTypes.append("ignore")
- currentStreet=0
- elif (hand[i].startswith("*** 4")):
- lineTypes.append("ignore")
- currentStreet=1
- elif (hand[i].startswith("*** 5")):
- lineTypes.append("ignore")
- currentStreet=2
- elif (hand[i].startswith("*** 6")):
- lineTypes.append("ignore")
- currentStreet=3
- elif (hand[i].startswith("*** 7") or hand[i]=="*** RIVER ***"):
- lineTypes.append("ignore")
- currentStreet=4
- elif (hand[i].find(" shows [")!=-1):
- lineTypes.append("cards")
- elif (hand[i].startswith("Table '")):
- lineTypes.append("table")
- else:
- raise FpdbError("unrecognised linetype in:"+hand[i])
- lineStreets.append(currentStreet)
-#end def classifyLines
-
-def convert3B4B(site, category, limit_type, actionTypes, actionAmounts):
- """calculates the actual bet amounts in the given amount array and changes it accordingly."""
- for i in range (len(actionTypes)):
- for j in range (len(actionTypes[i])):
- bets=[]
- for k in range (len(actionTypes[i][j])):
- if (actionTypes[i][j][k]=="bet"):
- bets.append((i,j,k))
- if (len(bets)==2):
- #print "len(bets) 2 or higher, need to correct it. bets:",bets,"len:",len(bets)
- amount2=actionAmounts[bets[1][0]][bets[1][1]][bets[1][2]]
- amount1=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]
- actionAmounts[bets[1][0]][bets[1][1]][bets[1][2]]=amount2-amount1
- elif (len(bets)>2):
- fail=True
- #todo: run correction for below
- if (site=="ps" and category=="holdem" and limit_type=="nl" and len(bets)==3):
- fail=False
- if (site=="ftp" and category=="omahahi" and limit_type=="pl" and len(bets)==3):
- fail=False
-
- if fail:
- print "len(bets)>2 in convert3B4B, i didnt think this is possible. i:",i,"j:",j,"k:",k
- print "actionTypes:",actionTypes
- raise FpdbError ("too many bets in convert3B4B")
- #print "actionAmounts postConvert",actionAmounts
-#end def convert3B4B(actionTypes, actionAmounts)
-
-#Corrects the bet amount if the player had to pay blinds
-def convertBlindBet(actionTypes, actionAmounts):
- i=0#setting street to pre-flop
- for j in range (len(actionTypes[i])):#playerloop
- blinds=[]
- bets=[]
- for k in range (len(actionTypes[i][j])):
- if (actionTypes[i][j][k]=="blind"):
- blinds.append((i,j,k))
-
- if (len(blinds)>0 and actionTypes[i][j][k]=="bet"):
- bets.append((i,j,k))
- if (len(bets)==1):
- blind_amount=actionAmounts[blinds[0][0]][blinds[0][1]][blinds[0][2]]
- bet_amount=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]
- actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]=bet_amount-blind_amount
-#end def convertBlindBet
-
-#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
-#todo: make this use convertCardValuesBoard
-def convertCardValues(arr):
- for i in range (len(arr)):
- for j in range (len(arr[i])):
- if (arr[i][j]=="A"):
- arr[i][j]=14
- elif (arr[i][j]=="K"):
- arr[i][j]=13
- elif (arr[i][j]=="Q"):
- arr[i][j]=12
- elif (arr[i][j]=="J"):
- arr[i][j]=11
- elif (arr[i][j]=="T"):
- arr[i][j]=10
- else:
- arr[i][j]=int(arr[i][j])
-#end def convertCardValues
-
-#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
-def convertCardValuesBoard(arr):
- for i in range (len(arr)):
- if (arr[i]=="A"):
- arr[i]=14
- elif (arr[i]=="K"):
- arr[i]=13
- elif (arr[i]=="Q"):
- arr[i]=12
- elif (arr[i]=="J"):
- arr[i]=11
- elif (arr[i]=="T"):
- arr[i]=10
- else:
- arr[i]=int(arr[i])
-#end def convertCardValuesBoard
-
-#this creates the 2D/3D arrays. manipulates the passed arrays instead of returning.
-def createArrays(category, seats, card_values, card_suits, antes, winnings, rakes, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
- for i in range(seats):#create second dimension arrays
- tmp=[]
- card_values.append(tmp)
- tmp=[]
- card_suits.append(tmp)
- antes.append(0)
- winnings.append(0)
- rakes.append(0)
-
- if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
- streetCount=4
- else:
- streetCount=5
-
- for i in range(streetCount): #build the first dimension array, for streets
- tmp=[]
- action_types.append(tmp)
- tmp=[]
- allIns.append(tmp)
- tmp=[]
- action_amounts.append(tmp)
- tmp=[]
- actionNos.append(tmp)
- tmp=[]
- actionTypeByNo.append(tmp)
- for j in range (seats): #second dimension arrays: players
- tmp=[]
- action_types[i].append(tmp)
- tmp=[]
- allIns[i].append(tmp)
- tmp=[]
- action_amounts[i].append(tmp)
- tmp=[]
- actionNos[i].append(tmp)
- if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
- pass
- elif (category=="razz" or category=="studhi" or category=="studhilo"):#need to fill card arrays.
- for i in range(seats):
- for j in range (7):
- card_values[i].append(0)
- card_suits[i].append("x")
- else:
- raise FpdbError("invalid category")
-#end def createArrays
-
-def fill_board_cards(board_values, board_suits):
-#fill up the two board card arrays
- while (len(board_values)<5):
- board_values.append(0)
- board_suits.append("x")
-#end def fill_board_cards
-
-def fillCardArrays(player_count, base, category, card_values, card_suits):
- """fills up the two card arrays"""
- if (category=="holdem"):
- cardCount=2
- elif (category=="omahahi" or category=="omahahilo"):
- cardCount=4
- elif base=="stud":
- cardCount=7
- else:
- raise fpdb_simple.FpdbError ("invalid category:", category)
-
- for i in range (player_count):
- while (len(card_values[i])=1):
- raise DuplicateError ("dupl")
-#end isAlreadyInDB
-
-def isRebuyOrAddon(topline):
- """isRebuyOrAddon not implemented yet"""
- return False
-#end def isRebuyOrAddon
-
-#returns whether the passed topline indicates a tournament or not
-def isTourney(topline):
- if (topline.find("Tournament")!=-1):
- return True
- else:
- return False
-#end def isTourney
-
-#returns boolean whether the passed line is a win line
-def isWinLine(line):
- if (line.find("wins the pot")!=-1):
- return True
- elif (line.find("ties for the high pot")!=-1):
- return True
- elif (line.find("ties for the high main pot")!=-1):
- return True
- elif (line.find("ties for the high side pot")!=-1):
- return True
- elif (line.find("ties for the low pot")!=-1):
- return True
- elif (line.find("ties for the low main pot")!=-1):
- return True
- elif (line.find("ties for the low side pot")!=-1):
- return True
- elif (line.find("ties for the main pot")!=-1): #for ftp tied main pot of split pot
- return True
- elif (line.find("ties for the pot")!=-1): #for ftp tie
- return True
- elif (line.find("ties for the side pot")!=-1): #for ftp tied split pots
- return True
- elif (line.find("wins side pot #")!=-1): #for ftp multi split pots
- return True
- elif (line.find("wins the low main pot")!=-1):
- return True
- elif (line.find("wins the low pot")!=-1):
- return True
- elif (line.find("wins the low side pot")!=-1):
- return True
- elif (line.find("wins the high main pot")!=-1):
- return True
- elif (line.find("wins the high pot")!=-1):
- return True
- elif (line.find("wins the high side pot")!=-1):
- return True
- elif (line.find("wins the main pot")!=-1):
- return True
- elif (line.find("wins the side pot")!=-1): #for ftp split pots
- return True
- elif (line.find("collected")!=-1):
- return True
- else:
- return False #not raising error here, any unknown line wouldve been detected in isActionLine already
-#end def isWinLine
-
-#returns the amount of cash/chips put into the put in the given action line
-def parseActionAmount(line, atype, site, isTourney):
- #if (line.endswith(" and is all-in")):
- # line=line[:-14]
- #elif (line.endswith(", and is all in")):
- # line=line[:-15]
-
- if line.endswith(", and is capped"):#ideally we should recognise this as an all-in if category is capXl
- line=line[:-15]
- if line.endswith(" and is capped"):
- line=line[:-14]
-
-
- if (atype=="fold"):
- amount=0
- elif (atype=="check"):
- amount=0
- elif (atype=="unbet" and site=="ftp"):
- pos1=line.find("$")+1
- pos2=line.find(" returned to")
- amount=float2int(line[pos1:pos2])
- elif (atype=="unbet" and site=="ps"):
- #print "ps unbet, line:",line
- pos1=line.find("$")+1
- if pos1==0:
- pos1=line.find("(")+1
- pos2=line.find(")")
- amount=float2int(line[pos1:pos2])
- elif (atype=="bet" and site=="ps" and line.find(": raises $")!=-1 and line.find("to $")!=-1):
- pos=line.find("to $")+4
- amount=float2int(line[pos:])
- else:
- if not isTourney:
- pos=line.rfind("$")+1
- #print "parseActionAmount, line:", line, "line[pos:]:", line[pos:]
- amount=float2int(line[pos:])
- else:
- #print "line:"+line+"EOL"
- pos=line.rfind(" ")+1
- #print "pos:",pos
- #print "pos of 20:", line.find("20")
- amount=int(line[pos:])
-
- if atype=="unbet":
- amount*=-1
- return amount
-#end def parseActionAmount
-
-#doesnt return anything, simply changes the passed arrays action_types and
-# action_amounts. For stud this expects numeric streets (3-7), for
-# holdem/omaha it expects predeal, preflop, flop, turn or river
-def parseActionLine(site, base, isTourney, line, street, playerIDs, names, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
- if (street=="predeal" or street=="preflop"):
- street=0
- elif (street=="flop"):
- street=1
- elif (street=="turn"):
- street=2
- elif (street=="river"):
- street=3
-
- nextActionNo=0
- for player in range(len(actionNos[street])):
- for count in range(len(actionNos[street][player])):
- if actionNos[street][player][count]>=nextActionNo:
- nextActionNo=actionNos[street][player][count]+1
-
- line, allIn=goesAllInOnThisLine(line)
- atype=parseActionType(line)
- playerno=recognisePlayerNo(line, names, atype)
- amount=parseActionAmount(line, atype, site, isTourney)
-
- action_types[street][playerno].append(atype)
- allIns[street][playerno].append(allIn)
- action_amounts[street][playerno].append(amount)
- actionNos[street][playerno].append(nextActionNo)
- tmp=(playerIDs[playerno], atype)
- actionTypeByNo[street].append(tmp)
-#end def parseActionLine
-
-def goesAllInOnThisLine(line):
- """returns whether the player went all-in on this line and removes the all-in text from the line."""
- isAllIn=False
- if (line.endswith(" and is all-in")):
- line=line[:-14]
- isAllIn=True
- elif (line.endswith(", and is all in")):
- line=line[:-15]
- isAllIn=True
- return (line, isAllIn)
-#end def goesAllInOnThisLine
-
-#returns the action type code (see table design) of the given action line
-def parseActionType(line):
- if (line.startswith("Uncalled bet")):
- return "unbet"
- elif (line.endswith("folds")):
- return "fold"
- elif (line.endswith("checks")):
- return "check"
- elif (line.find("calls")!=-1):
- return "call"
- elif (line.find("brings in for")!=-1):
- return "blind"
- elif (line.find("completes it to")!=-1):
- return "bet"
- #todo: what if someone completes instead of bringing in?
- elif (line.find(" posts $")!=-1):
- return "blind"
- elif (line.find(" posts a dead ")!=-1):
- return "blind"
- elif (line.find(": posts small blind ")!=-1):
- return "blind"
- elif (line.find(" posts the small blind of $")!=-1):
- return "blind"
- elif (line.find(": posts big blind ")!=-1):
- return "blind"
- elif (line.find(" posts the big blind of $")!=-1):
- return "blind"
- elif (line.find(": posts small & big blinds $")!=-1):
- return "blind"
- #todo: seperately record voluntary blind payments made to join table out of turn
- elif (line.find("bets")!=-1):
- return "bet"
- elif (line.find("raises")!=-1):
- return "bet"
- else:
- raise FpdbError ("failed to recognise actiontype in parseActionLine in: "+line)
-#end def parseActionType
-
-#parses the ante out of the given line and checks which player paid it, updates antes accordingly.
-def parseAnteLine(line, site, isTourney, names, antes):
- for i in range(len(names)):
- if (line.startswith(names[i].encode("latin-1"))): #found the ante'er
- pos=line.rfind("$")+1
- if not isTourney:
- antes[i]+=float2int(line[pos:])
- else:
- if line.find("all-in")==-1:
- pos=line.rfind(" ")+1
- antes[i]+=int(line[pos:])
- else:
- pos1=line.rfind("ante")+5
- pos2=line.find(" ",pos1)
- antes[i]+=int(line[pos1:pos2])
- #print "parseAnteLine line: ", line, "antes[i]", antes[i], "antes", antes
-#end def parseAntes
-
-#returns the buyin of a tourney in cents
-def parseBuyin(topline):
- pos1=topline.find("$")+1
- pos2=topline.find("+")
- return float2int(topline[pos1:pos2])
-#end def parseBuyin
-
-#parses a card line and changes the passed arrays accordingly
-#todo: reorganise this messy method
-def parseCardLine(site, category, street, line, names, cardValues, cardSuits, boardValues, boardSuits):
- if (line.startswith("Dealt to ") or line.find(" shows [")!=-1 or line.find("mucked [")!=-1):
- playerNo=recognisePlayerNo(line, names, "card") #anything but unbet will be ok for that string
-
- pos=line.rfind("[")+1
- if (category=="holdem"):
- for i in (pos, pos+3):
- cardValues[playerNo].append(line[i:i+1])
- cardSuits[playerNo].append(line[i+1:i+2])
- if (len(cardValues[playerNo])!=2):
- if cardValues[playerNo][0]==cardValues[playerNo][2] and cardSuits[playerNo][1]==cardSuits[playerNo][3]: #two tests will do
- cardValues[playerNo]=cardValues[playerNo][0:2]
- cardSuits[playerNo]=cardSuits[playerNo][0:2]
- else:
- print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
- raise FpdbError("read too many/too few holecards in parseCardLine")
- elif (category=="omahahi" or category=="omahahilo"):
- for i in (pos, pos+3, pos+6, pos+9):
- cardValues[playerNo].append(line[i:i+1])
- cardSuits[playerNo].append(line[i+1:i+2])
- if (len(cardValues[playerNo])!=4):
- if cardValues[playerNo][0]==cardValues[playerNo][4] and cardSuits[playerNo][3]==cardSuits[playerNo][7]: #two tests will do
- cardValues[playerNo]=cardValues[playerNo][0:4]
- cardSuits[playerNo]=cardSuits[playerNo][0:4]
- else:
- print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
- raise FpdbError("read too many/too few holecards in parseCardLine")
- elif (category=="razz" or category=="studhi" or category=="studhilo"):
- if (line.find("shows")==-1 and line.find("mucked") == -1):
- #print "parseCardLine(in stud if), street:", street
- if line[pos+2]=="]": #-> not (hero and 3rd street)
- cardValues[playerNo][street+2]=line[pos:pos+1]
- cardSuits[playerNo][street+2]=line[pos+1:pos+2]
- else:
- #print "hero card1:", line[pos:pos+2], "hero card2:", line[pos+3:pos+5], "hero card3:", line[pos+6:pos+8],
- cardValues[playerNo][street]=line[pos:pos+1]
- cardSuits[playerNo][street]=line[pos+1:pos+2]
- cardValues[playerNo][street+1]=line[pos+3:pos+4]
- cardSuits[playerNo][street+1]=line[pos+4:pos+5]
- cardValues[playerNo][street+2]=line[pos+6:pos+7]
- cardSuits[playerNo][street+2]=line[pos+7:pos+8]
- else:
- #print "parseCardLine(in stud else), street:", street
- cardValues[playerNo][0]=line[pos:pos+1]
- cardSuits[playerNo][0]=line[pos+1:pos+2]
- pos+=3
- cardValues[playerNo][1]=line[pos:pos+1]
- cardSuits[playerNo][1]=line[pos+1:pos+2]
- if street==4:
- pos=pos=line.rfind("]")-2
- cardValues[playerNo][6]=line[pos:pos+1]
- cardSuits[playerNo][6]=line[pos+1:pos+2]
- #print "cardValues:", cardValues
- #print "cardSuits:", cardSuits
- else:
- print "line:",line,"street:",street
- raise FpdbError("invalid category")
- #print "end of parseCardLine/playercards, cardValues:",cardValues
- elif (line.startswith("*** FLOP ***")):
- pos=line.find("[")+1
- for i in (pos, pos+3, pos+6):
- boardValues.append(line[i:i+1])
- boardSuits.append(line[i+1:i+2])
- #print boardValues
- elif (line.startswith("*** TURN ***") or line.startswith("*** RIVER ***")):
- pos=line.find("[")+1
- pos=line.find("[", pos+1)+1
- boardValues.append(line[pos:pos+1])
- boardSuits.append(line[pos+1:pos+2])
- #print boardValues
- else:
- raise FpdbError ("unrecognised line:"+line)
-#end def parseCardLine
-
-def parseCashesAndSeatNos(lines, site):
- """parses the startCashes and seatNos of each player out of the given lines and returns them as a dictionary of two arrays"""
- cashes = []
- seatNos = []
- for i in range (len(lines)):
- pos2=lines[i].find(":")
- seatNos.append(int(lines[i][5:pos2]))
-
- pos1=lines[i].rfind("($")+2
- if pos1==1: #for tourneys - it's 1 instead of -1 due to adding 2 above
- pos1=lines[i].rfind("(")+1
- if (site=="ftp"):
- pos2=lines[i].rfind(")")
- elif (site=="ps"):
- pos2=lines[i].find(" in chips")
- cashes.append(float2int(lines[i][pos1:pos2]))
- return {'startCashes':cashes, 'seatNos':seatNos}
-#end def parseCashesAndSeatNos
-
-#returns the buyin of a tourney in cents
-def parseFee(topline):
- pos1=topline.find("$")+1
- pos1=topline.find("$",pos1)+1
- pos2=topline.find(" ", pos1)
- return float2int(topline[pos1:pos2])
-#end def parsefee
-
-#returns a datetime object with the starttime indicated in the given topline
-def parseHandStartTime(topline, site):
- #convert x:13:35 to 0x:13:35
- counter=0
- while (True):
- pos=topline.find(" "+str(counter)+":")
- if (pos!=-1):
- topline=topline[0:pos+1]+"0"+topline[pos+1:]
- counter+=1
- if counter==10: break
-
- isUTC=False
- if site=="ftp":
- pos = topline.find(" ", len(topline)-26)+1
- tmp = topline[pos:]
- #print "year:", tmp[14:18], "month", tmp[19:21], "day", tmp[22:24], "hour", tmp[0:2], "minute", tmp[3:5], "second", tmp[6:8]
- result = datetime.datetime(int(tmp[14:18]), int(tmp[19:21]), int(tmp[22:24]), int(tmp[0:2]), int(tmp[3:5]), int(tmp[6:8]))
- elif site=="ps":
- if topline.find("UTC")!=-1:
- pos1 = topline.find("-")+2
- pos2 = topline.find("UTC")
- tmp=topline[pos1:pos2]
- isUTC=True
- else:
- tmp=topline
- # print "parsehandStartTime, tmp:", tmp
- pos = tmp.find("-")+2
- tmp = tmp[pos:]
- #Need to match either
- # 2008/09/07 06:23:14 ET or
- # 2008/08/17 - 01:14:43 (ET) or
- # 2008/11/12 9:33:31 CET [2008/11/12 3:33:31 ET]
- rexx = '(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P
[0-9]+):(?P[0-9]+):(?P[0-9]+)'
- m = re.search(rexx,tmp)
- #print "year:", int(m.group('YEAR')), "month", int(m.group('MON')), "day", int(m.group('DAY')), "hour", int(m.group('HR')), "minute", int(m.group('MIN')), "second", int(m.group('SEC'))
- result = datetime.datetime(int(m.group('YEAR')), int(m.group('MON')), int(m.group('DAY')), int(m.group('HR')), int(m.group('MIN')), int(m.group('SEC')))
- else:
- raise FpdbError("invalid site in parseHandStartTime")
-
- if (site=="ftp" or site=="ps") and not isUTC: #these use US ET
- result+=datetime.timedelta(hours=5)
-
- return result
-#end def parseHandStartTime
-
-#parses the names out of the given lines and returns them as an array
-def parseNames(lines):
- result = []
- for i in range (len(lines)):
- pos1=lines[i].find(":")+2
- pos2=lines[i].rfind("(")-1
- tmp=lines[i][pos1:pos2]
- #print "parseNames, tmp original:",tmp
- tmp=unicode(tmp,"latin-1")
- #print "parseNames, tmp after unicode latin-1 conversion:",tmp
- result.append(tmp)
- return result
-#end def parseNames
-
-#returns an array with the positions of the respective players
-def parsePositions (hand, names):
- #prep array
- positions=[]
- for i in range(len(names)):
- positions.append(-1)
-
- #find blinds
- sb,bb=-1,-1
- for i in range (len(hand)):
- if (sb==-1 and hand[i].find("small blind")!=-1 and hand[i].find("dead small blind")==-1):
- sb=hand[i]
- #print "sb:",sb
- if (bb==-1 and hand[i].find("big blind")!=-1 and hand[i].find("dead big blind")==-1):
- bb=hand[i]
- #print "bb:",bb
-
- #identify blinds
- #print "parsePositions before recognising sb/bb. names:",names
- sbExists=True
- if (sb!=-1):
- sb=recognisePlayerNo(sb, names, "bet")
- else:
- sbExists=False
- if (bb!=-1):
- bb=recognisePlayerNo(bb, names, "bet")
-
-# print "sb = ", sb, "bb = ", bb
- if bb == sb:
- sbExists = False
- sb = -1
-
- #write blinds into array
- if (sbExists):
- positions[sb]="S"
- positions[bb]="B"
-
- #fill up rest of array
- if (sbExists):
- arraypos=sb-1
- else:
- arraypos=bb-1
- distFromBtn=0
- while (arraypos>=0 and arraypos != bb):
- #print "parsePositions first while, arraypos:",arraypos,"positions:",positions
- positions[arraypos]=distFromBtn
- arraypos-=1
- distFromBtn+=1
- # eric - this takes into account dead seats between blinds
- if sbExists:
- i = bb - 1
- while positions[i] < 0 and i != sb:
- positions[i] = 9
- i -= 1
- ### RHH - Changed to set the null seats before BB to "9"
- if sbExists:
- i = sb-1
- else:
- i = bb-1
-
- while positions[i] < 0:
- positions[i]=9
- i-=1
-
- arraypos=len(names)-1
- if (bb!=0 or (bb==0 and sbExists==False) or (bb == 1 and sb != arraypos) ):
- while (arraypos>bb and arraypos > sb):
- positions[arraypos]=distFromBtn
- arraypos-=1
- distFromBtn+=1
-
- for i in range (len(names)):
- if positions[i]==-1:
- print "parsePositions names:",names
- print "result:",positions
- raise FpdbError ("failed to read positions")
- #print str(positions), "\n"
- return positions
-#end def parsePositions
-
-#simply parses the rake amount and returns it as an int
-def parseRake(line):
- pos=line.find("Rake")+6
- rake=float2int(line[pos:])
- return rake
-#end def parseRake
-
-def parseSiteHandNo(topline):
- """returns the hand no assigned by the poker site"""
- pos1=topline.find("#")+1
- pos2=topline.find(":")
- return topline[pos1:pos2]
-#end def parseSiteHandNo
-
-def parseTableLine(site, base, line):
- """returns a dictionary with maxSeats and tableName"""
- if site=="ps":
- pos1=line.find('\'')+1
- pos2=line.find('\'', pos1)
- #print "table:",line[pos1:pos2]
- pos3=pos2+2
- pos4=line.find("-max")
- #print "seats:",line[pos3:pos4]
- return {'maxSeats':int(line[pos3:pos4]), 'tableName':line[pos1:pos2]}
- elif site=="ftp":
- pos1=line.find("Table ")+6
- pos2=line.find("-")-1
- if base=="hold":
- maxSeats=9
- elif base=="stud":
- maxSeats=8
-
- if line.find("6 max")!=-1:
- maxSeats=6
- elif line.find("4 max")!=-1:
- maxSeats=4
- elif line.find("heads up")!=-1:
- maxSeats=2
-
- return {'maxSeats':maxSeats, 'tableName':line[pos1:pos2]}
- else:
- raise FpdbError("invalid site ID")
-#end def parseTableLine
-
-#returns the hand no assigned by the poker site
-def parseTourneyNo(topline):
- pos1=topline.find("Tournament #")+12
- pos2=topline.find(",", pos1)
- #print "parseTourneyNo pos1:",pos1," pos2:",pos2, " result:",topline[pos1:pos2]
- return topline[pos1:pos2]
-#end def parseTourneyNo
-
-#parses a win/collect line. manipulates the passed array winnings, no explicit return
-def parseWinLine(line, site, names, winnings, isTourney):
- #print "parseWinLine: line:",line
- for i in range(len(names)):
- if (line.startswith(names[i].encode("latin-1"))): #found a winner
- if isTourney:
- pos1=line.rfind("collected ")+10
- if (site=="ftp"):
- pos2=line.find(")", pos1)
- elif (site=="ps"):
- pos2=line.find(" ", pos1)
- winnings[i]+=int(line[pos1:pos2])
- else:
- pos1=line.rfind("$")+1
- if (site=="ftp"):
- pos2=line.find(")", pos1)
- elif (site=="ps"):
- pos2=line.find(" ", pos1)
- winnings[i]+=float2int(line[pos1:pos2])
-#end def parseWinLine
-
-#returns the category (as per database) string for the given line
-def recogniseCategory(line):
- if (line.find("Razz")!=-1):
- return "razz"
- elif (line.find("Hold'em")!=-1):
- return "holdem"
- elif (line.find("Omaha")!=-1 and line.find("Hi/Lo")==-1 and line.find("H/L")==-1):
- return "omahahi"
- elif (line.find("Omaha")!=-1 and (line.find("Hi/Lo")!=-1 or line.find("H/L")!=-1)):
- return "omahahilo"
- elif (line.find("Stud")!=-1 and line.find("Hi/Lo")==-1 and line.find("H/L")==-1):
- return "studhi"
- elif (line.find("Stud")!=-1 and (line.find("Hi/Lo")!=-1 or line.find("H/L")!=-1)):
- return "studhilo"
- else:
- raise FpdbError("failed to recognise category, line:"+line)
-#end def recogniseCategory
-
-#returns the int for the gametype_id for the given line
-def recogniseGametypeID(cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy
- #if (topline.find("HORSE")!=-1):
- # raise FpdbError("recogniseGametypeID: HORSE is not yet supported.")
-
- #note: the below variable names small_bet and big_bet are misleading, in NL/PL they mean small/big blind
- if isTourney:
- type="tour"
- pos1=topline.find("(")+1
- if (topline[pos1]=="H" or topline[pos1]=="O" or topline[pos1]=="R" or topline[pos1]=="S" or topline[pos1+2]=="C"):
- pos1=topline.find("(", pos1)+1
- pos2=topline.find("/", pos1)
- small_bet=int(topline[pos1:pos2])
- else:
- type="ring"
- pos1=topline.find("$")+1
- pos2=topline.find("/$")
- small_bet=float2int(topline[pos1:pos2])
-
- pos1=pos2+2
- if isTourney:
- pos1-=1
- if (site_id==1): #ftp
- pos2=topline.find(" ", pos1)
- elif (site_id==2): #ps
- pos2=topline.find(")")
-
- if pos2<=pos1:
- pos2=topline.find(")", pos1)
-
- if isTourney:
- big_bet=int(topline[pos1:pos2])
- else:
- big_bet=float2int(topline[pos1:pos2])
-
- if (topline.find("No Limit")!=-1):
- limit_type="nl"
- if (topline.find("Cap No")!=-1):
- limit_type="cn"
- elif (topline.find("Pot Limit")!=-1):
- limit_type="pl"
- if (topline.find("Cap Pot")!=-1):
- limit_type="cp"
- else:
- limit_type="fl"
-
- #print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type
- if (limit_type=="fl"):
- cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
- else:
- cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
- result=cursor.fetchone()
- #print "tried SELECTing gametypes.id, result:",result
-
- try:
- len(result)
- except TypeError:
- if category=="holdem" or category=="omahahi" or category=="omahahilo":
- base="hold"
- else:
- base="stud"
-
- if category=="holdem" or category=="omahahi" or category=="studhi":
- hiLo='h'
- elif category=="razz":
- hiLo='l'
- else:
- hiLo='s'
-
- if (limit_type=="fl"):
- big_blind=small_bet
- if base=="hold":
- if smallBlindLine==topline:
- raise FpdbError("invalid small blind line")
- elif isTourney:
- pos=smallBlindLine.rfind(" ")+1
- small_blind=int(smallBlindLine[pos:])
- else:
- pos=smallBlindLine.rfind("$")+1
- small_blind=float2int(smallBlindLine[pos:])
- else:
- small_blind=0
- cursor.execute("""INSERT INTO Gametypes
- (siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_blind, big_blind, small_bet, big_bet))
- cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
- else:
- cursor.execute("""INSERT INTO Gametypes
- (siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind
- cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
-
- result=cursor.fetchone()
- #print "created new gametypes.id:",result
-
- return result[0]
-#end def recogniseGametypeID
-
-def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon):
- cursor.execute ("SELECT id FROM TourneyTypes WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s", (siteId, buyin, fee, knockout, rebuyOrAddon))
- result=cursor.fetchone()
- #print "tried SELECTing gametypes.id, result:",result
-
- try:
- len(result)
- except TypeError:#this means we need to create a new entry
- cursor.execute("""INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon) VALUES (%s, %s, %s, %s, %s)""", (siteId, buyin, fee, knockout, rebuyOrAddon))
- cursor.execute("SELECT id FROM TourneyTypes WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s", (siteId, buyin, fee, knockout, rebuyOrAddon))
- result=cursor.fetchone()
- return result[0]
-#end def recogniseTourneyTypeId
-
-#returns the SQL ids of the names given in an array
-def recognisePlayerIDs(cursor, names, site_id):
- result = []
- for i in range (len(names)):
- cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
- tmp=cursor.fetchall()
- if (len(tmp)==0): #new player
- cursor.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (names[i], site_id))
- #print "Number of players rows inserted: %d" % cursor.rowcount
- cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
- tmp=cursor.fetchall()
- #print "recognisePlayerIDs, names[i]:",names[i],"tmp:",tmp
- result.append(tmp[0][0])
- return result
-#end def recognisePlayerIDs
-
-#recognises the name in the given line and returns its array position in the given array
-def recognisePlayerNo(line, names, atype):
- #print "recogniseplayerno, names:",names
- for i in range (len(names)):
- if (atype=="unbet"):
- if (line.endswith(names[i].encode("latin-1"))):
- return (i)
- elif (line.startswith("Dealt to ")):
- #print "recognisePlayerNo, card precut, line:",line
- tmp=line[9:]
- #print "recognisePlayerNo, card postcut, tmp:",tmp
- if (tmp.startswith(names[i].encode("latin-1"))):
- return (i)
- elif (line.startswith("Seat ")):
- if (line.startswith("Seat 10")):
- tmp=line[9:]
- else:
- tmp=line[8:]
-
- if (tmp.startswith(names[i].encode("latin-1"))):
- return (i)
- else:
- if (line.startswith(names[i].encode("latin-1"))):
- return (i)
- #if we're here we mustve failed
- raise FpdbError ("failed to recognise player in: "+line+" atype:"+atype)
-#end def recognisePlayerNo
-
-#returns the site abbreviation for the given site
-def recogniseSite(line):
- if (line.startswith("Full Tilt Poker")):
- return "ftp"
- elif (line.startswith("PokerStars")):
- return "ps"
- else:
- raise FpdbError("failed to recognise site, line:"+line)
-#end def recogniseSite
-
-#returns the ID of the given site
-def recogniseSiteID(cursor, site):
- if (site=="ftp"):
- return 1
- #cursor.execute("SELECT id FROM Sites WHERE name = ('Full Tilt Poker')")
- elif (site=="ps"):
- return 2
- #cursor.execute("SELECT id FROM Sites WHERE name = ('PokerStars')")
- else:
- raise FpdbError("invalid site in recogniseSiteID: "+site)
- return cursor.fetchall()[0][0]
-#end def recogniseSiteID
-
-#removes trailing \n from the given array
-def removeTrailingEOL(arr):
- for i in range(len(arr)):
- if (arr[i].endswith("\n")):
- #print "arr[i] before removetrailingEOL:", arr[i]
- arr[i]=arr[i][:-1]
- #print "arr[i] after removetrailingEOL:", arr[i]
- return arr
-#end def removeTrailingEOL
-
-#splits the rake according to the proportion of pot won. manipulates the second passed array.
-def splitRake(winnings, rakes, totalRake):
- winnercnt=0
- totalWin=0
- for i in range(len(winnings)):
- if winnings[i]!=0:
- winnercnt+=1
- totalWin+=winnings[i]
- firstWinner=i
- if winnercnt==1:
- rakes[firstWinner]=totalRake
- else:
- totalWin=float(totalWin)
- for i in range(len(winnings)):
- if winnings[i]!=0:
- winPortion=winnings[i]/totalWin
- rakes[i]=totalRake*winPortion
-#end def splitRake
-
-def storeActions(cursor, handsPlayersIds, actionTypes, allIns, actionAmounts, actionNos):
-#stores into table hands_actions
- #print "start of storeActions, actionNos:",actionNos
- #print " action_amounts:",action_amounts
- for i in range (len(actionTypes)): #iterate through streets
- for j in range (len(actionTypes[i])): #iterate through names
- for k in range (len(actionTypes[i][j])): #iterate through individual actions of that player on that street
- cursor.execute ("INSERT INTO HandsActions (handPlayerId, street, actionNo, action, allIn, amount) VALUES (%s, %s, %s, %s, %s, %s)", (handsPlayersIds[j], i, actionNos[i][j][k], actionTypes[i][j][k], allIns[i][j][k], actionAmounts[i][j][k]))
-#end def storeActions
-
-def store_board_cards(cursor, hands_id, board_values, board_suits):
-#stores into table board_cards
- cursor.execute ("""INSERT INTO BoardCards (handId, card1Value, card1Suit,
- card2Value, card2Suit, card3Value, card3Suit, card4Value, card4Suit,
- card5Value, card5Suit) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
- (hands_id, board_values[0], board_suits[0], board_values[1], board_suits[1],
- board_values[2], board_suits[2], board_values[3], board_suits[3],
- board_values[4], board_suits[4]))
-#end def store_board_cards
-
-def storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats):
-#stores into table hands
- cursor.execute ("INSERT INTO Hands (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats) VALUES (%s, %s, %s, %s, %s, %s, %s)", (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.datetime.today(), maxSeats))
- #todo: find a better way of doing this...
- cursor.execute("SELECT id FROM Hands WHERE siteHandNo=%s AND gametypeId=%s", (site_hand_no, gametype_id))
- return cursor.fetchall()[0][0]
-#end def storeHands
-
-def store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos):
- result=[]
- if (category=="holdem"):
- for i in range (len(player_ids)):
- cursor.execute ("""
- INSERT INTO HandsPlayers
- (handId, playerId, startCash, position,
- card1Value, card1Suit, card2Value, card2Suit, winnings, rake, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], positions[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- winnings[i], rakes[i], seatNos[i]))
- cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
- result.append(cursor.fetchall()[0][0])
- elif (category=="omahahi" or category=="omahahilo"):
- for i in range (len(player_ids)):
- cursor.execute ("""INSERT INTO HandsPlayers
- (handId, playerId, startCash, position,
- card1Value, card1Suit, card2Value, card2Suit,
- card3Value, card3Suit, card4Value, card4Suit, winnings, rake, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], positions[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
- winnings[i], rakes[i], seatNos[i]))
- cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
- result.append(cursor.fetchall()[0][0])
- else:
- raise FpdbError("invalid category")
- return result
-#end def store_hands_players_holdem_omaha
-
-def store_hands_players_stud(cursor, hands_id, player_ids, start_cashes, antes,
- card_values, card_suits, winnings, rakes, seatNos):
-#stores hands_players rows for stud/razz games. returns an array of the resulting IDs
- result=[]
- #print "before inserts in store_hands_players_stud, antes:", antes
- for i in range (len(player_ids)):
- cursor.execute ("""INSERT INTO HandsPlayers
- (handId, playerId, startCash, ante,
- card1Value, card1Suit, card2Value, card2Suit,
- card3Value, card3Suit, card4Value, card4Suit,
- card5Value, card5Suit, card6Value, card6Suit,
- card7Value, card7Suit, winnings, rake, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
- %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], antes[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
- card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
- card_values[i][6], card_suits[i][6], winnings[i], rakes[i], seatNos[i]))
- cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
- result.append(cursor.fetchall()[0][0])
- return result
-#end def store_hands_players_stud
-
-def store_hands_players_holdem_omaha_tourney(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
-#stores hands_players for tourney holdem/omaha hands
- result=[]
- for i in range (len(player_ids)):
- if len(card_values[0])==2:
- cursor.execute ("""INSERT INTO HandsPlayers
- (handId, playerId, startCash, position,
- card1Value, card1Suit, card2Value, card2Suit,
- winnings, rake, tourneysPlayersId, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], positions[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
- elif len(card_values[0])==4:
- cursor.execute ("""INSERT INTO HandsPlayers
- (handId, playerId, startCash, position,
- card1Value, card1Suit, card2Value, card2Suit,
- card3Value, card3Suit, card4Value, card4Suit,
- winnings, rake, tourneysPlayersId, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], positions[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
- winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
- else:
- raise FpdbError ("invalid card_values length:"+str(len(card_values[0])))
- cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
- result.append(cursor.fetchall()[0][0])
-
- return result
-#end def store_hands_players_holdem_omaha_tourney
-
-def store_hands_players_stud_tourney(cursor, hands_id, player_ids, start_cashes,
- antes, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
-#stores hands_players for tourney stud/razz hands
- result=[]
- for i in range (len(player_ids)):
- cursor.execute ("""INSERT INTO HandsPlayers
- (handId, playerId, startCash, ante,
- card1Value, card1Suit, card2Value, card2Suit,
- card3Value, card3Suit, card4Value, card4Suit,
- card5Value, card5Suit, card6Value, card6Suit,
- card7Value, card7Suit, winnings, rake, tourneysPlayersId, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
- %s, %s, %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], antes[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
- card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
- card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
- cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
- result.append(cursor.fetchall()[0][0])
- return result
-#end def store_hands_players_stud_tourney
-
-def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo, winnings, totalWinnings, positions):
- """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"""
- #setup subarrays of the result dictionary.
- street0VPI=[]
- street0Aggr=[]
- street0_3B4BChance=[]
- street0_3B4BDone=[]
- street1Seen=[]
- street2Seen=[]
- street3Seen=[]
- street4Seen=[]
- sawShowdown=[]
- street1Aggr=[]
- street2Aggr=[]
- street3Aggr=[]
- street4Aggr=[]
- otherRaisedStreet1=[]
- otherRaisedStreet2=[]
- otherRaisedStreet3=[]
- otherRaisedStreet4=[]
- foldToOtherRaisedStreet1=[]
- foldToOtherRaisedStreet2=[]
- foldToOtherRaisedStreet3=[]
- foldToOtherRaisedStreet4=[]
- wonWhenSeenStreet1=[]
-
- wonAtSD=[]
- stealAttemptChance=[]
- stealAttempted=[]
- hudDataPositions=[]
-
- firstPfRaiseByNo=-1
- firstPfRaiserId=-1
- firstPfRaiserNo=-1
- firstPfCallByNo=-1
- firstPfCallerId=-1
- for i in range(len(actionTypeByNo[0])):
- if actionTypeByNo[0][i][1]=="bet":
- firstPfRaiseByNo=i
- firstPfRaiserId=actionTypeByNo[0][i][0]
- for j in range(len(player_ids)):
- if player_ids[j]==firstPfRaiserId:
- firstPfRaiserNo=j
- break
- break
- for i in range(len(actionTypeByNo[0])):
- if actionTypeByNo[0][i][1]=="call":
- firstPfCallByNo=i
- firstPfCallerId=actionTypeByNo[0][i][0]
- break
-
- cutoffId=-1
- buttonId=-1
- sbId=-1
- bbId=-1
- if base=="hold":
- for player in range(len(positions)):
- if positions==1:
- cutoffId=player_ids[player]
- if positions==0:
- buttonId=player_ids[player]
- if positions=='S':
- sbId=player_ids[player]
- if positions=='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 range (len(player_ids)):
- #set default values
- myStreet0VPI=False
- myStreet0Aggr=False
- myStreet0_3B4BChance=False
- myStreet0_3B4BDone=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
-
- #calculate VPIP and PFR
- street=0
- heroPfRaiseCount=0
- for count in range (len(action_types[street][player])):#finally individual actions
- currentAction=action_types[street][player][count]
- if currentAction=="bet":
- myStreet0Aggr=True
- if (currentAction=="bet" or currentAction=="call"):
- myStreet0VPI=True
-
- #PF3B4BChance and PF3B4B
- pfFold=-1
- pfRaise=-1
- if firstPfRaiseByNo!=-1:
- for i in range(len(actionTypeByNo[0])):
- if actionTypeByNo[0][i][0]==player_ids[player]:
- if actionTypeByNo[0][i][1]=="bet" and pfRaise==-1 and i>firstPfRaiseByNo:
- pfRaise=i
- if actionTypeByNo[0][i][1]=="fold" and pfFold==-1:
- pfFold=i
- if pfFold==-1 or pfFold>firstPfRaiseByNo:
- myStreet0_3B4BChance=True
- if pfRaise>firstPfRaiseByNo:
- myStreet0_3B4BDone=True
-
- #steal calculations
- if base=="hold":
- if len(player_ids)>=5: #no point otherwise
- if positions[player]==1:
- if firstPfRaiserId==player_ids[player]:
- myStealAttemptChance=True
- myStealAttempted=True
- elif firstPfRaiserId==buttonId or firstPfRaiserId==sbId or firstPfRaiserId==bbId or firstPfRaiserId==-1:
- myStealAttemptChance=True
- if positions[player]==0:
- if firstPfRaiserId==player_ids[player]:
- myStealAttemptChance=True
- myStealAttempted=True
- elif firstPfRaiserId==sbId or firstPfRaiserId==bbId or firstPfRaiserId==-1:
- myStealAttemptChance=True
- if positions[player]=='S':
- if firstPfRaiserId==player_ids[player]:
- myStealAttemptChance=True
- myStealAttempted=True
- elif firstPfRaiserId==bbId or firstPfRaiserId==-1:
- myStealAttemptChance=True
- if positions[player]=='B':
- pass
-
- if myStealAttempted:
- someoneStole=True
-
-
- #calculate saw* values
- isAllIn=False
- for i in range(len(allIns[0][player])):
- if allIns[0][player][i]:
- isAllIn=True
- if (len(action_types[1][player])>0 or isAllIn):
- myStreet1Seen=True
-
- for i in range(len(allIns[1][player])):
- if allIns[1][player][i]:
- isAllIn=True
- if (len(action_types[2][player])>0 or isAllIn):
- myStreet2Seen=True
-
- for i in range(len(allIns[2][player])):
- if allIns[2][player][i]:
- isAllIn=True
- if (len(action_types[3][player])>0 or isAllIn):
- myStreet3Seen=True
-
- #print "base:", base
- if base=="hold":
- mySawShowdown=True
- for count in range (len(action_types[3][player])):
- if action_types[3][player][count]=="fold":
- mySawShowdown=False
- else:
- #print "in else"
- for i in range(len(allIns[3][player])):
- if allIns[3][player][i]:
- isAllIn=True
- if (len(action_types[4][player])>0 or isAllIn):
- #print "in if"
- myStreet4Seen=True
-
- mySawShowdown=True
- for count in range (len(action_types[4][player])):
- if action_types[4][player][count]=="fold":
- mySawShowdown=False
-
-
- #flop stuff
- street=1
- if myStreet1Seen:
- for count in range(len(action_types[street][player])):
- if action_types[street][player][count]=="bet":
- myStreet1Aggr=True
-
- for otherPlayer in range (len(player_ids)):
- if player==otherPlayer:
- pass
- else:
- for countOther in range (len(action_types[street][otherPlayer])):
- if action_types[street][otherPlayer][countOther]=="bet":
- myOtherRaisedStreet1=True
- for countOtherFold in range (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:
- for count in range(len(action_types[street][player])):
- if action_types[street][player][count]=="bet":
- myStreet2Aggr=True
-
- for otherPlayer in range (len(player_ids)):
- if player==otherPlayer:
- pass
- else:
- for countOther in range (len(action_types[street][otherPlayer])):
- if action_types[street][otherPlayer][countOther]=="bet":
- myOtherRaisedStreet2=True
- for countOtherFold in range (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:
- for count in range(len(action_types[street][player])):
- if action_types[street][player][count]=="bet":
- myStreet3Aggr=True
-
- for otherPlayer in range (len(player_ids)):
- if player==otherPlayer:
- pass
- else:
- for countOther in range (len(action_types[street][otherPlayer])):
- if action_types[street][otherPlayer][countOther]=="bet":
- myOtherRaisedStreet3=True
- for countOtherFold in range (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:
- for count in range(len(action_types[street][player])):
- if action_types[street][player][count]=="bet":
- myStreet4Aggr=True
-
- for otherPlayer in range (len(player_ids)):
- if player==otherPlayer:
- pass
- else:
- for countOther in range (len(action_types[street][otherPlayer])):
- if action_types[street][otherPlayer][countOther]=="bet":
- myOtherRaisedStreet4=True
- for countOtherFold in range (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_3B4BChance.append(myStreet0_3B4BChance)
- street0_3B4BDone.append(myStreet0_3B4BDone)
- 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
-
- #add each array to the to-be-returned dictionary
- result={'street0VPI':street0VPI}
- result['street0Aggr']=street0Aggr
- result['street0_3B4BChance']=street0_3B4BChance
- result['street0_3B4BDone']=street0_3B4BDone
- 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
-
- #now the various steal values
- foldBbToStealChance=[]
- foldedBbToSteal=[]
- foldSbToStealChance=[]
- foldedSbToSteal=[]
- for player in range (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 range (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 range (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 range (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 range (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 range (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 range (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=[]
- for player in range (len(player_ids)):
- myTotalProfit=0
-
- myStreet1CheckCallRaiseChance=False
- myStreet1CheckCallRaiseDone=False
- myStreet2CheckCallRaiseChance=False
- myStreet2CheckCallRaiseDone=False
- myStreet3CheckCallRaiseChance=False
- myStreet3CheckCallRaiseDone=False
- myStreet4CheckCallRaiseChance=False
- myStreet4CheckCallRaiseDone=False
-
- totalProfit.append(myTotalProfit)
-
- 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
-
- 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
-
-def generateFoldToCB(street, playerIDs, didStreetCB, streetCBDone, foldToStreetCBChance, foldToStreetCBDone, actionTypeByNo):
- """fills the passed foldToStreetCB* arrays appropriately depending on the given street"""
- #print "beginning of generateFoldToCB, street:", street, "len(actionTypeByNo):", len(actionTypeByNo)
- #print "len(actionTypeByNo[street]):",len(actionTypeByNo[street])
- firstCBReaction=0
- for action in range(len(actionTypeByNo[street])):
- if actionTypeByNo[street][action][1]=="bet":
- for player in didStreetCB:
- if player==actionTypeByNo[street][action][0] and firstCBReaction==0:
- firstCBReaction=action+1
- break
-
- for action in actionTypeByNo[street][firstCBReaction:]:
- for player in range(len(playerIDs)):
- if playerIDs[player]==action[0]:
- foldToStreetCBChance[player]=True
- if action[1]=="fold":
- foldToStreetCBDone[player]=True
-#end def generateFoldToCB
-
-def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
-# if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
-
- for player in range (len(playerIds)):
- if base=="hold":
- cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player]))
- else:
- cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s", (gametypeId, playerIds[player], len(playerIds)))
- row=cursor.fetchone()
- #print "gametypeId:", gametypeId, "playerIds[player]",playerIds[player], "len(playerIds):",len(playerIds), "row:",row
-
- try: len(row)
- except TypeError:
- row=[]
-
- if (len(row)==0):
- #print "new huddata row"
- doInsert=True
- row=[]
- row.append(0)#blank for id
- row.append(gametypeId)
- row.append(playerIds[player])
- row.append(len(playerIds))#seats
- for i in range(len(hudImportData)+2):
- row.append(0)
-
- else:
- doInsert=False
- newrow=[]
- for i in range(len(row)):
- newrow.append(row[i])
- row=newrow
-
- if base=="hold":
- row[4]=hudImportData['position'][player]
- else:
- row[4]=0
- row[5]=1 #tourneysGametypeId
- row[6]+=1 #HDs
- if hudImportData['street0VPI'][player]: row[7]+=1
- if hudImportData['street0Aggr'][player]: row[8]+=1
- if hudImportData['street0_3B4BChance'][player]: row[9]+=1
- if hudImportData['street0_3B4BDone'][player]: row[10]+=1
- if hudImportData['street1Seen'][player]: row[11]+=1
- if hudImportData['street2Seen'][player]: row[12]+=1
- if hudImportData['street3Seen'][player]: row[13]+=1
- if hudImportData['street4Seen'][player]: row[14]+=1
- if hudImportData['sawShowdown'][player]: row[15]+=1
- if hudImportData['street1Aggr'][player]: row[16]+=1
- if hudImportData['street2Aggr'][player]: row[17]+=1
- if hudImportData['street3Aggr'][player]: row[18]+=1
- if hudImportData['street4Aggr'][player]: row[19]+=1
- if hudImportData['otherRaisedStreet1'][player]: row[20]+=1
- if hudImportData['otherRaisedStreet2'][player]: row[21]+=1
- if hudImportData['otherRaisedStreet3'][player]: row[22]+=1
- if hudImportData['otherRaisedStreet4'][player]: row[23]+=1
- if hudImportData['foldToOtherRaisedStreet1'][player]: row[24]+=1
- if hudImportData['foldToOtherRaisedStreet2'][player]: row[25]+=1
- if hudImportData['foldToOtherRaisedStreet3'][player]: row[26]+=1
- if hudImportData['foldToOtherRaisedStreet4'][player]: row[27]+=1
- if hudImportData['wonWhenSeenStreet1'][player]!=0.0: row[28]+=hudImportData['wonWhenSeenStreet1'][player]
- if hudImportData['wonAtSD'][player]!=0.0: row[29]+=hudImportData['wonAtSD'][player]
- if hudImportData['stealAttemptChance'][player]: row[30]+=1
- if hudImportData['stealAttempted'][player]: row[31]+=1
- if hudImportData['foldBbToStealChance'][player]: row[32]+=1
- if hudImportData['foldedBbToSteal'][player]: row[33]+=1
- if hudImportData['foldSbToStealChance'][player]: row[34]+=1
- if hudImportData['foldedSbToSteal'][player]: row[35]+=1
-
- if hudImportData['street1CBChance'][player]: row[36]+=1
- if hudImportData['street1CBDone'][player]: row[37]+=1
- if hudImportData['street2CBChance'][player]: row[38]+=1
- if hudImportData['street2CBDone'][player]: row[39]+=1
- if hudImportData['street3CBChance'][player]: row[40]+=1
- if hudImportData['street3CBDone'][player]: row[41]+=1
- if hudImportData['street4CBChance'][player]: row[42]+=1
- if hudImportData['street4CBDone'][player]: row[43]+=1
-
- if hudImportData['foldToStreet1CBChance'][player]: row[44]+=1
- if hudImportData['foldToStreet1CBDone'][player]: row[45]+=1
- if hudImportData['foldToStreet2CBChance'][player]: row[46]+=1
- if hudImportData['foldToStreet2CBDone'][player]: row[47]+=1
- if hudImportData['foldToStreet3CBChance'][player]: row[48]+=1
- if hudImportData['foldToStreet3CBDone'][player]: row[49]+=1
- if hudImportData['foldToStreet4CBChance'][player]: row[50]+=1
- if hudImportData['foldToStreet4CBDone'][player]: row[51]+=1
-
- row[52]+=hudImportData['totalProfit'][player]
-
- if hudImportData['street1CheckCallRaiseChance'][player]: row[53]+=1
- if hudImportData['street1CheckCallRaiseDone'][player]: row[54]+=1
- if hudImportData['street2CheckCallRaiseChance'][player]: row[55]+=1
- if hudImportData['street2CheckCallRaiseDone'][player]: row[56]+=1
- if hudImportData['street3CheckCallRaiseChance'][player]: row[57]+=1
- if hudImportData['street3CheckCallRaiseDone'][player]: row[58]+=1
- if hudImportData['street4CheckCallRaiseChance'][player]: row[59]+=1
- if hudImportData['street4CheckCallRaiseDone'][player]: row[60]+=1
-
- if doInsert:
- #print "playerid before insert:",row[2]
- cursor.execute("""INSERT INTO HudCache
- (gametypeId, playerId, activeSeats, position, tourneyTypeId,
- HDs, street0VPI, street0Aggr, street0_3B4BChance, street0_3B4BDone,
- street1Seen, street2Seen, street3Seen, street4Seen, sawShowdown,
- street1Aggr, street2Aggr, street3Aggr, street4Aggr, otherRaisedStreet1,
- otherRaisedStreet2, otherRaisedStreet3, otherRaisedStreet4, foldToOtherRaisedStreet1, foldToOtherRaisedStreet2,
- foldToOtherRaisedStreet3, foldToOtherRaisedStreet4, wonWhenSeenStreet1, wonAtSD, stealAttemptChance,
- stealAttempted, foldBbToStealChance, foldedBbToSteal, foldSbToStealChance, foldedSbToSteal,
- street1CBChance, street1CBDone, street2CBChance, street2CBDone, street3CBChance,
- street3CBDone, street4CBChance, street4CBDone, foldToStreet1CBChance, foldToStreet1CBDone,
- foldToStreet2CBChance, foldToStreet2CBDone, foldToStreet3CBChance, foldToStreet3CBDone, foldToStreet4CBChance,
- foldToStreet4CBDone, totalProfit, street1CheckCallRaiseChance, street1CheckCallRaiseDone, street2CheckCallRaiseChance,
- street2CheckCallRaiseDone, street3CheckCallRaiseChance, street3CheckCallRaiseDone, street4CheckCallRaiseChance, street4CheckCallRaiseDone)
- 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, %s,
- %s, %s, %s, %s, %s)""", (row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19], row[20], row[21], row[22], row[23], row[24], row[25], row[26], row[27], row[28], row[29], row[30], row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40], row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50], row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60]))
- else:
- #print "storing updated hud data line"
- cursor.execute("""UPDATE HudCache
- SET HDs=%s, street0VPI=%s, street0Aggr=%s, street0_3B4BChance=%s, street0_3B4BDone=%s,
- street1Seen=%s, street2Seen=%s, street3Seen=%s, street4Seen=%s, sawShowdown=%s,
- street1Aggr=%s, street2Aggr=%s, street3Aggr=%s, street4Aggr=%s, otherRaisedStreet1=%s,
- otherRaisedStreet2=%s, otherRaisedStreet3=%s, otherRaisedStreet4=%s, foldToOtherRaisedStreet1=%s, foldToOtherRaisedStreet2=%s,
- foldToOtherRaisedStreet3=%s, foldToOtherRaisedStreet4=%s, wonWhenSeenStreet1=%s, wonAtSD=%s, stealAttemptChance=%s,
- stealAttempted=%s, foldBbToStealChance=%s, foldedBbToSteal=%s, foldSbToStealChance=%s, foldedSbToSteal=%s,
- street1CBChance=%s, street1CBDone=%s, street2CBChance=%s, street2CBDone=%s, street3CBChance=%s,
- street3CBDone=%s, street4CBChance=%s, street4CBDone=%s, foldToStreet1CBChance=%s, foldToStreet1CBDone=%s,
- foldToStreet2CBChance=%s, foldToStreet2CBDone=%s, foldToStreet3CBChance=%s, foldToStreet3CBDone=%s, foldToStreet4CBChance=%s,
- foldToStreet4CBDone=%s, totalProfit=%s, street1CheckCallRaiseChance=%s, street1CheckCallRaiseDone=%s, street2CheckCallRaiseChance=%s,
- street2CheckCallRaiseDone=%s, street3CheckCallRaiseChance=%s, street3CheckCallRaiseDone=%s, street4CheckCallRaiseChance=%s, street4CheckCallRaiseDone=%s
- WHERE gametypeId=%s AND playerId=%s AND activeSeats=%s AND position=%s AND tourneyTypeId=%s""", (row[6], row[7], row[8], row[9], row[10],
- row[11], row[12], row[13], row[14], row[15],
- row[16], row[17], row[18], row[19], row[20],
- row[21], row[22], row[23], row[24], row[25],
- row[26], row[27], row[28], row[29], row[30],
- row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40],
- row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50],
- row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60],
- row[1], row[2], row[3], str(row[4]), row[5]))
-# else:
-# print "todo: implement storeHudCache for stud base"
-#end def storeHudCache
-
-def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime):
- cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
- tmp=cursor.fetchone()
- #print "tried SELECTing tourneys.id, result:",tmp
-
- try:
- len(tmp)
- except TypeError:#means we have to create new one
- cursor.execute("""INSERT INTO Tourneys
- (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)
- VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime))
- cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
- tmp=cursor.fetchone()
- #print "created new tourneys.id:",tmp
- return tmp[0]
-#end def store_tourneys
-
-def store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings):
- result=[]
- #print "in store_tourneys_players. tourney_id:",tourney_id
- #print "player_ids:",player_ids
- #print "payin_amounts:",payin_amounts
- #print "ranks:",ranks
- #print "winnings:",winnings
- for i in range (len(player_ids)):
- cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", (tourney_id, player_ids[i]))
- tmp=cursor.fetchone()
- #print "tried SELECTing tourneys_players.id:",tmp
-
- try:
- len(tmp)
- except TypeError:
- cursor.execute("""INSERT INTO TourneysPlayers
- (tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""",
- (tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i]))
-
- cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s",
- (tourney_id, player_ids[i]))
- tmp=cursor.fetchone()
- #print "created new tourneys_players.id:",tmp
- result.append(tmp[0])
- return result
-#end def store_tourneys_players
+#!/usr/bin/python
+
+#Copyright 2008 Steffen Jobbagy-Felso
+#This program is free software: you can redistribute it and/or modify
+#it under the terms of the GNU Affero General Public License as published by
+#the Free Software Foundation, version 3 of the License.
+#
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+#
+#You should have received a copy of the GNU Affero General Public License
+#along with this program. If not, see .
+#In the "official" distribution you can find the license in
+#agpl-3.0.txt in the docs folder of the package.
+
+#This file contains simple functions for fpdb
+
+import datetime
+import re
+
+PS=1
+FTP=2
+
+class DuplicateError(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+class FpdbError(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+#returns an array of the total money paid. intending to add rebuys/addons here
+def calcPayin(count, buyin, fee):
+ result=[]
+ for i in range(count):
+ result.append (buyin+fee)
+ return result
+#end def calcPayin
+
+def checkPositions(positions):
+ """verifies that these positions are valid"""
+ for i in range (len(positions)):
+ pos=positions[i]
+ try:#todo: use type recognition instead of error
+ if (len(pos)!=1):
+ raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+pos) #dont need to str() here
+ except TypeError:#->not string->is int->fine
+ pass
+
+ ### RHH modified to allow for "position 9" here (pos==9 is when you're a dead hand before the BB
+ if (pos!="B" and pos!="S" and pos!=0 and pos!=1 and pos!=2 and pos!=3 and pos!=4 and pos!=5 and pos!=6 and pos!=7 and pos!=9):
+ raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+str(pos))
+#end def fpdb_simple.checkPositions
+
+#classifies each line for further processing in later code. Manipulates the passed arrays.
+def classifyLines(hand, category, lineTypes, lineStreets):
+ currentStreet="predeal"
+ done=False #set this to true once we reach the last relevant line (the summary, except rake, is all repeats)
+ for i in range (len(hand)):
+ if (done):
+ if (hand[i].find("[")==-1 or hand[i].find("mucked [")==-1):
+ lineTypes.append("ignore")
+ else: #it's storing a mucked card
+ lineTypes.append("cards")
+ elif (hand[i].startswith("Dealt to")):
+ lineTypes.append("cards")
+ elif (i==0):
+ lineTypes.append("header")
+ elif (hand[i].startswith("Seat ") and ((hand[i].find("in chips")!=-1) or (hand[i].find("($")!=-1))):
+ lineTypes.append("name")
+ elif (isActionLine(hand[i])):
+ lineTypes.append("action")
+ if (hand[i].find(" posts ")!=-1 or hand[i].find(" posts the ")!=-1):#need to set this here so the "action" of posting blinds is registered properly
+ currentStreet="preflop"
+ elif (isWinLine(hand[i])):
+ lineTypes.append("win")
+ elif (hand[i].startswith("Total pot ") and hand[i].find("Rake")!=-1):
+ lineTypes.append("rake")
+ done=True
+ elif (hand[i]=="*** SHOW DOWN ***" or hand[i]=="*** SUMMARY ***"):
+ lineTypes.append("ignore")
+ #print "in classifyLine, showdown or summary"
+ elif (hand[i].find(" antes ")!=-1 or hand[i].find(" posts the ante ")!=-1):
+ lineTypes.append("ante")
+ elif (hand[i].startswith("*** FLOP *** [")):
+ lineTypes.append("cards")
+ currentStreet="flop"
+ elif (hand[i].startswith("*** TURN *** [")):
+ lineTypes.append("cards")
+ currentStreet="turn"
+ elif (hand[i].startswith("*** RIVER *** [")):
+ lineTypes.append("cards")
+ currentStreet="river"
+ elif (hand[i].startswith("*** 3")):
+ lineTypes.append("ignore")
+ currentStreet=0
+ elif (hand[i].startswith("*** 4")):
+ lineTypes.append("ignore")
+ currentStreet=1
+ elif (hand[i].startswith("*** 5")):
+ lineTypes.append("ignore")
+ currentStreet=2
+ elif (hand[i].startswith("*** 6")):
+ lineTypes.append("ignore")
+ currentStreet=3
+ elif (hand[i].startswith("*** 7") or hand[i]=="*** RIVER ***"):
+ lineTypes.append("ignore")
+ currentStreet=4
+ elif (hand[i].find(" shows [")!=-1):
+ lineTypes.append("cards")
+ elif (hand[i].startswith("Table '")):
+ lineTypes.append("table")
+ else:
+ raise FpdbError("unrecognised linetype in:"+hand[i])
+ lineStreets.append(currentStreet)
+#end def classifyLines
+
+def convert3B4B(site, category, limit_type, actionTypes, actionAmounts):
+ """calculates the actual bet amounts in the given amount array and changes it accordingly."""
+ for i in range (len(actionTypes)):
+ for j in range (len(actionTypes[i])):
+ bets=[]
+ for k in range (len(actionTypes[i][j])):
+ if (actionTypes[i][j][k]=="bet"):
+ bets.append((i,j,k))
+ if (len(bets)==2):
+ #print "len(bets) 2 or higher, need to correct it. bets:",bets,"len:",len(bets)
+ amount2=actionAmounts[bets[1][0]][bets[1][1]][bets[1][2]]
+ amount1=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]
+ actionAmounts[bets[1][0]][bets[1][1]][bets[1][2]]=amount2-amount1
+ elif (len(bets)>2):
+ fail=True
+ #todo: run correction for below
+ if (site=="ps" and category=="holdem" and limit_type=="nl" and len(bets)==3):
+ fail=False
+ if (site=="ftp" and category=="omahahi" and limit_type=="pl" and len(bets)==3):
+ fail=False
+
+ if fail:
+ print "len(bets)>2 in convert3B4B, i didnt think this is possible. i:",i,"j:",j,"k:",k
+ print "actionTypes:",actionTypes
+ raise FpdbError ("too many bets in convert3B4B")
+ #print "actionAmounts postConvert",actionAmounts
+#end def convert3B4B(actionTypes, actionAmounts)
+
+#Corrects the bet amount if the player had to pay blinds
+def convertBlindBet(actionTypes, actionAmounts):
+ i=0#setting street to pre-flop
+ for j in range (len(actionTypes[i])):#playerloop
+ blinds=[]
+ bets=[]
+ for k in range (len(actionTypes[i][j])):
+ if (actionTypes[i][j][k]=="blind"):
+ blinds.append((i,j,k))
+
+ if (len(blinds)>0 and actionTypes[i][j][k]=="bet"):
+ bets.append((i,j,k))
+ if (len(bets)==1):
+ blind_amount=actionAmounts[blinds[0][0]][blinds[0][1]][blinds[0][2]]
+ bet_amount=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]
+ actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]=bet_amount-blind_amount
+#end def convertBlindBet
+
+#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
+#todo: make this use convertCardValuesBoard
+def convertCardValues(arr):
+ for i in range (len(arr)):
+ for j in range (len(arr[i])):
+ if (arr[i][j]=="A"):
+ arr[i][j]=14
+ elif (arr[i][j]=="K"):
+ arr[i][j]=13
+ elif (arr[i][j]=="Q"):
+ arr[i][j]=12
+ elif (arr[i][j]=="J"):
+ arr[i][j]=11
+ elif (arr[i][j]=="T"):
+ arr[i][j]=10
+ else:
+ arr[i][j]=int(arr[i][j])
+#end def convertCardValues
+
+#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
+def convertCardValuesBoard(arr):
+ for i in range (len(arr)):
+ if (arr[i]=="A"):
+ arr[i]=14
+ elif (arr[i]=="K"):
+ arr[i]=13
+ elif (arr[i]=="Q"):
+ arr[i]=12
+ elif (arr[i]=="J"):
+ arr[i]=11
+ elif (arr[i]=="T"):
+ arr[i]=10
+ else:
+ arr[i]=int(arr[i])
+#end def convertCardValuesBoard
+
+#this creates the 2D/3D arrays. manipulates the passed arrays instead of returning.
+def createArrays(category, seats, card_values, card_suits, antes, winnings, rakes, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
+ for i in range(seats):#create second dimension arrays
+ tmp=[]
+ card_values.append(tmp)
+ tmp=[]
+ card_suits.append(tmp)
+ antes.append(0)
+ winnings.append(0)
+ rakes.append(0)
+
+ if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
+ streetCount=4
+ else:
+ streetCount=5
+
+ for i in range(streetCount): #build the first dimension array, for streets
+ tmp=[]
+ action_types.append(tmp)
+ tmp=[]
+ allIns.append(tmp)
+ tmp=[]
+ action_amounts.append(tmp)
+ tmp=[]
+ actionNos.append(tmp)
+ tmp=[]
+ actionTypeByNo.append(tmp)
+ for j in range (seats): #second dimension arrays: players
+ tmp=[]
+ action_types[i].append(tmp)
+ tmp=[]
+ allIns[i].append(tmp)
+ tmp=[]
+ action_amounts[i].append(tmp)
+ tmp=[]
+ actionNos[i].append(tmp)
+ if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
+ pass
+ elif (category=="razz" or category=="studhi" or category=="studhilo"):#need to fill card arrays.
+ for i in range(seats):
+ for j in range (7):
+ card_values[i].append(0)
+ card_suits[i].append("x")
+ else:
+ raise FpdbError("invalid category")
+#end def createArrays
+
+def fill_board_cards(board_values, board_suits):
+#fill up the two board card arrays
+ while (len(board_values)<5):
+ board_values.append(0)
+ board_suits.append("x")
+#end def fill_board_cards
+
+def fillCardArrays(player_count, base, category, card_values, card_suits):
+ """fills up the two card arrays"""
+ if (category=="holdem"):
+ cardCount=2
+ elif (category=="omahahi" or category=="omahahilo"):
+ cardCount=4
+ elif base=="stud":
+ cardCount=7
+ else:
+ raise fpdb_simple.FpdbError ("invalid category:", category)
+
+ for i in range (player_count):
+ while (len(card_values[i])=1):
+ raise DuplicateError ("dupl")
+#end isAlreadyInDB
+
+def isRebuyOrAddon(topline):
+ """isRebuyOrAddon not implemented yet"""
+ return False
+#end def isRebuyOrAddon
+
+#returns whether the passed topline indicates a tournament or not
+def isTourney(topline):
+ if (topline.find("Tournament")!=-1):
+ return True
+ else:
+ return False
+#end def isTourney
+
+#returns boolean whether the passed line is a win line
+def isWinLine(line):
+ if (line.find("wins the pot")!=-1):
+ return True
+ elif (line.find("ties for the high pot")!=-1):
+ return True
+ elif (line.find("ties for the high main pot")!=-1):
+ return True
+ elif (line.find("ties for the high side pot")!=-1):
+ return True
+ elif (line.find("ties for the low pot")!=-1):
+ return True
+ elif (line.find("ties for the low main pot")!=-1):
+ return True
+ elif (line.find("ties for the low side pot")!=-1):
+ return True
+ elif (line.find("ties for the main pot")!=-1): #for ftp tied main pot of split pot
+ return True
+ elif (line.find("ties for the pot")!=-1): #for ftp tie
+ return True
+ elif (line.find("ties for the side pot")!=-1): #for ftp tied split pots
+ return True
+ elif (line.find("wins side pot #")!=-1): #for ftp multi split pots
+ return True
+ elif (line.find("wins the low main pot")!=-1):
+ return True
+ elif (line.find("wins the low pot")!=-1):
+ return True
+ elif (line.find("wins the low side pot")!=-1):
+ return True
+ elif (line.find("wins the high main pot")!=-1):
+ return True
+ elif (line.find("wins the high pot")!=-1):
+ return True
+ elif (line.find("wins the high side pot")!=-1):
+ return True
+ elif (line.find("wins the main pot")!=-1):
+ return True
+ elif (line.find("wins the side pot")!=-1): #for ftp split pots
+ return True
+ elif (line.find("collected")!=-1):
+ return True
+ else:
+ return False #not raising error here, any unknown line wouldve been detected in isActionLine already
+#end def isWinLine
+
+#returns the amount of cash/chips put into the put in the given action line
+def parseActionAmount(line, atype, site, isTourney):
+ #if (line.endswith(" and is all-in")):
+ # line=line[:-14]
+ #elif (line.endswith(", and is all in")):
+ # line=line[:-15]
+
+ if line.endswith(", and is capped"):#ideally we should recognise this as an all-in if category is capXl
+ line=line[:-15]
+ if line.endswith(" and is capped"):
+ line=line[:-14]
+
+
+ if (atype=="fold"):
+ amount=0
+ elif (atype=="check"):
+ amount=0
+ elif (atype=="unbet" and site=="ftp"):
+ pos1=line.find("$")+1
+ pos2=line.find(" returned to")
+ amount=float2int(line[pos1:pos2])
+ elif (atype=="unbet" and site=="ps"):
+ #print "ps unbet, line:",line
+ pos1=line.find("$")+1
+ if pos1==0:
+ pos1=line.find("(")+1
+ pos2=line.find(")")
+ amount=float2int(line[pos1:pos2])
+ elif (atype=="bet" and site=="ps" and line.find(": raises $")!=-1 and line.find("to $")!=-1):
+ pos=line.find("to $")+4
+ amount=float2int(line[pos:])
+ else:
+ if not isTourney:
+ pos=line.rfind("$")+1
+ #print "parseActionAmount, line:", line, "line[pos:]:", line[pos:]
+ amount=float2int(line[pos:])
+ else:
+ #print "line:"+line+"EOL"
+ pos=line.rfind(" ")+1
+ #print "pos:",pos
+ #print "pos of 20:", line.find("20")
+ amount=int(line[pos:])
+
+ if atype=="unbet":
+ amount*=-1
+ return amount
+#end def parseActionAmount
+
+#doesnt return anything, simply changes the passed arrays action_types and
+# action_amounts. For stud this expects numeric streets (3-7), for
+# holdem/omaha it expects predeal, preflop, flop, turn or river
+def parseActionLine(site, base, isTourney, line, street, playerIDs, names, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
+ if (street=="predeal" or street=="preflop"):
+ street=0
+ elif (street=="flop"):
+ street=1
+ elif (street=="turn"):
+ street=2
+ elif (street=="river"):
+ street=3
+
+ nextActionNo=0
+ for player in range(len(actionNos[street])):
+ for count in range(len(actionNos[street][player])):
+ if actionNos[street][player][count]>=nextActionNo:
+ nextActionNo=actionNos[street][player][count]+1
+
+ line, allIn=goesAllInOnThisLine(line)
+ atype=parseActionType(line)
+ playerno=recognisePlayerNo(line, names, atype)
+ amount=parseActionAmount(line, atype, site, isTourney)
+
+ action_types[street][playerno].append(atype)
+ allIns[street][playerno].append(allIn)
+ action_amounts[street][playerno].append(amount)
+ actionNos[street][playerno].append(nextActionNo)
+ tmp=(playerIDs[playerno], atype)
+ actionTypeByNo[street].append(tmp)
+#end def parseActionLine
+
+def goesAllInOnThisLine(line):
+ """returns whether the player went all-in on this line and removes the all-in text from the line."""
+ isAllIn=False
+ if (line.endswith(" and is all-in")):
+ line=line[:-14]
+ isAllIn=True
+ elif (line.endswith(", and is all in")):
+ line=line[:-15]
+ isAllIn=True
+ return (line, isAllIn)
+#end def goesAllInOnThisLine
+
+#returns the action type code (see table design) of the given action line
+def parseActionType(line):
+ if (line.startswith("Uncalled bet")):
+ return "unbet"
+ elif (line.endswith("folds")):
+ return "fold"
+ elif (line.endswith("checks")):
+ return "check"
+ elif (line.find("calls")!=-1):
+ return "call"
+ elif (line.find("brings in for")!=-1):
+ return "blind"
+ elif (line.find("completes it to")!=-1):
+ return "bet"
+ #todo: what if someone completes instead of bringing in?
+ elif (line.find(" posts $")!=-1):
+ return "blind"
+ elif (line.find(" posts a dead ")!=-1):
+ return "blind"
+ elif (line.find(": posts small blind ")!=-1):
+ return "blind"
+ elif (line.find(" posts the small blind of $")!=-1):
+ return "blind"
+ elif (line.find(": posts big blind ")!=-1):
+ return "blind"
+ elif (line.find(" posts the big blind of $")!=-1):
+ return "blind"
+ elif (line.find(": posts small & big blinds $")!=-1):
+ return "blind"
+ #todo: seperately record voluntary blind payments made to join table out of turn
+ elif (line.find("bets")!=-1):
+ return "bet"
+ elif (line.find("raises")!=-1):
+ return "bet"
+ else:
+ raise FpdbError ("failed to recognise actiontype in parseActionLine in: "+line)
+#end def parseActionType
+
+#parses the ante out of the given line and checks which player paid it, updates antes accordingly.
+def parseAnteLine(line, site, isTourney, names, antes):
+ for i in range(len(names)):
+ if (line.startswith(names[i].encode("latin-1"))): #found the ante'er
+ pos=line.rfind("$")+1
+ if not isTourney:
+ antes[i]+=float2int(line[pos:])
+ else:
+ if line.find("all-in")==-1:
+ pos=line.rfind(" ")+1
+ antes[i]+=int(line[pos:])
+ else:
+ pos1=line.rfind("ante")+5
+ pos2=line.find(" ",pos1)
+ antes[i]+=int(line[pos1:pos2])
+ #print "parseAnteLine line: ", line, "antes[i]", antes[i], "antes", antes
+#end def parseAntes
+
+#returns the buyin of a tourney in cents
+def parseBuyin(topline):
+ pos1=topline.find("$")+1
+ pos2=topline.find("+")
+ return float2int(topline[pos1:pos2])
+#end def parseBuyin
+
+#parses a card line and changes the passed arrays accordingly
+#todo: reorganise this messy method
+def parseCardLine(site, category, street, line, names, cardValues, cardSuits, boardValues, boardSuits):
+ if (line.startswith("Dealt to ") or line.find(" shows [")!=-1 or line.find("mucked [")!=-1):
+ playerNo=recognisePlayerNo(line, names, "card") #anything but unbet will be ok for that string
+
+ pos=line.rfind("[")+1
+ if (category=="holdem"):
+ for i in (pos, pos+3):
+ cardValues[playerNo].append(line[i:i+1])
+ cardSuits[playerNo].append(line[i+1:i+2])
+ if (len(cardValues[playerNo])!=2):
+ if cardValues[playerNo][0]==cardValues[playerNo][2] and cardSuits[playerNo][1]==cardSuits[playerNo][3]: #two tests will do
+ cardValues[playerNo]=cardValues[playerNo][0:2]
+ cardSuits[playerNo]=cardSuits[playerNo][0:2]
+ else:
+ print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
+ raise FpdbError("read too many/too few holecards in parseCardLine")
+ elif (category=="omahahi" or category=="omahahilo"):
+ for i in (pos, pos+3, pos+6, pos+9):
+ cardValues[playerNo].append(line[i:i+1])
+ cardSuits[playerNo].append(line[i+1:i+2])
+ if (len(cardValues[playerNo])!=4):
+ if cardValues[playerNo][0]==cardValues[playerNo][4] and cardSuits[playerNo][3]==cardSuits[playerNo][7]: #two tests will do
+ cardValues[playerNo]=cardValues[playerNo][0:4]
+ cardSuits[playerNo]=cardSuits[playerNo][0:4]
+ else:
+ print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
+ raise FpdbError("read too many/too few holecards in parseCardLine")
+ elif (category=="razz" or category=="studhi" or category=="studhilo"):
+ if (line.find("shows")==-1):
+ #print "parseCardLine(in stud if), street:", street
+ if line[pos+2]=="]": #-> not (hero and 3rd street)
+ cardValues[playerNo][street+2]=line[pos:pos+1]
+ cardSuits[playerNo][street+2]=line[pos+1:pos+2]
+ else:
+ #print "hero card1:", line[pos:pos+2], "hero card2:", line[pos+3:pos+5], "hero card3:", line[pos+6:pos+8],
+ cardValues[playerNo][street]=line[pos:pos+1]
+ cardSuits[playerNo][street]=line[pos+1:pos+2]
+ cardValues[playerNo][street+1]=line[pos+3:pos+4]
+ cardSuits[playerNo][street+1]=line[pos+4:pos+5]
+ cardValues[playerNo][street+2]=line[pos+6:pos+7]
+ cardSuits[playerNo][street+2]=line[pos+7:pos+8]
+ else:
+ #print "parseCardLine(in stud else), street:", street
+ cardValues[playerNo][0]=line[pos:pos+1]
+ cardSuits[playerNo][0]=line[pos+1:pos+2]
+ pos+=3
+ cardValues[playerNo][1]=line[pos:pos+1]
+ cardSuits[playerNo][1]=line[pos+1:pos+2]
+ if street==4:
+ pos=pos=line.rfind("]")-2
+ cardValues[playerNo][6]=line[pos:pos+1]
+ cardSuits[playerNo][6]=line[pos+1:pos+2]
+ #print "cardValues:", cardValues
+ #print "cardSuits:", cardSuits
+ else:
+ print "line:",line,"street:",street
+ raise FpdbError("invalid category")
+ #print "end of parseCardLine/playercards, cardValues:",cardValues
+ elif (line.startswith("*** FLOP ***")):
+ pos=line.find("[")+1
+ for i in (pos, pos+3, pos+6):
+ boardValues.append(line[i:i+1])
+ boardSuits.append(line[i+1:i+2])
+ #print boardValues
+ elif (line.startswith("*** TURN ***") or line.startswith("*** RIVER ***")):
+ pos=line.find("[")+1
+ pos=line.find("[", pos+1)+1
+ boardValues.append(line[pos:pos+1])
+ boardSuits.append(line[pos+1:pos+2])
+ #print boardValues
+ else:
+ raise FpdbError ("unrecognised line:"+line)
+#end def parseCardLine
+
+def parseCashesAndSeatNos(lines, site):
+ """parses the startCashes and seatNos of each player out of the given lines and returns them as a dictionary of two arrays"""
+ cashes = []
+ seatNos = []
+ for i in range (len(lines)):
+ pos2=lines[i].find(":")
+ seatNos.append(int(lines[i][5:pos2]))
+
+ pos1=lines[i].rfind("($")+2
+ if pos1==1: #for tourneys - it's 1 instead of -1 due to adding 2 above
+ pos1=lines[i].rfind("(")+1
+ if (site=="ftp"):
+ pos2=lines[i].rfind(")")
+ elif (site=="ps"):
+ pos2=lines[i].find(" in chips")
+ cashes.append(float2int(lines[i][pos1:pos2]))
+ return {'startCashes':cashes, 'seatNos':seatNos}
+#end def parseCashesAndSeatNos
+
+#returns the buyin of a tourney in cents
+def parseFee(topline):
+ pos1=topline.find("$")+1
+ pos1=topline.find("$",pos1)+1
+ pos2=topline.find(" ", pos1)
+ return float2int(topline[pos1:pos2])
+#end def parsefee
+
+#returns a datetime object with the starttime indicated in the given topline
+def parseHandStartTime(topline, site):
+ #convert x:13:35 to 0x:13:35
+ counter=0
+ while (True):
+ pos=topline.find(" "+str(counter)+":")
+ if (pos!=-1):
+ topline=topline[0:pos+1]+"0"+topline[pos+1:]
+ counter+=1
+ if counter==10: break
+
+ isUTC=False
+ if site=="ftp":
+ pos = topline.find(" ", len(topline)-26)+1
+ tmp = topline[pos:]
+ #print "year:", tmp[14:18], "month", tmp[19:21], "day", tmp[22:24], "hour", tmp[0:2], "minute", tmp[3:5], "second", tmp[6:8]
+ result = datetime.datetime(int(tmp[14:18]), int(tmp[19:21]), int(tmp[22:24]), int(tmp[0:2]), int(tmp[3:5]), int(tmp[6:8]))
+ elif site=="ps":
+ if topline.find("UTC")!=-1:
+ pos1 = topline.find("-")+2
+ pos2 = topline.find("UTC")
+ tmp=topline[pos1:pos2]
+ isUTC=True
+ else:
+ tmp=topline[-30:]
+ #print "parsehandStartTime, tmp:", tmp
+ pos = tmp.find("-")+2
+ tmp = tmp[pos:]
+ #Need to match either
+ # 2008/09/07 06:23:14 ET or
+ # 2008/08/17 - 01:14:43 (ET)
+ m = re.match('(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P
[0-9]{2}):(?P[0-9]{2}):(?P[0-9]{2})',tmp)
+ #print "year:", int(m.group('YEAR')), "month", int(m.group('MON')), "day", int(m.group('DAY')), "hour", int(m.group('HR')), "minute", int(m.group('MIN')), "second", int(m.group('SEC'))
+ result = datetime.datetime(int(m.group('YEAR')), int(m.group('MON')), int(m.group('DAY')), int(m.group('HR')), int(m.group('MIN')), int(m.group('SEC')))
+ else:
+ raise FpdbError("invalid site in parseHandStartTime")
+
+ if (site=="ftp" or site=="ps") and not isUTC: #these use US ET
+ result+=datetime.timedelta(hours=5)
+
+ return result
+#end def parseHandStartTime
+
+#parses the names out of the given lines and returns them as an array
+def parseNames(lines):
+ result = []
+ for i in range (len(lines)):
+ pos1=lines[i].find(":")+2
+ pos2=lines[i].rfind("(")-1
+ tmp=lines[i][pos1:pos2]
+ #print "parseNames, tmp original:",tmp
+ tmp=unicode(tmp,"latin-1")
+ #print "parseNames, tmp after unicode latin-1 conversion:",tmp
+ result.append(tmp)
+ return result
+#end def parseNames
+
+#returns an array with the positions of the respective players
+def parsePositions (hand, names):
+ #prep array
+ positions=[]
+ for i in range(len(names)):
+ positions.append(-1)
+
+ #find blinds
+ sb,bb=-1,-1
+ for i in range (len(hand)):
+ if (sb==-1 and hand[i].find("small blind")!=-1 and hand[i].find("dead small blind")==-1):
+ sb=hand[i]
+ #print "sb:",sb
+ if (bb==-1 and hand[i].find("big blind")!=-1 and hand[i].find("dead big blind")==-1):
+ bb=hand[i]
+ #print "bb:",bb
+
+ #identify blinds
+ #print "parsePositions before recognising sb/bb. names:",names
+ sbExists=True
+ if (sb!=-1):
+ sb=recognisePlayerNo(sb, names, "bet")
+ else:
+ sbExists=False
+ if (bb!=-1):
+ bb=recognisePlayerNo(bb, names, "bet")
+
+ #write blinds into array
+ if (sbExists):
+ positions[sb]="S"
+ positions[bb]="B"
+
+ #fill up rest of array
+ if (sbExists):
+ arraypos=sb-1
+ else:
+ arraypos=bb-1
+ distFromBtn=0
+ while (arraypos>=0 and arraypos != bb):
+ #print "parsePositions first while, arraypos:",arraypos,"positions:",positions
+ positions[arraypos]=distFromBtn
+ arraypos-=1
+ distFromBtn+=1
+
+ ### RHH - Changed to set the null seats before BB to "9"
+ i=bb-1
+ while positions[i] < 0:
+ positions[i]=9
+ i-=1
+
+ arraypos=len(names)-1
+ if (bb!=0 or (bb==0 and sbExists==False)):
+ while (arraypos>bb):
+ positions[arraypos]=distFromBtn
+ arraypos-=1
+ distFromBtn+=1
+
+ for i in range (len(names)):
+ if positions[i]==-1:
+ print "parsePositions names:",names
+ print "result:",positions
+ raise FpdbError ("failed to read positions")
+ return positions
+#end def parsePositions
+
+#simply parses the rake amount and returns it as an int
+def parseRake(line):
+ pos=line.find("Rake")+6
+ rake=float2int(line[pos:])
+ return rake
+#end def parseRake
+
+def parseSiteHandNo(topline):
+ """returns the hand no assigned by the poker site"""
+ pos1=topline.find("#")+1
+ pos2=topline.find(":")
+ return topline[pos1:pos2]
+#end def parseSiteHandNo
+
+def parseTableLine(site, base, line):
+ """returns a dictionary with maxSeats and tableName"""
+ if site=="ps":
+ pos1=line.find('\'')+1
+ pos2=line.find('\'', pos1)
+ #print "table:",line[pos1:pos2]
+ pos3=pos2+2
+ pos4=line.find("-max")
+ #print "seats:",line[pos3:pos4]
+ return {'maxSeats':int(line[pos3:pos4]), 'tableName':line[pos1:pos2]}
+ elif site=="ftp":
+ pos1=line.find("Table ")+6
+ pos2=line.find("-")-1
+ if base=="hold":
+ maxSeats=9
+ elif base=="stud":
+ maxSeats=8
+
+ if line.find("6 max")!=-1:
+ maxSeats=6
+ elif line.find("4 max")!=-1:
+ maxSeats=4
+ elif line.find("heads up")!=-1:
+ maxSeats=2
+
+ return {'maxSeats':maxSeats, 'tableName':line[pos1:pos2]}
+ else:
+ raise FpdbError("invalid site ID")
+#end def parseTableLine
+
+#returns the hand no assigned by the poker site
+def parseTourneyNo(topline):
+ pos1=topline.find("Tournament #")+12
+ pos2=topline.find(",", pos1)
+ #print "parseTourneyNo pos1:",pos1," pos2:",pos2, " result:",topline[pos1:pos2]
+ return topline[pos1:pos2]
+#end def parseTourneyNo
+
+#parses a win/collect line. manipulates the passed array winnings, no explicit return
+def parseWinLine(line, site, names, winnings, isTourney):
+ #print "parseWinLine: line:",line
+ for i in range(len(names)):
+ if (line.startswith(names[i].encode("latin-1"))): #found a winner
+ if isTourney:
+ pos1=line.rfind("collected ")+10
+ if (site=="ftp"):
+ pos2=line.find(")", pos1)
+ elif (site=="ps"):
+ pos2=line.find(" ", pos1)
+ winnings[i]+=int(line[pos1:pos2])
+ else:
+ pos1=line.rfind("$")+1
+ if (site=="ftp"):
+ pos2=line.find(")", pos1)
+ elif (site=="ps"):
+ pos2=line.find(" ", pos1)
+ winnings[i]+=float2int(line[pos1:pos2])
+#end def parseWinLine
+
+#returns the category (as per database) string for the given line
+def recogniseCategory(line):
+ if (line.find("Razz")!=-1):
+ return "razz"
+ elif (line.find("Hold'em")!=-1):
+ return "holdem"
+ elif (line.find("Omaha")!=-1 and line.find("Hi/Lo")==-1 and line.find("H/L")==-1):
+ return "omahahi"
+ elif (line.find("Omaha")!=-1 and (line.find("Hi/Lo")!=-1 or line.find("H/L")!=-1)):
+ return "omahahilo"
+ elif (line.find("Stud")!=-1 and line.find("Hi/Lo")==-1 and line.find("H/L")==-1):
+ return "studhi"
+ elif (line.find("Stud")!=-1 and (line.find("Hi/Lo")!=-1 or line.find("H/L")!=-1)):
+ return "studhilo"
+ else:
+ raise FpdbError("failed to recognise category, line:"+line)
+#end def recogniseCategory
+
+#returns the int for the gametype_id for the given line
+def recogniseGametypeID(db, cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy
+ #if (topline.find("HORSE")!=-1):
+ # raise FpdbError("recogniseGametypeID: HORSE is not yet supported.")
+
+ #note: the below variable names small_bet and big_bet are misleading, in NL/PL they mean small/big blind
+ if isTourney:
+ type="tour"
+ pos1=topline.find("(")+1
+ if (topline[pos1]=="H" or topline[pos1]=="O" or topline[pos1]=="R" or topline[pos1]=="S" or topline[pos1+2]=="C"):
+ pos1=topline.find("(", pos1)+1
+ pos2=topline.find("/", pos1)
+ small_bet=int(topline[pos1:pos2])
+ else:
+ type="ring"
+ pos1=topline.find("$")+1
+ pos2=topline.find("/$")
+ small_bet=float2int(topline[pos1:pos2])
+
+ pos1=pos2+2
+ if isTourney:
+ pos1-=1
+ if (site_id==1): #ftp
+ pos2=topline.find(" ", pos1)
+ elif (site_id==2): #ps
+ pos2=topline.find(")")
+
+ if pos2<=pos1:
+ pos2=topline.find(")", pos1)
+
+ if isTourney:
+ big_bet=int(topline[pos1:pos2])
+ else:
+ big_bet=float2int(topline[pos1:pos2])
+
+ if (topline.find("No Limit")!=-1):
+ limit_type="nl"
+ if (topline.find("Cap No")!=-1):
+ limit_type="cn"
+ elif (topline.find("Pot Limit")!=-1):
+ limit_type="pl"
+ if (topline.find("Cap Pot")!=-1):
+ limit_type="cp"
+ else:
+ limit_type="fl"
+
+ #print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type
+ if (limit_type=="fl"):
+ cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
+ else:
+ cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
+ result=cursor.fetchone()
+ #print "recgt1 result=",result
+ #ret=result[0]
+ #print "recgt1 ret=",ret
+ #print "tried SELECTing gametypes.id, result:",result
+
+ try:
+ len(result)
+ except TypeError:
+ if category=="holdem" or category=="omahahi" or category=="omahahilo":
+ base="hold"
+ else:
+ base="stud"
+
+ if category=="holdem" or category=="omahahi" or category=="studhi":
+ hiLo='h'
+ elif category=="razz":
+ hiLo='l'
+ else:
+ hiLo='s'
+
+ if (limit_type=="fl"):
+ big_blind=small_bet
+ if base=="hold":
+ if smallBlindLine==topline:
+ raise FpdbError("invalid small blind line")
+ elif isTourney:
+ pos=smallBlindLine.rfind(" ")+1
+ small_blind=int(smallBlindLine[pos:])
+ else:
+ pos=smallBlindLine.rfind("$")+1
+ small_blind=float2int(smallBlindLine[pos:])
+ else:
+ small_blind=0
+ cursor.execute("""INSERT INTO Gametypes
+ (siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_blind, big_blind, small_bet, big_bet))
+ #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
+ else:
+ cursor.execute("""INSERT INTO Gametypes
+ (siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind
+ #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
+
+ result=(db.insert_id(),)
+ #print "recgt2 result=",result
+ #print "created new gametypes.id:",result
+
+ #print "recgt3: result=", result
+ return result[0]
+#end def recogniseGametypeID
+
+def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon):
+ cursor.execute ("SELECT id FROM TourneyTypes WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s", (siteId, buyin, fee, knockout, rebuyOrAddon))
+ result=cursor.fetchone()
+ #print "tried SELECTing gametypes.id, result:",result
+
+ try:
+ len(result)
+ except TypeError:#this means we need to create a new entry
+ cursor.execute("""INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon) VALUES (%s, %s, %s, %s, %s)""", (siteId, buyin, fee, knockout, rebuyOrAddon))
+ cursor.execute("SELECT id FROM TourneyTypes WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s", (siteId, buyin, fee, knockout, rebuyOrAddon))
+ result=cursor.fetchone()
+ return result[0]
+#end def recogniseTourneyTypeId
+
+#returns the SQL ids of the names given in an array
+def recognisePlayerIDs(cursor, names, site_id):
+ result = []
+ for i in range (len(names)):
+ cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
+ tmp=cursor.fetchall()
+ if (len(tmp)==0): #new player
+ cursor.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (names[i], site_id))
+ #print "Number of players rows inserted: %d" % cursor.rowcount
+ cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
+ tmp=cursor.fetchall()
+ #print "recognisePlayerIDs, names[i]:",names[i],"tmp:",tmp
+ result.append(tmp[0][0])
+ return result
+#end def recognisePlayerIDs
+
+#recognises the name in the given line and returns its array position in the given array
+def recognisePlayerNo(line, names, atype):
+ #print "recogniseplayerno, names:",names
+ for i in range (len(names)):
+ if (atype=="unbet"):
+ if (line.endswith(names[i].encode("latin-1"))):
+ return (i)
+ elif (line.startswith("Dealt to ")):
+ #print "recognisePlayerNo, card precut, line:",line
+ tmp=line[9:]
+ #print "recognisePlayerNo, card postcut, tmp:",tmp
+ if (tmp.startswith(names[i].encode("latin-1"))):
+ return (i)
+ elif (line.startswith("Seat ")):
+ if (line.startswith("Seat 10")):
+ tmp=line[9:]
+ else:
+ tmp=line[8:]
+
+ if (tmp.startswith(names[i].encode("latin-1"))):
+ return (i)
+ else:
+ if (line.startswith(names[i].encode("latin-1"))):
+ return (i)
+ #if we're here we mustve failed
+ raise FpdbError ("failed to recognise player in: "+line+" atype:"+atype)
+#end def recognisePlayerNo
+
+#returns the site abbreviation for the given site
+def recogniseSite(line):
+ if (line.startswith("Full Tilt Poker")):
+ return "ftp"
+ elif (line.startswith("PokerStars")):
+ return "ps"
+ else:
+ raise FpdbError("failed to recognise site, line:"+line)
+#end def recogniseSite
+
+#returns the ID of the given site
+def recogniseSiteID(cursor, site):
+ if (site=="ftp"):
+ return 1
+ #cursor.execute("SELECT id FROM Sites WHERE name = ('Full Tilt Poker')")
+ elif (site=="ps"):
+ return 2
+ #cursor.execute("SELECT id FROM Sites WHERE name = ('PokerStars')")
+ else:
+ raise FpdbError("invalid site in recogniseSiteID: "+site)
+ return cursor.fetchall()[0][0]
+#end def recogniseSiteID
+
+#removes trailing \n from the given array
+def removeTrailingEOL(arr):
+ for i in range(len(arr)):
+ if (arr[i].endswith("\n")):
+ #print "arr[i] before removetrailingEOL:", arr[i]
+ arr[i]=arr[i][:-1]
+ #print "arr[i] after removetrailingEOL:", arr[i]
+ return arr
+#end def removeTrailingEOL
+
+#splits the rake according to the proportion of pot won. manipulates the second passed array.
+def splitRake(winnings, rakes, totalRake):
+ winnercnt=0
+ totalWin=0
+ for i in range(len(winnings)):
+ if winnings[i]!=0:
+ winnercnt+=1
+ totalWin+=winnings[i]
+ firstWinner=i
+ if winnercnt==1:
+ rakes[firstWinner]=totalRake
+ else:
+ totalWin=float(totalWin)
+ for i in range(len(winnings)):
+ if winnings[i]!=0:
+ winPortion=winnings[i]/totalWin
+ rakes[i]=totalRake*winPortion
+#end def splitRake
+
+def storeActions(cursor, handsPlayersIds, actionTypes, allIns, actionAmounts, actionNos):
+#stores into table hands_actions
+ #print "start of storeActions, actionNos:",actionNos
+ #print " action_amounts:",action_amounts
+ for i in range (len(actionTypes)): #iterate through streets
+ for j in range (len(actionTypes[i])): #iterate through names
+ for k in range (len(actionTypes[i][j])): #iterate through individual actions of that player on that street
+ cursor.execute ("INSERT INTO HandsActions (handPlayerId, street, actionNo, action, allIn, amount) VALUES (%s, %s, %s, %s, %s, %s)"
+ , (handsPlayersIds[j], i, actionNos[i][j][k], actionTypes[i][j][k], allIns[i][j][k], actionAmounts[i][j][k]))
+#end def storeActions
+
+def store_board_cards(cursor, hands_id, board_values, board_suits):
+#stores into table board_cards
+ cursor.execute ("""INSERT INTO BoardCards (handId, card1Value, card1Suit,
+ card2Value, card2Suit, card3Value, card3Suit, card4Value, card4Suit,
+ card5Value, card5Suit) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+ (hands_id, board_values[0], board_suits[0], board_values[1], board_suits[1],
+ board_values[2], board_suits[2], board_values[3], board_suits[3],
+ board_values[4], board_suits[4]))
+#end def store_board_cards
+
+def storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats):
+#stores into table hands
+ cursor.execute ("INSERT INTO Hands (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats) VALUES (%s, %s, %s, %s, %s, %s, %s)", (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.datetime.today(), maxSeats))
+ #todo: find a better way of doing this...
+ #cursor.execute("SELECT id FROM Hands WHERE siteHandNo=%s AND gametypeId=%s", (site_hand_no, gametype_id))
+ #return cursor.fetchall()[0][0]
+ return db.insert_id() # mysql only
+#end def storeHands
+
+def store_hands_players_holdem_omaha(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos):
+ result=[]
+ if (category=="holdem"):
+ for i in range (len(player_ids)):
+ cursor.execute ("""
+ INSERT INTO HandsPlayers
+ (handId, playerId, startCash, position,
+ card1Value, card1Suit, card2Value, card2Suit, winnings, rake, seatNo)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], positions[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ winnings[i], rakes[i], seatNos[i]))
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( db.insert_id() ) # mysql only
+ elif (category=="omahahi" or category=="omahahilo"):
+ for i in range (len(player_ids)):
+ cursor.execute ("""INSERT INTO HandsPlayers
+ (handId, playerId, startCash, position,
+ card1Value, card1Suit, card2Value, card2Suit,
+ card3Value, card3Suit, card4Value, card4Suit, winnings, rake, seatNo)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], positions[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
+ winnings[i], rakes[i], seatNos[i]))
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( db.insert_id() ) # mysql only
+ else:
+ raise FpdbError("invalid category")
+ return result
+#end def store_hands_players_holdem_omaha
+
+def store_hands_players_stud(db, cursor, hands_id, player_ids, start_cashes, antes,
+ card_values, card_suits, winnings, rakes, seatNos):
+#stores hands_players rows for stud/razz games. returns an array of the resulting IDs
+ result=[]
+ #print "before inserts in store_hands_players_stud, antes:", antes
+ for i in range (len(player_ids)):
+ cursor.execute ("""INSERT INTO HandsPlayers
+ (handId, playerId, startCash, ante,
+ card1Value, card1Suit, card2Value, card2Suit,
+ card3Value, card3Suit, card4Value, card4Suit,
+ card5Value, card5Suit, card6Value, card6Suit,
+ card7Value, card7Suit, winnings, rake, seatNo)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
+ %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], antes[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
+ card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
+ card_values[i][6], card_suits[i][6], winnings[i], rakes[i], seatNos[i]))
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( db.insert_id() ) # mysql only
+ return result
+#end def store_hands_players_stud
+
+def store_hands_players_holdem_omaha_tourney(db, cursor, category, hands_id, player_ids,
+ start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
+#stores hands_players for tourney holdem/omaha hands
+ result=[]
+ for i in range (len(player_ids)):
+ if len(card_values[0])==2:
+ cursor.execute ("""INSERT INTO HandsPlayers
+ (handId, playerId, startCash, position,
+ card1Value, card1Suit, card2Value, card2Suit,
+ winnings, rake, tourneysPlayersId, seatNo)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], positions[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
+ elif len(card_values[0])==4:
+ cursor.execute ("""INSERT INTO HandsPlayers
+ (handId, playerId, startCash, position,
+ card1Value, card1Suit, card2Value, card2Suit,
+ card3Value, card3Suit, card4Value, card4Suit,
+ winnings, rake, tourneysPlayersId, seatNo)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], positions[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
+ winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
+ else:
+ raise FpdbError ("invalid card_values length:"+str(len(card_values[0])))
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( db.insert_id() ) # mysql only
+
+ return result
+#end def store_hands_players_holdem_omaha_tourney
+
+def store_hands_players_stud_tourney(db, cursor, hands_id, player_ids, start_cashes,
+ antes, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
+#stores hands_players for tourney stud/razz hands
+ result=[]
+ for i in range (len(player_ids)):
+ cursor.execute ("""INSERT INTO HandsPlayers
+ (handId, playerId, startCash, ante,
+ card1Value, card1Suit, card2Value, card2Suit,
+ card3Value, card3Suit, card4Value, card4Suit,
+ card5Value, card5Suit, card6Value, card6Suit,
+ card7Value, card7Suit, winnings, rake, tourneysPlayersId, seatNo)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
+ %s, %s, %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], antes[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
+ card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
+ card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( db.insert_id() ) # mysql only
+ return result
+#end def store_hands_players_stud_tourney
+
+def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo
+ ,winnings, totalWinnings, positions, actionTypes, actionAmounts):
+ """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_3B4BChance=[]
+ street0_3B4BDone=[]
+ street1Seen=[]
+ street2Seen=[]
+ street3Seen=[]
+ street4Seen=[]
+ sawShowdown=[]
+ street1Aggr=[]
+ street2Aggr=[]
+ street3Aggr=[]
+ street4Aggr=[]
+ otherRaisedStreet1=[]
+ otherRaisedStreet2=[]
+ otherRaisedStreet3=[]
+ otherRaisedStreet4=[]
+ foldToOtherRaisedStreet1=[]
+ foldToOtherRaisedStreet2=[]
+ foldToOtherRaisedStreet3=[]
+ foldToOtherRaisedStreet4=[]
+ wonWhenSeenStreet1=[]
+
+ wonAtSD=[]
+ stealAttemptChance=[]
+ stealAttempted=[]
+ hudDataPositions=[]
+
+ firstPfRaiseByNo=-1
+ firstPfRaiserId=-1
+ firstPfRaiserNo=-1
+ firstPfCallByNo=-1
+ firstPfCallerId=-1
+ for i in range(len(actionTypeByNo[0])):
+ if actionTypeByNo[0][i][1]=="bet":
+ firstPfRaiseByNo=i
+ firstPfRaiserId=actionTypeByNo[0][i][0]
+ for j in range(len(player_ids)):
+ if player_ids[j]==firstPfRaiserId:
+ firstPfRaiserNo=j
+ break
+ break
+ for i in range(len(actionTypeByNo[0])):
+ if actionTypeByNo[0][i][1]=="call":
+ firstPfCallByNo=i
+ firstPfCallerId=actionTypeByNo[0][i][0]
+ break
+
+ cutoffId=-1
+ buttonId=-1
+ sbId=-1
+ bbId=-1
+ if base=="hold":
+ for player in range(len(positions)):
+ if positions==1:
+ cutoffId=player_ids[player]
+ if positions==0:
+ buttonId=player_ids[player]
+ if positions=='S':
+ sbId=player_ids[player]
+ if positions=='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 range (len(player_ids)):
+ #set default values
+ myStreet0VPI=False
+ myStreet0Aggr=False
+ myStreet0_3B4BChance=False
+ myStreet0_3B4BDone=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
+
+ #calculate VPIP and PFR
+ street=0
+ heroPfRaiseCount=0
+ for count in range (len(action_types[street][player])):#finally individual actions
+ currentAction=action_types[street][player][count]
+ if currentAction=="bet":
+ myStreet0Aggr=True
+ if (currentAction=="bet" or currentAction=="call"):
+ myStreet0VPI=True
+
+ #PF3B4BChance and PF3B4B
+ pfFold=-1
+ pfRaise=-1
+ if firstPfRaiseByNo!=-1:
+ for i in range(len(actionTypeByNo[0])):
+ if actionTypeByNo[0][i][0]==player_ids[player]:
+ if actionTypeByNo[0][i][1]=="bet" and pfRaise==-1 and i>firstPfRaiseByNo:
+ pfRaise=i
+ if actionTypeByNo[0][i][1]=="fold" and pfFold==-1:
+ pfFold=i
+ if pfFold==-1 or pfFold>firstPfRaiseByNo:
+ myStreet0_3B4BChance=True
+ if pfRaise>firstPfRaiseByNo:
+ myStreet0_3B4BDone=True
+
+ #steal calculations
+ if base=="hold":
+ if len(player_ids)>=5: #no point otherwise
+ if positions[player]==1:
+ if firstPfRaiserId==player_ids[player]:
+ myStealAttemptChance=True
+ myStealAttempted=True
+ elif firstPfRaiserId==buttonId or firstPfRaiserId==sbId or firstPfRaiserId==bbId or firstPfRaiserId==-1:
+ myStealAttemptChance=True
+ if positions[player]==0:
+ if firstPfRaiserId==player_ids[player]:
+ myStealAttemptChance=True
+ myStealAttempted=True
+ elif firstPfRaiserId==sbId or firstPfRaiserId==bbId or firstPfRaiserId==-1:
+ myStealAttemptChance=True
+ if positions[player]=='S':
+ if firstPfRaiserId==player_ids[player]:
+ myStealAttemptChance=True
+ myStealAttempted=True
+ elif firstPfRaiserId==bbId or firstPfRaiserId==-1:
+ myStealAttemptChance=True
+ if positions[player]=='B':
+ pass
+
+ if myStealAttempted:
+ someoneStole=True
+
+
+ #calculate saw* values
+ isAllIn=False
+ for i in range(len(allIns[0][player])):
+ if allIns[0][player][i]:
+ isAllIn=True
+ if (len(action_types[1][player])>0 or isAllIn):
+ myStreet1Seen=True
+
+ for i in range(len(allIns[1][player])):
+ if allIns[1][player][i]:
+ isAllIn=True
+ if (len(action_types[2][player])>0 or isAllIn):
+ myStreet2Seen=True
+
+ for i in range(len(allIns[2][player])):
+ if allIns[2][player][i]:
+ isAllIn=True
+ if (len(action_types[3][player])>0 or isAllIn):
+ myStreet3Seen=True
+
+ #print "base:", base
+ if base=="hold":
+ mySawShowdown=True
+ for count in range (len(action_types[3][player])):
+ if action_types[3][player][count]=="fold":
+ mySawShowdown=False
+ else:
+ #print "in else"
+ for i in range(len(allIns[3][player])):
+ if allIns[3][player][i]:
+ isAllIn=True
+ if (len(action_types[4][player])>0 or isAllIn):
+ #print "in if"
+ myStreet4Seen=True
+
+ mySawShowdown=True
+ for count in range (len(action_types[4][player])):
+ if action_types[4][player][count]=="fold":
+ mySawShowdown=False
+
+
+ #flop stuff
+ street=1
+ if myStreet1Seen:
+ for count in range(len(action_types[street][player])):
+ if action_types[street][player][count]=="bet":
+ myStreet1Aggr=True
+
+ for otherPlayer in range (len(player_ids)):
+ if player==otherPlayer:
+ pass
+ else:
+ for countOther in range (len(action_types[street][otherPlayer])):
+ if action_types[street][otherPlayer][countOther]=="bet":
+ myOtherRaisedStreet1=True
+ for countOtherFold in range (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:
+ for count in range(len(action_types[street][player])):
+ if action_types[street][player][count]=="bet":
+ myStreet2Aggr=True
+
+ for otherPlayer in range (len(player_ids)):
+ if player==otherPlayer:
+ pass
+ else:
+ for countOther in range (len(action_types[street][otherPlayer])):
+ if action_types[street][otherPlayer][countOther]=="bet":
+ myOtherRaisedStreet2=True
+ for countOtherFold in range (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:
+ for count in range(len(action_types[street][player])):
+ if action_types[street][player][count]=="bet":
+ myStreet3Aggr=True
+
+ for otherPlayer in range (len(player_ids)):
+ if player==otherPlayer:
+ pass
+ else:
+ for countOther in range (len(action_types[street][otherPlayer])):
+ if action_types[street][otherPlayer][countOther]=="bet":
+ myOtherRaisedStreet3=True
+ for countOtherFold in range (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:
+ for count in range(len(action_types[street][player])):
+ if action_types[street][player][count]=="bet":
+ myStreet4Aggr=True
+
+ for otherPlayer in range (len(player_ids)):
+ if player==otherPlayer:
+ pass
+ else:
+ for countOther in range (len(action_types[street][otherPlayer])):
+ if action_types[street][otherPlayer][countOther]=="bet":
+ myOtherRaisedStreet4=True
+ for countOtherFold in range (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_3B4BChance.append(myStreet0_3B4BChance)
+ street0_3B4BDone.append(myStreet0_3B4BDone)
+ 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<=7:
+ 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
+
+ #add each array to the to-be-returned dictionary
+ result={'street0VPI':street0VPI}
+ result['street0Aggr']=street0Aggr
+ result['street0_3B4BChance']=street0_3B4BChance
+ result['street0_3B4BDone']=street0_3B4BDone
+ 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
+
+ #now the various steal values
+ foldBbToStealChance=[]
+ foldedBbToSteal=[]
+ foldSbToStealChance=[]
+ foldedSbToSteal=[]
+ for player in range (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 range (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 range (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 range (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 range (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 range (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 range (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 range (len(player_ids)):
+ #print "pl=", pl
+ myTotalProfit=winnings[pl] # still need to deduct costs
+ for i in range (len(actionTypes)): #iterate through streets
+ #for j in range (len(actionTypes[i])): #iterate through names (using pl loop above)
+ for k in range (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
+
+def generateFoldToCB(street, playerIDs, didStreetCB, streetCBDone, foldToStreetCBChance, foldToStreetCBDone, actionTypeByNo):
+ """fills the passed foldToStreetCB* arrays appropriately depending on the given street"""
+ #print "beginning of generateFoldToCB, street:", street, "len(actionTypeByNo):", len(actionTypeByNo)
+ #print "len(actionTypeByNo[street]):",len(actionTypeByNo[street])
+ firstCBReaction=0
+ for action in range(len(actionTypeByNo[street])):
+ if actionTypeByNo[street][action][1]=="bet":
+ for player in didStreetCB:
+ if player==actionTypeByNo[street][action][0] and firstCBReaction==0:
+ firstCBReaction=action+1
+ break
+
+ for action in actionTypeByNo[street][firstCBReaction:]:
+ for player in range(len(playerIDs)):
+ if playerIDs[player]==action[0]:
+ foldToStreetCBChance[player]=True
+ if action[1]=="fold":
+ foldToStreetCBDone[player]=True
+#end def generateFoldToCB
+
+def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
+# if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
+
+ #print "storeHudCache, len(playerIds)=", len(playerIds), " len(vpip)=" \
+ #, len(hudImportData['street0VPI']), " len(totprof)=", len(hudImportData['totalProfit'])
+ for player in range (len(playerIds)):
+ if base=="hold":
+ cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player]))
+ else:
+ cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s", (gametypeId, playerIds[player], len(playerIds)))
+ row=cursor.fetchone()
+ #print "gametypeId:", gametypeId, "playerIds[player]",playerIds[player], "len(playerIds):",len(playerIds), "row:",row
+
+ try: len(row)
+ except TypeError:
+ row=[]
+
+ if (len(row)==0):
+ #print "new huddata row"
+ doInsert=True
+ row=[]
+ row.append(0)#blank for id
+ row.append(gametypeId)
+ row.append(playerIds[player])
+ row.append(len(playerIds))#seats
+ for i in range(len(hudImportData)+2):
+ row.append(0)
+
+ else:
+ doInsert=False
+ newrow=[]
+ for i in range(len(row)):
+ newrow.append(row[i])
+ row=newrow
+
+ if base=="hold":
+ row[4]=hudImportData['position'][player]
+ else:
+ row[4]=0
+ row[5]=1 #tourneysGametypeId
+ row[6]+=1 #HDs
+ if hudImportData['street0VPI'][player]: row[7]+=1
+ if hudImportData['street0Aggr'][player]: row[8]+=1
+ if hudImportData['street0_3B4BChance'][player]: row[9]+=1
+ if hudImportData['street0_3B4BDone'][player]: row[10]+=1
+ if hudImportData['street1Seen'][player]: row[11]+=1
+ if hudImportData['street2Seen'][player]: row[12]+=1
+ if hudImportData['street3Seen'][player]: row[13]+=1
+ if hudImportData['street4Seen'][player]: row[14]+=1
+ if hudImportData['sawShowdown'][player]: row[15]+=1
+ if hudImportData['street1Aggr'][player]: row[16]+=1
+ if hudImportData['street2Aggr'][player]: row[17]+=1
+ if hudImportData['street3Aggr'][player]: row[18]+=1
+ if hudImportData['street4Aggr'][player]: row[19]+=1
+ if hudImportData['otherRaisedStreet1'][player]: row[20]+=1
+ if hudImportData['otherRaisedStreet2'][player]: row[21]+=1
+ if hudImportData['otherRaisedStreet3'][player]: row[22]+=1
+ if hudImportData['otherRaisedStreet4'][player]: row[23]+=1
+ if hudImportData['foldToOtherRaisedStreet1'][player]: row[24]+=1
+ if hudImportData['foldToOtherRaisedStreet2'][player]: row[25]+=1
+ if hudImportData['foldToOtherRaisedStreet3'][player]: row[26]+=1
+ if hudImportData['foldToOtherRaisedStreet4'][player]: row[27]+=1
+ if hudImportData['wonWhenSeenStreet1'][player]!=0.0: row[28]+=hudImportData['wonWhenSeenStreet1'][player]
+ if hudImportData['wonAtSD'][player]!=0.0: row[29]+=hudImportData['wonAtSD'][player]
+ if hudImportData['stealAttemptChance'][player]: row[30]+=1
+ if hudImportData['stealAttempted'][player]: row[31]+=1
+ if hudImportData['foldBbToStealChance'][player]: row[32]+=1
+ if hudImportData['foldedBbToSteal'][player]: row[33]+=1
+ if hudImportData['foldSbToStealChance'][player]: row[34]+=1
+ if hudImportData['foldedSbToSteal'][player]: row[35]+=1
+
+ if hudImportData['street1CBChance'][player]: row[36]+=1
+ if hudImportData['street1CBDone'][player]: row[37]+=1
+ if hudImportData['street2CBChance'][player]: row[38]+=1
+ if hudImportData['street2CBDone'][player]: row[39]+=1
+ if hudImportData['street3CBChance'][player]: row[40]+=1
+ if hudImportData['street3CBDone'][player]: row[41]+=1
+ if hudImportData['street4CBChance'][player]: row[42]+=1
+ if hudImportData['street4CBDone'][player]: row[43]+=1
+
+ if hudImportData['foldToStreet1CBChance'][player]: row[44]+=1
+ if hudImportData['foldToStreet1CBDone'][player]: row[45]+=1
+ if hudImportData['foldToStreet2CBChance'][player]: row[46]+=1
+ if hudImportData['foldToStreet2CBDone'][player]: row[47]+=1
+ if hudImportData['foldToStreet3CBChance'][player]: row[48]+=1
+ if hudImportData['foldToStreet3CBDone'][player]: row[49]+=1
+ if hudImportData['foldToStreet4CBChance'][player]: row[50]+=1
+ if hudImportData['foldToStreet4CBDone'][player]: row[51]+=1
+
+ #print "player=", player
+ #print "len(totalProfit)=", len(hudImportData['totalProfit'])
+ if hudImportData['totalProfit'][player]:
+ row[52]+=hudImportData['totalProfit'][player]
+
+ if hudImportData['street1CheckCallRaiseChance'][player]: row[53]+=1
+ if hudImportData['street1CheckCallRaiseDone'][player]: row[54]+=1
+ if hudImportData['street2CheckCallRaiseChance'][player]: row[55]+=1
+ if hudImportData['street2CheckCallRaiseDone'][player]: row[56]+=1
+ if hudImportData['street3CheckCallRaiseChance'][player]: row[57]+=1
+ if hudImportData['street3CheckCallRaiseDone'][player]: row[58]+=1
+ if hudImportData['street4CheckCallRaiseChance'][player]: row[59]+=1
+ if hudImportData['street4CheckCallRaiseDone'][player]: row[60]+=1
+
+ if doInsert:
+ #print "playerid before insert:",row[2]
+ cursor.execute("""INSERT INTO HudCache
+ (gametypeId, playerId, activeSeats, position, tourneyTypeId,
+ HDs, street0VPI, street0Aggr, street0_3B4BChance, street0_3B4BDone,
+ street1Seen, street2Seen, street3Seen, street4Seen, sawShowdown,
+ street1Aggr, street2Aggr, street3Aggr, street4Aggr, otherRaisedStreet1,
+ otherRaisedStreet2, otherRaisedStreet3, otherRaisedStreet4, foldToOtherRaisedStreet1, foldToOtherRaisedStreet2,
+ foldToOtherRaisedStreet3, foldToOtherRaisedStreet4, wonWhenSeenStreet1, wonAtSD, stealAttemptChance,
+ stealAttempted, foldBbToStealChance, foldedBbToSteal, foldSbToStealChance, foldedSbToSteal,
+ street1CBChance, street1CBDone, street2CBChance, street2CBDone, street3CBChance,
+ street3CBDone, street4CBChance, street4CBDone, foldToStreet1CBChance, foldToStreet1CBDone,
+ foldToStreet2CBChance, foldToStreet2CBDone, foldToStreet3CBChance, foldToStreet3CBDone, foldToStreet4CBChance,
+ foldToStreet4CBDone, totalProfit, street1CheckCallRaiseChance, street1CheckCallRaiseDone, street2CheckCallRaiseChance,
+ street2CheckCallRaiseDone, street3CheckCallRaiseChance, street3CheckCallRaiseDone, street4CheckCallRaiseChance, street4CheckCallRaiseDone)
+ 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, %s,
+ %s, %s, %s, %s, %s)""", (row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19], row[20], row[21], row[22], row[23], row[24], row[25], row[26], row[27], row[28], row[29], row[30], row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40], row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50], row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60]))
+ else:
+ #print "storing updated hud data line"
+ cursor.execute("""UPDATE HudCache
+ SET HDs=%s, street0VPI=%s, street0Aggr=%s, street0_3B4BChance=%s, street0_3B4BDone=%s,
+ street1Seen=%s, street2Seen=%s, street3Seen=%s, street4Seen=%s, sawShowdown=%s,
+ street1Aggr=%s, street2Aggr=%s, street3Aggr=%s, street4Aggr=%s, otherRaisedStreet1=%s,
+ otherRaisedStreet2=%s, otherRaisedStreet3=%s, otherRaisedStreet4=%s, foldToOtherRaisedStreet1=%s, foldToOtherRaisedStreet2=%s,
+ foldToOtherRaisedStreet3=%s, foldToOtherRaisedStreet4=%s, wonWhenSeenStreet1=%s, wonAtSD=%s, stealAttemptChance=%s,
+ stealAttempted=%s, foldBbToStealChance=%s, foldedBbToSteal=%s, foldSbToStealChance=%s, foldedSbToSteal=%s,
+ street1CBChance=%s, street1CBDone=%s, street2CBChance=%s, street2CBDone=%s, street3CBChance=%s,
+ street3CBDone=%s, street4CBChance=%s, street4CBDone=%s, foldToStreet1CBChance=%s, foldToStreet1CBDone=%s,
+ foldToStreet2CBChance=%s, foldToStreet2CBDone=%s, foldToStreet3CBChance=%s, foldToStreet3CBDone=%s, foldToStreet4CBChance=%s,
+ foldToStreet4CBDone=%s, totalProfit=%s, street1CheckCallRaiseChance=%s, street1CheckCallRaiseDone=%s, street2CheckCallRaiseChance=%s,
+ street2CheckCallRaiseDone=%s, street3CheckCallRaiseChance=%s, street3CheckCallRaiseDone=%s, street4CheckCallRaiseChance=%s, street4CheckCallRaiseDone=%s
+ WHERE gametypeId=%s AND playerId=%s AND activeSeats=%s AND position=%s AND tourneyTypeId=%s""", (row[6], row[7], row[8], row[9], row[10],
+ row[11], row[12], row[13], row[14], row[15],
+ row[16], row[17], row[18], row[19], row[20],
+ row[21], row[22], row[23], row[24], row[25],
+ row[26], row[27], row[28], row[29], row[30],
+ row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40],
+ row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50],
+ row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60],
+ row[1], row[2], row[3], str(row[4]), row[5]))
+# else:
+# print "todo: implement storeHudCache for stud base"
+#end def storeHudCache
+
+def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime):
+ cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
+ tmp=cursor.fetchone()
+ #print "tried SELECTing tourneys.id, result:",tmp
+
+ try:
+ len(tmp)
+ except TypeError:#means we have to create new one
+ cursor.execute("""INSERT INTO Tourneys
+ (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)
+ VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime))
+ cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
+ tmp=cursor.fetchone()
+ #print "created new tourneys.id:",tmp
+ return tmp[0]
+#end def store_tourneys
+
+def store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings):
+ result=[]
+ #print "in store_tourneys_players. tourney_id:",tourney_id
+ #print "player_ids:",player_ids
+ #print "payin_amounts:",payin_amounts
+ #print "ranks:",ranks
+ #print "winnings:",winnings
+ for i in range (len(player_ids)):
+ cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", (tourney_id, player_ids[i]))
+ tmp=cursor.fetchone()
+ #print "tried SELECTing tourneys_players.id:",tmp
+
+ try:
+ len(tmp)
+ except TypeError:
+ cursor.execute("""INSERT INTO TourneysPlayers
+ (tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""",
+ (tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i]))
+
+ cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s",
+ (tourney_id, player_ids[i]))
+ tmp=cursor.fetchone()
+ #print "created new tourneys_players.id:",tmp
+ result.append(tmp[0])
+ return result
+#end def store_tourneys_players
From 30e61901d6604c8519a9f1e748e0c879a2452c0a Mon Sep 17 00:00:00 2001
From: sqlcoder
Date: Mon, 8 Dec 2008 01:38:06 +0000
Subject: [PATCH 24/32] use spaces not tabs and get first part of insert_id()
code working again
---
pyfpdb/fpdb_parse_logic.py | 274 ++++++++++++++++++-------------------
pyfpdb/fpdb_simple.py | 8 +-
2 files changed, 141 insertions(+), 141 deletions(-)
diff --git a/pyfpdb/fpdb_parse_logic.py b/pyfpdb/fpdb_parse_logic.py
index 8400af31..1d7d54a0 100644
--- a/pyfpdb/fpdb_parse_logic.py
+++ b/pyfpdb/fpdb_parse_logic.py
@@ -22,154 +22,154 @@ import fpdb_save_to_db
#parses a holdem hand
def mainParser(db, cursor, site, category, hand):
- if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
- base="hold"
- else:
- base="stud"
- #part 0: create the empty arrays
- lineTypes=[] #char, valid values: header, name, cards, action, win, rake, ignore
- lineStreets=[] #char, valid values: (predeal, preflop, flop, turn, river)
+ if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
+ base="hold"
+ else:
+ base="stud"
+ #part 0: create the empty arrays
+ lineTypes=[] #char, valid values: header, name, cards, action, win, rake, ignore
+ lineStreets=[] #char, valid values: (predeal, preflop, flop, turn, river)
- cardValues, cardSuits, boardValues, boardSuits, antes, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo, seatLines, winnings, rakes=[],[],[],[],[],[],[],[],[],[],[],[],[]
+ cardValues, cardSuits, boardValues, boardSuits, antes, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo, seatLines, winnings, rakes=[],[],[],[],[],[],[],[],[],[],[],[],[]
- #part 1: read hand no and check for duplicate
- siteHandNo=fpdb_simple.parseSiteHandNo(hand[0])
- handStartTime=fpdb_simple.parseHandStartTime(hand[0], site)
- siteID=fpdb_simple.recogniseSiteID(cursor, site)
- #print "parse logic, siteID:",siteID,"site:",site
-
- isTourney=fpdb_simple.isTourney(hand[0])
- smallBlindLine=0
- for i in range(len(hand)):
- if hand[i].find("posts small blind")!=-1 or hand[i].find("posts the small blind")!=-1:
- if hand[i][-2:] == "$0":
- continue
- smallBlindLine=i
- #print "found small blind line:",smallBlindLine
- break
- #print "small blind line:",smallBlindLine
- gametypeID=fpdb_simple.recogniseGametypeID(db, cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
- if isTourney:
- if site!="ps":
- raise fpdb_simple.FpdbError("tourneys are only supported on PS right now")
- siteTourneyNo=fpdb_simple.parseTourneyNo(hand[0])
- buyin=fpdb_simple.parseBuyin(hand[0])
- fee=fpdb_simple.parseFee(hand[0])
- entries=-1 #todo: parse this
- prizepool=-1 #todo: parse this
- knockout=0
- tourneyStartTime=handStartTime #todo: read tourney start time
- rebuyOrAddon=fpdb_simple.isRebuyOrAddon(hand[0])
+ #part 1: read hand no and check for duplicate
+ siteHandNo=fpdb_simple.parseSiteHandNo(hand[0])
+ handStartTime=fpdb_simple.parseHandStartTime(hand[0], site)
+ siteID=fpdb_simple.recogniseSiteID(cursor, site)
+ #print "parse logic, siteID:",siteID,"site:",site
+
+ isTourney=fpdb_simple.isTourney(hand[0])
+ smallBlindLine=0
+ for i in range(len(hand)):
+ if hand[i].find("posts small blind")!=-1 or hand[i].find("posts the small blind")!=-1:
+ if hand[i][-2:] == "$0":
+ continue
+ smallBlindLine=i
+ #print "found small blind line:",smallBlindLine
+ break
+ #print "small blind line:",smallBlindLine
+ gametypeID=fpdb_simple.recogniseGametypeID(db, cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
+ if isTourney:
+ if site!="ps":
+ raise fpdb_simple.FpdbError("tourneys are only supported on PS right now")
+ siteTourneyNo=fpdb_simple.parseTourneyNo(hand[0])
+ buyin=fpdb_simple.parseBuyin(hand[0])
+ fee=fpdb_simple.parseFee(hand[0])
+ entries=-1 #todo: parse this
+ prizepool=-1 #todo: parse this
+ knockout=0
+ tourneyStartTime=handStartTime #todo: read tourney start time
+ rebuyOrAddon=fpdb_simple.isRebuyOrAddon(hand[0])
- tourneyTypeId=fpdb_simple.recogniseTourneyTypeId(cursor, siteID, buyin, fee, knockout, rebuyOrAddon)
- fpdb_simple.isAlreadyInDB(cursor, gametypeID, siteHandNo)
-
- #part 2: classify lines by type (e.g. cards, action, win, sectionchange) and street
- fpdb_simple.classifyLines(hand, category, lineTypes, lineStreets)
-
- #part 3: read basic player info
- #3a read player names, startcashes
- for i in range (len(hand)): #todo: use maxseats+1 here.
- if (lineTypes[i]=="name"):
- seatLines.append(hand[i])
- names=fpdb_simple.parseNames(seatLines)
- playerIDs = fpdb_simple.recognisePlayerIDs(cursor, names, siteID)
- tmp=fpdb_simple.parseCashesAndSeatNos(seatLines, site)
- startCashes=tmp['startCashes']
- seatNos=tmp['seatNos']
-
- fpdb_simple.createArrays(category, len(names), cardValues, cardSuits, antes, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo)
-
- #3b read positions
- if base=="hold":
- positions = fpdb_simple.parsePositions (hand, names)
-
- #part 4: take appropriate action for each line based on linetype
- for i in range(len(hand)):
- if (lineTypes[i]=="cards"):
- fpdb_simple.parseCardLine (site, category, lineStreets[i], hand[i], names, cardValues, cardSuits, boardValues, boardSuits)
- #if category=="studhilo":
- # print "hand[i]:", hand[i]
- # print "cardValues:", cardValues
- # print "cardSuits:", cardSuits
- elif (lineTypes[i]=="action"):
- fpdb_simple.parseActionLine (site, base, isTourney, hand[i], lineStreets[i], playerIDs, names, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo)
- elif (lineTypes[i]=="win"):
- fpdb_simple.parseWinLine (hand[i], site, names, winnings, isTourney)
- elif (lineTypes[i]=="rake"):
- if isTourney:
- totalRake=0
- else:
- totalRake=fpdb_simple.parseRake(hand[i])
- fpdb_simple.splitRake(winnings, rakes, totalRake)
- elif (lineTypes[i]=="header" or lineTypes[i]=="rake" or lineTypes[i]=="name" or lineTypes[i]=="ignore"):
- pass
- elif (lineTypes[i]=="ante"):
- fpdb_simple.parseAnteLine(hand[i], site, isTourney, names, antes)
- elif (lineTypes[i]=="table"):
- tableResult=fpdb_simple.parseTableLine(site, base, hand[i])
- else:
- raise fpdb_simple.FpdbError("unrecognised lineType:"+lineTypes[i])
- if site=="ftp":
- tableResult=fpdb_simple.parseTableLine(site, base, hand[0])
- maxSeats=tableResult['maxSeats']
- tableName=tableResult['tableName']
- #print "before part5, antes:", antes
-
- #part 5: final preparations, then call fpdb_save_to_db.* with
- # the arrays as they are - that file will fill them.
- fpdb_simple.convertCardValues(cardValues)
- if base=="hold":
- fpdb_simple.convertCardValuesBoard(boardValues)
- fpdb_simple.convertBlindBet(actionTypes, actionAmounts)
- fpdb_simple.checkPositions(positions)
-
- cursor.execute("SELECT limitType FROM Gametypes WHERE id=%s",(gametypeID, ))
- limit_type=cursor.fetchone()[0]
- fpdb_simple.convert3B4B(site, category, limit_type, actionTypes, actionAmounts)
-
- totalWinnings=0
- for i in range(len(winnings)):
- totalWinnings+=winnings[i]
-
- if base=="hold":
- hudImportData=fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
+ tourneyTypeId=fpdb_simple.recogniseTourneyTypeId(cursor, siteID, buyin, fee, knockout, rebuyOrAddon)
+ fpdb_simple.isAlreadyInDB(cursor, gametypeID, siteHandNo)
+
+ #part 2: classify lines by type (e.g. cards, action, win, sectionchange) and street
+ fpdb_simple.classifyLines(hand, category, lineTypes, lineStreets)
+
+ #part 3: read basic player info
+ #3a read player names, startcashes
+ for i in range (len(hand)): #todo: use maxseats+1 here.
+ if (lineTypes[i]=="name"):
+ seatLines.append(hand[i])
+ names=fpdb_simple.parseNames(seatLines)
+ playerIDs = fpdb_simple.recognisePlayerIDs(cursor, names, siteID)
+ tmp=fpdb_simple.parseCashesAndSeatNos(seatLines, site)
+ startCashes=tmp['startCashes']
+ seatNos=tmp['seatNos']
+
+ fpdb_simple.createArrays(category, len(names), cardValues, cardSuits, antes, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo)
+
+ #3b read positions
+ if base=="hold":
+ positions = fpdb_simple.parsePositions (hand, names)
+
+ #part 4: take appropriate action for each line based on linetype
+ for i in range(len(hand)):
+ if (lineTypes[i]=="cards"):
+ fpdb_simple.parseCardLine (site, category, lineStreets[i], hand[i], names, cardValues, cardSuits, boardValues, boardSuits)
+ #if category=="studhilo":
+ # print "hand[i]:", hand[i]
+ # print "cardValues:", cardValues
+ # print "cardSuits:", cardSuits
+ elif (lineTypes[i]=="action"):
+ fpdb_simple.parseActionLine (site, base, isTourney, hand[i], lineStreets[i], playerIDs, names, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo)
+ elif (lineTypes[i]=="win"):
+ fpdb_simple.parseWinLine (hand[i], site, names, winnings, isTourney)
+ elif (lineTypes[i]=="rake"):
+ if isTourney:
+ totalRake=0
+ else:
+ totalRake=fpdb_simple.parseRake(hand[i])
+ fpdb_simple.splitRake(winnings, rakes, totalRake)
+ elif (lineTypes[i]=="header" or lineTypes[i]=="rake" or lineTypes[i]=="name" or lineTypes[i]=="ignore"):
+ pass
+ elif (lineTypes[i]=="ante"):
+ fpdb_simple.parseAnteLine(hand[i], site, isTourney, names, antes)
+ elif (lineTypes[i]=="table"):
+ tableResult=fpdb_simple.parseTableLine(site, base, hand[i])
+ else:
+ raise fpdb_simple.FpdbError("unrecognised lineType:"+lineTypes[i])
+ if site=="ftp":
+ tableResult=fpdb_simple.parseTableLine(site, base, hand[0])
+ maxSeats=tableResult['maxSeats']
+ tableName=tableResult['tableName']
+ #print "before part5, antes:", antes
+
+ #part 5: final preparations, then call fpdb_save_to_db.* with
+ # the arrays as they are - that file will fill them.
+ fpdb_simple.convertCardValues(cardValues)
+ if base=="hold":
+ fpdb_simple.convertCardValuesBoard(boardValues)
+ fpdb_simple.convertBlindBet(actionTypes, actionAmounts)
+ fpdb_simple.checkPositions(positions)
+
+ cursor.execute("SELECT limitType FROM Gametypes WHERE id=%s",(gametypeID, ))
+ limit_type=cursor.fetchone()[0]
+ fpdb_simple.convert3B4B(site, category, limit_type, actionTypes, actionAmounts)
+
+ totalWinnings=0
+ for i in range(len(winnings)):
+ totalWinnings+=winnings[i]
+
+ if base=="hold":
+ hudImportData=fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
, allIns, actionTypeByNo, winnings, totalWinnings, positions
, actionTypes, actionAmounts)
- else:
- hudImportData=fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
+ else:
+ hudImportData=fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
, allIns, actionTypeByNo, winnings, totalWinnings, None
, actionTypes, actionAmounts)
-
- if isTourney:
- ranks=[]
- for i in range (len(names)):
- ranks.append(0)
- payin_amounts=fpdb_simple.calcPayin(len(names), buyin, fee)
-
- if base=="hold":
- result = fpdb_save_to_db.tourney_holdem_omaha(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
- siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
- elif base=="stud":
- result = fpdb_save_to_db.tourney_stud(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
- siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
- else:
- raise fpdb_simple.FpdbError ("unrecognised category")
- else:
- if base=="hold":
- result = fpdb_save_to_db.ring_holdem_omaha(db, cursor, base, category, siteHandNo
+
+ if isTourney:
+ ranks=[]
+ for i in range (len(names)):
+ ranks.append(0)
+ payin_amounts=fpdb_simple.calcPayin(len(names), buyin, fee)
+
+ if base=="hold":
+ result = fpdb_save_to_db.tourney_holdem_omaha(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
+ siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
+ elif base=="stud":
+ result = fpdb_save_to_db.tourney_stud(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
+ siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
+ else:
+ raise fpdb_simple.FpdbError ("unrecognised category")
+ else:
+ if base=="hold":
+ result = fpdb_save_to_db.ring_holdem_omaha(db, cursor, base, category, siteHandNo
,gametypeID, handStartTime, names, playerIDs
,startCashes, positions, cardValues, cardSuits
,boardValues, boardSuits, winnings, rakes
,actionTypes, allIns, actionAmounts, actionNos
,hudImportData, maxSeats, tableName, seatNos)
- elif base=="stud":
- result = fpdb_save_to_db.ring_stud(db, cursor, base, category, siteHandNo, gametypeID,
- handStartTime, names, playerIDs, startCashes, antes, cardValues,
- cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
- else:
- raise fpdb_simple.FpdbError ("unrecognised category")
- db.commit()
- return result
+ elif base=="stud":
+ result = fpdb_save_to_db.ring_stud(db, cursor, base, category, siteHandNo, gametypeID,
+ handStartTime, names, playerIDs, startCashes, antes, cardValues,
+ cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
+ else:
+ raise fpdb_simple.FpdbError ("unrecognised category")
+ db.commit()
+ return result
#end def mainParser
diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py
index 11a2a1ea..c64f0030 100755
--- a/pyfpdb/fpdb_simple.py
+++ b/pyfpdb/fpdb_simple.py
@@ -1074,9 +1074,9 @@ def recogniseGametypeID(db, cursor, topline, smallBlindLine, site_id, category,
cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
result=cursor.fetchone()
#print "recgt1 result=",result
- #ret=result[0]
- #print "recgt1 ret=",ret
- #print "tried SELECTing gametypes.id, result:",result
+ #ret=result[0]
+ #print "recgt1 ret=",ret
+ #print "tried SELECTing gametypes.id, result:",result
try:
len(result)
@@ -1121,7 +1121,7 @@ def recogniseGametypeID(db, cursor, topline, smallBlindLine, site_id, category,
#print "created new gametypes.id:",result
#print "recgt3: result=", result
- return result[0]
+ return result[0]
#end def recogniseGametypeID
def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon):
From 71a587facaf70ccab407352a1fd40c25dbd1125c Mon Sep 17 00:00:00 2001
From: sqlcoder
Date: Tue, 9 Dec 2008 00:29:39 +0000
Subject: [PATCH 25/32] mods to use insert_id() instead of repeated selects and
get postgres working
---
pyfpdb/fpdb_db.py | 3 +-
pyfpdb/fpdb_import.py | 7 +-
pyfpdb/fpdb_parse_logic.py | 46 +-
pyfpdb/fpdb_save_to_db.py | 157 +-
pyfpdb/fpdb_simple.py | 4390 ++++++++++++++++++------------------
5 files changed, 2349 insertions(+), 2254 deletions(-)
diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py
index 2663224e..e1c61c6d 100644
--- a/pyfpdb/fpdb_db.py
+++ b/pyfpdb/fpdb_db.py
@@ -48,7 +48,8 @@ class fpdb_db:
import psycopg2
# If DB connection is made over TCP, then the variables
# host, user and password are required
- if self.host or self.user:
+ print "host=%s user=%s pass=%s." % (host, user, password)
+ if self.host and self.user and self.password:
self.db = psycopg2.connect(host = host,
user = user,
password = password,
diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py
index fd2a321f..2e88899c 100644
--- a/pyfpdb/fpdb_import.py
+++ b/pyfpdb/fpdb_import.py
@@ -75,8 +75,8 @@ class Importer:
if not pgsqlLibFound:
raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
print self.settings
- if not self.settings.has_key('db-host') or \
- not self.settings.has_key('db-user'):
+ if self.settings.has_key('db-host') and \
+ self.settings.has_key('db-user'):
self.db = psycopg2.connect(host = self.settings['db-host'],
user = self.settings['db-user'],
password = self.settings['db-password'],
@@ -243,7 +243,8 @@ class Importer:
self.hand=hand
try:
- handsId=fpdb_parse_logic.mainParser(self.db, self.cursor, site, category, hand)
+ handsId=fpdb_parse_logic.mainParser(self.settings['db-backend'], self.db
+ ,self.cursor, site, category, hand)
self.db.commit()
stored+=1
diff --git a/pyfpdb/fpdb_parse_logic.py b/pyfpdb/fpdb_parse_logic.py
index 1d7d54a0..a345dc93 100644
--- a/pyfpdb/fpdb_parse_logic.py
+++ b/pyfpdb/fpdb_parse_logic.py
@@ -21,7 +21,7 @@ import fpdb_simple
import fpdb_save_to_db
#parses a holdem hand
-def mainParser(db, cursor, site, category, hand):
+def mainParser(backend, db, cursor, site, category, hand):
if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
base="hold"
else:
@@ -48,7 +48,7 @@ def mainParser(db, cursor, site, category, hand):
#print "found small blind line:",smallBlindLine
break
#print "small blind line:",smallBlindLine
- gametypeID=fpdb_simple.recogniseGametypeID(db, cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
+ gametypeID=fpdb_simple.recogniseGametypeID(backend, db, cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
if isTourney:
if site!="ps":
raise fpdb_simple.FpdbError("tourneys are only supported on PS right now")
@@ -148,25 +148,41 @@ def mainParser(db, cursor, site, category, hand):
payin_amounts=fpdb_simple.calcPayin(len(names), buyin, fee)
if base=="hold":
- result = fpdb_save_to_db.tourney_holdem_omaha(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
- siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
+ result = fpdb_save_to_db.tourney_holdem_omaha(
+ backend, db, cursor, base, category, siteTourneyNo, buyin
+ , fee, knockout, entries, prizepool, tourneyStartTime
+ , payin_amounts, ranks, tourneyTypeId, siteID, siteHandNo
+ , gametypeID, handStartTime, names, playerIDs, startCashes
+ , positions, cardValues, cardSuits, boardValues, boardSuits
+ , winnings, rakes, actionTypes, allIns, actionAmounts
+ , actionNos, hudImportData, maxSeats, tableName, seatNos)
elif base=="stud":
- result = fpdb_save_to_db.tourney_stud(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
- siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
+ result = fpdb_save_to_db.tourney_stud(
+ backend, db, cursor, base, category, siteTourneyNo
+ , buyin, fee, knockout, entries, prizepool, tourneyStartTime
+ , payin_amounts, ranks, tourneyTypeId, siteID, siteHandNo
+ , gametypeID, handStartTime, names, playerIDs, startCashes
+ , antes, cardValues, cardSuits, winnings, rakes, actionTypes
+ , allIns, actionAmounts, actionNos, hudImportData, maxSeats
+ , tableName, seatNos)
else:
raise fpdb_simple.FpdbError ("unrecognised category")
else:
if base=="hold":
- result = fpdb_save_to_db.ring_holdem_omaha(db, cursor, base, category, siteHandNo
- ,gametypeID, handStartTime, names, playerIDs
- ,startCashes, positions, cardValues, cardSuits
- ,boardValues, boardSuits, winnings, rakes
- ,actionTypes, allIns, actionAmounts, actionNos
- ,hudImportData, maxSeats, tableName, seatNos)
+ result = fpdb_save_to_db.ring_holdem_omaha(
+ backend, db, cursor, base, category, siteHandNo
+ , gametypeID, handStartTime, names, playerIDs
+ , startCashes, positions, cardValues, cardSuits
+ , boardValues, boardSuits, winnings, rakes
+ , actionTypes, allIns, actionAmounts, actionNos
+ , hudImportData, maxSeats, tableName, seatNos)
elif base=="stud":
- result = fpdb_save_to_db.ring_stud(db, cursor, base, category, siteHandNo, gametypeID,
- handStartTime, names, playerIDs, startCashes, antes, cardValues,
- cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
+ result = fpdb_save_to_db.ring_stud(
+ backend, db, cursor, base, category, siteHandNo, gametypeID
+ , handStartTime, names, playerIDs, startCashes, antes
+ , cardValues, cardSuits, winnings, rakes, actionTypes, allIns
+ , actionAmounts, actionNos, hudImportData, maxSeats, tableName
+ , seatNos)
else:
raise fpdb_simple.FpdbError ("unrecognised category")
db.commit()
diff --git a/pyfpdb/fpdb_save_to_db.py b/pyfpdb/fpdb_save_to_db.py
index d548eca5..3a7989ca 100644
--- a/pyfpdb/fpdb_save_to_db.py
+++ b/pyfpdb/fpdb_save_to_db.py
@@ -18,77 +18,110 @@
#This file contains methods to store hands into the db. decides to move this
#into a seperate file since its ugly, fairly long and just generally in the way.
+from time import time
+
import fpdb_simple
#stores a stud/razz hand into the database
-def ring_stud(db, cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
- fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
-
- hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
-
- #print "before calling store_hands_players_stud, antes:", antes
- hands_players_ids=fpdb_simple.store_hands_players_stud(db, cursor, hands_id, player_ids,
- start_cashes, antes, card_values, card_suits, winnings, rakes, seatNos)
-
- fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
-
- fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
- return hands_id
+def ring_stud(backend, db, cursor, base, category, site_hand_no, gametype_id, hand_start_time
+ ,names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes
+ ,action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName
+ ,seatNos):
+ fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
+
+ hands_id=fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id
+ ,hand_start_time, names, tableName, maxSeats)
+
+ #print "before calling store_hands_players_stud, antes:", antes
+ hands_players_ids=fpdb_simple.store_hands_players_stud(backend, db, cursor, hands_id, player_ids
+ ,start_cashes, antes, card_values
+ ,card_suits, winnings, rakes, seatNos)
+
+ fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
+
+ fpdb_simple.storeActions(cursor, hands_players_ids, action_types
+ ,allIns, action_amounts, actionNos)
+ return hands_id
#end def ring_stud
-def ring_holdem_omaha(db, cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
- """stores a holdem/omaha hand into the database"""
- fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
- fpdb_simple.fill_board_cards(board_values, board_suits)
+def ring_holdem_omaha(backend, db, cursor, base, category, site_hand_no, gametype_id
+ ,hand_start_time, names, player_ids, start_cashes, positions, card_values
+ ,card_suits, board_values, board_suits, winnings, rakes, action_types, allIns
+ ,action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
+ """stores a holdem/omaha hand into the database"""
+ t0 = time()
+ fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
+ t1 = time()
+ fpdb_simple.fill_board_cards(board_values, board_suits)
+ t2 = time()
- hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
-
- hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos)
-
- fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
-
- fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits)
-
- fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
- return hands_id
+ hands_id=fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id
+ ,hand_start_time, names, tableName, maxSeats)
+ t3 = time()
+ hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha(
+ backend, db, cursor, category, hands_id, player_ids, start_cashes
+ , positions, card_values, card_suits, winnings, rakes, seatNos)
+ t4 = time()
+ fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
+ t5 = time()
+ fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits)
+ t6 = time()
+ fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
+ t7 = time()
+ print "cards=%4.3f board=%4.3f hands=%4.3f plyrs=%4.3f hudcache=%4.3f board=%4.3f actions=%4.3f" \
+ % (t1-t0, t2-t1, t3-t2, t4-t3, t5-t4, t6-t5, t7-t6)
+ return hands_id
#end def ring_holdem_omaha
-def tourney_holdem_omaha(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId, siteId, #end of tourney specific params
- site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
- """stores a tourney holdem/omaha hand into the database"""
- fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
- fpdb_simple.fill_board_cards(board_values, board_suits)
-
- tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourney_start)
- tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings)
-
- hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
-
- hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha_tourney(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids)
-
- fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
-
- fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits)
-
- fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
- return hands_id
+def tourney_holdem_omaha(backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout
+ ,entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId
+ ,siteId #end of tourney specific params
+ ,site_hand_no, gametype_id, hand_start_time, names, player_ids
+ ,start_cashes, positions, card_values, card_suits, board_values
+ ,board_suits, winnings, rakes, action_types, allIns, action_amounts
+ ,actionNos, hudImportData, maxSeats, tableName, seatNos):
+ """stores a tourney holdem/omaha hand into the database"""
+ fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
+ fpdb_simple.fill_board_cards(board_values, board_suits)
+
+ tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourney_start)
+ tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings)
+
+ hands_id=fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id
+ ,hand_start_time, names, tableName, maxSeats)
+
+ hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha_tourney(
+ backend, db, cursor, category, hands_id, player_ids, start_cashes, positions
+ , card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids)
+
+ fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
+
+ fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits)
+
+ fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
+ return hands_id
#end def tourney_holdem_omaha
-def tourney_stud(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId,
- siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
+def tourney_stud(backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries
+ ,prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId
+ ,siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes
+ ,cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts
+ ,actionNos, hudImportData, maxSeats, tableName, seatNos):
#stores a tourney stud/razz hand into the database
- fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits)
-
- tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourneyStartTime)
-
- tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, playerIds, payin_amounts, ranks, winnings)
-
- hands_id=fpdb_simple.storeHands(db, cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats)
-
- hands_players_ids=fpdb_simple.store_hands_players_stud_tourney(db, cursor, hands_id, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, seatNos, tourneys_players_ids)
-
- fpdb_simple.storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData)
-
- fpdb_simple.storeActions(cursor, hands_players_ids, actionTypes, allIns, actionAmounts, actionNos)
- return hands_id
+ fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits)
+
+ tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourneyStartTime)
+
+ tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, playerIds, payin_amounts, ranks, winnings)
+
+ hands_id=fpdb_simple.storeHands(backend, db, cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats)
+
+ hands_players_ids=fpdb_simple.store_hands_players_stud_tourney(backend, db, cursor, hands_id
+ , playerIds, startCashes, antes, cardValues, cardSuits
+ , winnings, rakes, seatNos, tourneys_players_ids)
+
+ fpdb_simple.storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData)
+
+ fpdb_simple.storeActions(cursor, hands_players_ids, actionTypes, allIns, actionAmounts, actionNos)
+ return hands_id
#end def tourney_stud
diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py
index c64f0030..dd7d56e8 100755
--- a/pyfpdb/fpdb_simple.py
+++ b/pyfpdb/fpdb_simple.py
@@ -1,2173 +1,2217 @@
-#!/usr/bin/python
-
-#Copyright 2008 Steffen Jobbagy-Felso
-#This program is free software: you can redistribute it and/or modify
-#it under the terms of the GNU Affero General Public License as published by
-#the Free Software Foundation, version 3 of the License.
-#
-#This program is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-#GNU General Public License for more details.
-#
-#You should have received a copy of the GNU Affero General Public License
-#along with this program. If not, see .
-#In the "official" distribution you can find the license in
-#agpl-3.0.txt in the docs folder of the package.
-
-#This file contains simple functions for fpdb
-
-import datetime
-import re
-
-PS=1
-FTP=2
-
-class DuplicateError(Exception):
- def __init__(self, value):
- self.value = value
- def __str__(self):
- return repr(self.value)
-
-class FpdbError(Exception):
- def __init__(self, value):
- self.value = value
- def __str__(self):
- return repr(self.value)
-
-#returns an array of the total money paid. intending to add rebuys/addons here
-def calcPayin(count, buyin, fee):
- result=[]
- for i in range(count):
- result.append (buyin+fee)
- return result
-#end def calcPayin
-
-def checkPositions(positions):
- """verifies that these positions are valid"""
- for i in range (len(positions)):
- pos=positions[i]
- try:#todo: use type recognition instead of error
- if (len(pos)!=1):
- raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+pos) #dont need to str() here
- except TypeError:#->not string->is int->fine
- pass
-
- ### RHH modified to allow for "position 9" here (pos==9 is when you're a dead hand before the BB
- if (pos!="B" and pos!="S" and pos!=0 and pos!=1 and pos!=2 and pos!=3 and pos!=4 and pos!=5 and pos!=6 and pos!=7 and pos!=9):
- raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+str(pos))
-#end def fpdb_simple.checkPositions
-
-#classifies each line for further processing in later code. Manipulates the passed arrays.
-def classifyLines(hand, category, lineTypes, lineStreets):
- currentStreet="predeal"
- done=False #set this to true once we reach the last relevant line (the summary, except rake, is all repeats)
- for i in range (len(hand)):
- if (done):
- if (hand[i].find("[")==-1 or hand[i].find("mucked [")==-1):
- lineTypes.append("ignore")
- else: #it's storing a mucked card
- lineTypes.append("cards")
- elif (hand[i].startswith("Dealt to")):
- lineTypes.append("cards")
- elif (i==0):
- lineTypes.append("header")
- elif (hand[i].startswith("Seat ") and ((hand[i].find("in chips")!=-1) or (hand[i].find("($")!=-1))):
- lineTypes.append("name")
- elif (isActionLine(hand[i])):
- lineTypes.append("action")
- if (hand[i].find(" posts ")!=-1 or hand[i].find(" posts the ")!=-1):#need to set this here so the "action" of posting blinds is registered properly
- currentStreet="preflop"
- elif (isWinLine(hand[i])):
- lineTypes.append("win")
- elif (hand[i].startswith("Total pot ") and hand[i].find("Rake")!=-1):
- lineTypes.append("rake")
- done=True
- elif (hand[i]=="*** SHOW DOWN ***" or hand[i]=="*** SUMMARY ***"):
- lineTypes.append("ignore")
- #print "in classifyLine, showdown or summary"
- elif (hand[i].find(" antes ")!=-1 or hand[i].find(" posts the ante ")!=-1):
- lineTypes.append("ante")
- elif (hand[i].startswith("*** FLOP *** [")):
- lineTypes.append("cards")
- currentStreet="flop"
- elif (hand[i].startswith("*** TURN *** [")):
- lineTypes.append("cards")
- currentStreet="turn"
- elif (hand[i].startswith("*** RIVER *** [")):
- lineTypes.append("cards")
- currentStreet="river"
- elif (hand[i].startswith("*** 3")):
- lineTypes.append("ignore")
- currentStreet=0
- elif (hand[i].startswith("*** 4")):
- lineTypes.append("ignore")
- currentStreet=1
- elif (hand[i].startswith("*** 5")):
- lineTypes.append("ignore")
- currentStreet=2
- elif (hand[i].startswith("*** 6")):
- lineTypes.append("ignore")
- currentStreet=3
- elif (hand[i].startswith("*** 7") or hand[i]=="*** RIVER ***"):
- lineTypes.append("ignore")
- currentStreet=4
- elif (hand[i].find(" shows [")!=-1):
- lineTypes.append("cards")
- elif (hand[i].startswith("Table '")):
- lineTypes.append("table")
- else:
- raise FpdbError("unrecognised linetype in:"+hand[i])
- lineStreets.append(currentStreet)
-#end def classifyLines
-
-def convert3B4B(site, category, limit_type, actionTypes, actionAmounts):
- """calculates the actual bet amounts in the given amount array and changes it accordingly."""
- for i in range (len(actionTypes)):
- for j in range (len(actionTypes[i])):
- bets=[]
- for k in range (len(actionTypes[i][j])):
- if (actionTypes[i][j][k]=="bet"):
- bets.append((i,j,k))
- if (len(bets)==2):
- #print "len(bets) 2 or higher, need to correct it. bets:",bets,"len:",len(bets)
- amount2=actionAmounts[bets[1][0]][bets[1][1]][bets[1][2]]
- amount1=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]
- actionAmounts[bets[1][0]][bets[1][1]][bets[1][2]]=amount2-amount1
- elif (len(bets)>2):
- fail=True
- #todo: run correction for below
- if (site=="ps" and category=="holdem" and limit_type=="nl" and len(bets)==3):
- fail=False
- if (site=="ftp" and category=="omahahi" and limit_type=="pl" and len(bets)==3):
- fail=False
-
- if fail:
- print "len(bets)>2 in convert3B4B, i didnt think this is possible. i:",i,"j:",j,"k:",k
- print "actionTypes:",actionTypes
- raise FpdbError ("too many bets in convert3B4B")
- #print "actionAmounts postConvert",actionAmounts
-#end def convert3B4B(actionTypes, actionAmounts)
-
-#Corrects the bet amount if the player had to pay blinds
-def convertBlindBet(actionTypes, actionAmounts):
- i=0#setting street to pre-flop
- for j in range (len(actionTypes[i])):#playerloop
- blinds=[]
- bets=[]
- for k in range (len(actionTypes[i][j])):
- if (actionTypes[i][j][k]=="blind"):
- blinds.append((i,j,k))
-
- if (len(blinds)>0 and actionTypes[i][j][k]=="bet"):
- bets.append((i,j,k))
- if (len(bets)==1):
- blind_amount=actionAmounts[blinds[0][0]][blinds[0][1]][blinds[0][2]]
- bet_amount=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]
- actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]=bet_amount-blind_amount
-#end def convertBlindBet
-
-#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
-#todo: make this use convertCardValuesBoard
-def convertCardValues(arr):
- for i in range (len(arr)):
- for j in range (len(arr[i])):
- if (arr[i][j]=="A"):
- arr[i][j]=14
- elif (arr[i][j]=="K"):
- arr[i][j]=13
- elif (arr[i][j]=="Q"):
- arr[i][j]=12
- elif (arr[i][j]=="J"):
- arr[i][j]=11
- elif (arr[i][j]=="T"):
- arr[i][j]=10
- else:
- arr[i][j]=int(arr[i][j])
-#end def convertCardValues
-
-#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
-def convertCardValuesBoard(arr):
- for i in range (len(arr)):
- if (arr[i]=="A"):
- arr[i]=14
- elif (arr[i]=="K"):
- arr[i]=13
- elif (arr[i]=="Q"):
- arr[i]=12
- elif (arr[i]=="J"):
- arr[i]=11
- elif (arr[i]=="T"):
- arr[i]=10
- else:
- arr[i]=int(arr[i])
-#end def convertCardValuesBoard
-
-#this creates the 2D/3D arrays. manipulates the passed arrays instead of returning.
-def createArrays(category, seats, card_values, card_suits, antes, winnings, rakes, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
- for i in range(seats):#create second dimension arrays
- tmp=[]
- card_values.append(tmp)
- tmp=[]
- card_suits.append(tmp)
- antes.append(0)
- winnings.append(0)
- rakes.append(0)
-
- if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
- streetCount=4
- else:
- streetCount=5
-
- for i in range(streetCount): #build the first dimension array, for streets
- tmp=[]
- action_types.append(tmp)
- tmp=[]
- allIns.append(tmp)
- tmp=[]
- action_amounts.append(tmp)
- tmp=[]
- actionNos.append(tmp)
- tmp=[]
- actionTypeByNo.append(tmp)
- for j in range (seats): #second dimension arrays: players
- tmp=[]
- action_types[i].append(tmp)
- tmp=[]
- allIns[i].append(tmp)
- tmp=[]
- action_amounts[i].append(tmp)
- tmp=[]
- actionNos[i].append(tmp)
- if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
- pass
- elif (category=="razz" or category=="studhi" or category=="studhilo"):#need to fill card arrays.
- for i in range(seats):
- for j in range (7):
- card_values[i].append(0)
- card_suits[i].append("x")
- else:
- raise FpdbError("invalid category")
-#end def createArrays
-
-def fill_board_cards(board_values, board_suits):
-#fill up the two board card arrays
- while (len(board_values)<5):
- board_values.append(0)
- board_suits.append("x")
-#end def fill_board_cards
-
-def fillCardArrays(player_count, base, category, card_values, card_suits):
- """fills up the two card arrays"""
- if (category=="holdem"):
- cardCount=2
- elif (category=="omahahi" or category=="omahahilo"):
- cardCount=4
- elif base=="stud":
- cardCount=7
- else:
- raise fpdb_simple.FpdbError ("invalid category:", category)
-
- for i in range (player_count):
- while (len(card_values[i])=1):
- raise DuplicateError ("dupl")
-#end isAlreadyInDB
-
-def isRebuyOrAddon(topline):
- """isRebuyOrAddon not implemented yet"""
- return False
-#end def isRebuyOrAddon
-
-#returns whether the passed topline indicates a tournament or not
-def isTourney(topline):
- if (topline.find("Tournament")!=-1):
- return True
- else:
- return False
-#end def isTourney
-
-#returns boolean whether the passed line is a win line
-def isWinLine(line):
- if (line.find("wins the pot")!=-1):
- return True
- elif (line.find("ties for the high pot")!=-1):
- return True
- elif (line.find("ties for the high main pot")!=-1):
- return True
- elif (line.find("ties for the high side pot")!=-1):
- return True
- elif (line.find("ties for the low pot")!=-1):
- return True
- elif (line.find("ties for the low main pot")!=-1):
- return True
- elif (line.find("ties for the low side pot")!=-1):
- return True
- elif (line.find("ties for the main pot")!=-1): #for ftp tied main pot of split pot
- return True
- elif (line.find("ties for the pot")!=-1): #for ftp tie
- return True
- elif (line.find("ties for the side pot")!=-1): #for ftp tied split pots
- return True
- elif (line.find("wins side pot #")!=-1): #for ftp multi split pots
- return True
- elif (line.find("wins the low main pot")!=-1):
- return True
- elif (line.find("wins the low pot")!=-1):
- return True
- elif (line.find("wins the low side pot")!=-1):
- return True
- elif (line.find("wins the high main pot")!=-1):
- return True
- elif (line.find("wins the high pot")!=-1):
- return True
- elif (line.find("wins the high side pot")!=-1):
- return True
- elif (line.find("wins the main pot")!=-1):
- return True
- elif (line.find("wins the side pot")!=-1): #for ftp split pots
- return True
- elif (line.find("collected")!=-1):
- return True
- else:
- return False #not raising error here, any unknown line wouldve been detected in isActionLine already
-#end def isWinLine
-
-#returns the amount of cash/chips put into the put in the given action line
-def parseActionAmount(line, atype, site, isTourney):
- #if (line.endswith(" and is all-in")):
- # line=line[:-14]
- #elif (line.endswith(", and is all in")):
- # line=line[:-15]
-
- if line.endswith(", and is capped"):#ideally we should recognise this as an all-in if category is capXl
- line=line[:-15]
- if line.endswith(" and is capped"):
- line=line[:-14]
-
-
- if (atype=="fold"):
- amount=0
- elif (atype=="check"):
- amount=0
- elif (atype=="unbet" and site=="ftp"):
- pos1=line.find("$")+1
- pos2=line.find(" returned to")
- amount=float2int(line[pos1:pos2])
- elif (atype=="unbet" and site=="ps"):
- #print "ps unbet, line:",line
- pos1=line.find("$")+1
- if pos1==0:
- pos1=line.find("(")+1
- pos2=line.find(")")
- amount=float2int(line[pos1:pos2])
- elif (atype=="bet" and site=="ps" and line.find(": raises $")!=-1 and line.find("to $")!=-1):
- pos=line.find("to $")+4
- amount=float2int(line[pos:])
- else:
- if not isTourney:
- pos=line.rfind("$")+1
- #print "parseActionAmount, line:", line, "line[pos:]:", line[pos:]
- amount=float2int(line[pos:])
- else:
- #print "line:"+line+"EOL"
- pos=line.rfind(" ")+1
- #print "pos:",pos
- #print "pos of 20:", line.find("20")
- amount=int(line[pos:])
-
- if atype=="unbet":
- amount*=-1
- return amount
-#end def parseActionAmount
-
-#doesnt return anything, simply changes the passed arrays action_types and
-# action_amounts. For stud this expects numeric streets (3-7), for
-# holdem/omaha it expects predeal, preflop, flop, turn or river
-def parseActionLine(site, base, isTourney, line, street, playerIDs, names, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
- if (street=="predeal" or street=="preflop"):
- street=0
- elif (street=="flop"):
- street=1
- elif (street=="turn"):
- street=2
- elif (street=="river"):
- street=3
-
- nextActionNo=0
- for player in range(len(actionNos[street])):
- for count in range(len(actionNos[street][player])):
- if actionNos[street][player][count]>=nextActionNo:
- nextActionNo=actionNos[street][player][count]+1
-
- line, allIn=goesAllInOnThisLine(line)
- atype=parseActionType(line)
- playerno=recognisePlayerNo(line, names, atype)
- amount=parseActionAmount(line, atype, site, isTourney)
-
- action_types[street][playerno].append(atype)
- allIns[street][playerno].append(allIn)
- action_amounts[street][playerno].append(amount)
- actionNos[street][playerno].append(nextActionNo)
- tmp=(playerIDs[playerno], atype)
- actionTypeByNo[street].append(tmp)
-#end def parseActionLine
-
-def goesAllInOnThisLine(line):
- """returns whether the player went all-in on this line and removes the all-in text from the line."""
- isAllIn=False
- if (line.endswith(" and is all-in")):
- line=line[:-14]
- isAllIn=True
- elif (line.endswith(", and is all in")):
- line=line[:-15]
- isAllIn=True
- return (line, isAllIn)
-#end def goesAllInOnThisLine
-
-#returns the action type code (see table design) of the given action line
-def parseActionType(line):
- if (line.startswith("Uncalled bet")):
- return "unbet"
- elif (line.endswith("folds")):
- return "fold"
- elif (line.endswith("checks")):
- return "check"
- elif (line.find("calls")!=-1):
- return "call"
- elif (line.find("brings in for")!=-1):
- return "blind"
- elif (line.find("completes it to")!=-1):
- return "bet"
- #todo: what if someone completes instead of bringing in?
- elif (line.find(" posts $")!=-1):
- return "blind"
- elif (line.find(" posts a dead ")!=-1):
- return "blind"
- elif (line.find(": posts small blind ")!=-1):
- return "blind"
- elif (line.find(" posts the small blind of $")!=-1):
- return "blind"
- elif (line.find(": posts big blind ")!=-1):
- return "blind"
- elif (line.find(" posts the big blind of $")!=-1):
- return "blind"
- elif (line.find(": posts small & big blinds $")!=-1):
- return "blind"
- #todo: seperately record voluntary blind payments made to join table out of turn
- elif (line.find("bets")!=-1):
- return "bet"
- elif (line.find("raises")!=-1):
- return "bet"
- else:
- raise FpdbError ("failed to recognise actiontype in parseActionLine in: "+line)
-#end def parseActionType
-
-#parses the ante out of the given line and checks which player paid it, updates antes accordingly.
-def parseAnteLine(line, site, isTourney, names, antes):
- for i in range(len(names)):
- if (line.startswith(names[i].encode("latin-1"))): #found the ante'er
- pos=line.rfind("$")+1
- if not isTourney:
- antes[i]+=float2int(line[pos:])
- else:
- if line.find("all-in")==-1:
- pos=line.rfind(" ")+1
- antes[i]+=int(line[pos:])
- else:
- pos1=line.rfind("ante")+5
- pos2=line.find(" ",pos1)
- antes[i]+=int(line[pos1:pos2])
- #print "parseAnteLine line: ", line, "antes[i]", antes[i], "antes", antes
-#end def parseAntes
-
-#returns the buyin of a tourney in cents
-def parseBuyin(topline):
- pos1=topline.find("$")+1
- pos2=topline.find("+")
- return float2int(topline[pos1:pos2])
-#end def parseBuyin
-
-#parses a card line and changes the passed arrays accordingly
-#todo: reorganise this messy method
-def parseCardLine(site, category, street, line, names, cardValues, cardSuits, boardValues, boardSuits):
- if (line.startswith("Dealt to ") or line.find(" shows [")!=-1 or line.find("mucked [")!=-1):
- playerNo=recognisePlayerNo(line, names, "card") #anything but unbet will be ok for that string
-
- pos=line.rfind("[")+1
- if (category=="holdem"):
- for i in (pos, pos+3):
- cardValues[playerNo].append(line[i:i+1])
- cardSuits[playerNo].append(line[i+1:i+2])
- if (len(cardValues[playerNo])!=2):
- if cardValues[playerNo][0]==cardValues[playerNo][2] and cardSuits[playerNo][1]==cardSuits[playerNo][3]: #two tests will do
- cardValues[playerNo]=cardValues[playerNo][0:2]
- cardSuits[playerNo]=cardSuits[playerNo][0:2]
- else:
- print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
- raise FpdbError("read too many/too few holecards in parseCardLine")
- elif (category=="omahahi" or category=="omahahilo"):
- for i in (pos, pos+3, pos+6, pos+9):
- cardValues[playerNo].append(line[i:i+1])
- cardSuits[playerNo].append(line[i+1:i+2])
- if (len(cardValues[playerNo])!=4):
- if cardValues[playerNo][0]==cardValues[playerNo][4] and cardSuits[playerNo][3]==cardSuits[playerNo][7]: #two tests will do
- cardValues[playerNo]=cardValues[playerNo][0:4]
- cardSuits[playerNo]=cardSuits[playerNo][0:4]
- else:
- print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
- raise FpdbError("read too many/too few holecards in parseCardLine")
- elif (category=="razz" or category=="studhi" or category=="studhilo"):
- if (line.find("shows")==-1):
- #print "parseCardLine(in stud if), street:", street
- if line[pos+2]=="]": #-> not (hero and 3rd street)
- cardValues[playerNo][street+2]=line[pos:pos+1]
- cardSuits[playerNo][street+2]=line[pos+1:pos+2]
- else:
- #print "hero card1:", line[pos:pos+2], "hero card2:", line[pos+3:pos+5], "hero card3:", line[pos+6:pos+8],
- cardValues[playerNo][street]=line[pos:pos+1]
- cardSuits[playerNo][street]=line[pos+1:pos+2]
- cardValues[playerNo][street+1]=line[pos+3:pos+4]
- cardSuits[playerNo][street+1]=line[pos+4:pos+5]
- cardValues[playerNo][street+2]=line[pos+6:pos+7]
- cardSuits[playerNo][street+2]=line[pos+7:pos+8]
- else:
- #print "parseCardLine(in stud else), street:", street
- cardValues[playerNo][0]=line[pos:pos+1]
- cardSuits[playerNo][0]=line[pos+1:pos+2]
- pos+=3
- cardValues[playerNo][1]=line[pos:pos+1]
- cardSuits[playerNo][1]=line[pos+1:pos+2]
- if street==4:
- pos=pos=line.rfind("]")-2
- cardValues[playerNo][6]=line[pos:pos+1]
- cardSuits[playerNo][6]=line[pos+1:pos+2]
- #print "cardValues:", cardValues
- #print "cardSuits:", cardSuits
- else:
- print "line:",line,"street:",street
- raise FpdbError("invalid category")
- #print "end of parseCardLine/playercards, cardValues:",cardValues
- elif (line.startswith("*** FLOP ***")):
- pos=line.find("[")+1
- for i in (pos, pos+3, pos+6):
- boardValues.append(line[i:i+1])
- boardSuits.append(line[i+1:i+2])
- #print boardValues
- elif (line.startswith("*** TURN ***") or line.startswith("*** RIVER ***")):
- pos=line.find("[")+1
- pos=line.find("[", pos+1)+1
- boardValues.append(line[pos:pos+1])
- boardSuits.append(line[pos+1:pos+2])
- #print boardValues
- else:
- raise FpdbError ("unrecognised line:"+line)
-#end def parseCardLine
-
-def parseCashesAndSeatNos(lines, site):
- """parses the startCashes and seatNos of each player out of the given lines and returns them as a dictionary of two arrays"""
- cashes = []
- seatNos = []
- for i in range (len(lines)):
- pos2=lines[i].find(":")
- seatNos.append(int(lines[i][5:pos2]))
-
- pos1=lines[i].rfind("($")+2
- if pos1==1: #for tourneys - it's 1 instead of -1 due to adding 2 above
- pos1=lines[i].rfind("(")+1
- if (site=="ftp"):
- pos2=lines[i].rfind(")")
- elif (site=="ps"):
- pos2=lines[i].find(" in chips")
- cashes.append(float2int(lines[i][pos1:pos2]))
- return {'startCashes':cashes, 'seatNos':seatNos}
-#end def parseCashesAndSeatNos
-
-#returns the buyin of a tourney in cents
-def parseFee(topline):
- pos1=topline.find("$")+1
- pos1=topline.find("$",pos1)+1
- pos2=topline.find(" ", pos1)
- return float2int(topline[pos1:pos2])
-#end def parsefee
-
-#returns a datetime object with the starttime indicated in the given topline
-def parseHandStartTime(topline, site):
- #convert x:13:35 to 0x:13:35
- counter=0
- while (True):
- pos=topline.find(" "+str(counter)+":")
- if (pos!=-1):
- topline=topline[0:pos+1]+"0"+topline[pos+1:]
- counter+=1
- if counter==10: break
-
- isUTC=False
- if site=="ftp":
- pos = topline.find(" ", len(topline)-26)+1
- tmp = topline[pos:]
- #print "year:", tmp[14:18], "month", tmp[19:21], "day", tmp[22:24], "hour", tmp[0:2], "minute", tmp[3:5], "second", tmp[6:8]
- result = datetime.datetime(int(tmp[14:18]), int(tmp[19:21]), int(tmp[22:24]), int(tmp[0:2]), int(tmp[3:5]), int(tmp[6:8]))
- elif site=="ps":
- if topline.find("UTC")!=-1:
- pos1 = topline.find("-")+2
- pos2 = topline.find("UTC")
- tmp=topline[pos1:pos2]
- isUTC=True
- else:
- tmp=topline[-30:]
- #print "parsehandStartTime, tmp:", tmp
- pos = tmp.find("-")+2
- tmp = tmp[pos:]
- #Need to match either
- # 2008/09/07 06:23:14 ET or
- # 2008/08/17 - 01:14:43 (ET)
- m = re.match('(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P
[0-9]{2}):(?P[0-9]{2}):(?P[0-9]{2})',tmp)
- #print "year:", int(m.group('YEAR')), "month", int(m.group('MON')), "day", int(m.group('DAY')), "hour", int(m.group('HR')), "minute", int(m.group('MIN')), "second", int(m.group('SEC'))
- result = datetime.datetime(int(m.group('YEAR')), int(m.group('MON')), int(m.group('DAY')), int(m.group('HR')), int(m.group('MIN')), int(m.group('SEC')))
- else:
- raise FpdbError("invalid site in parseHandStartTime")
-
- if (site=="ftp" or site=="ps") and not isUTC: #these use US ET
- result+=datetime.timedelta(hours=5)
-
- return result
-#end def parseHandStartTime
-
-#parses the names out of the given lines and returns them as an array
-def parseNames(lines):
- result = []
- for i in range (len(lines)):
- pos1=lines[i].find(":")+2
- pos2=lines[i].rfind("(")-1
- tmp=lines[i][pos1:pos2]
- #print "parseNames, tmp original:",tmp
- tmp=unicode(tmp,"latin-1")
- #print "parseNames, tmp after unicode latin-1 conversion:",tmp
- result.append(tmp)
- return result
-#end def parseNames
-
-#returns an array with the positions of the respective players
-def parsePositions (hand, names):
- #prep array
- positions=[]
- for i in range(len(names)):
- positions.append(-1)
-
- #find blinds
- sb,bb=-1,-1
- for i in range (len(hand)):
- if (sb==-1 and hand[i].find("small blind")!=-1 and hand[i].find("dead small blind")==-1):
- sb=hand[i]
- #print "sb:",sb
- if (bb==-1 and hand[i].find("big blind")!=-1 and hand[i].find("dead big blind")==-1):
- bb=hand[i]
- #print "bb:",bb
-
- #identify blinds
- #print "parsePositions before recognising sb/bb. names:",names
- sbExists=True
- if (sb!=-1):
- sb=recognisePlayerNo(sb, names, "bet")
- else:
- sbExists=False
- if (bb!=-1):
- bb=recognisePlayerNo(bb, names, "bet")
-
- #write blinds into array
- if (sbExists):
- positions[sb]="S"
- positions[bb]="B"
-
- #fill up rest of array
- if (sbExists):
- arraypos=sb-1
- else:
- arraypos=bb-1
- distFromBtn=0
- while (arraypos>=0 and arraypos != bb):
- #print "parsePositions first while, arraypos:",arraypos,"positions:",positions
- positions[arraypos]=distFromBtn
- arraypos-=1
- distFromBtn+=1
-
- ### RHH - Changed to set the null seats before BB to "9"
- i=bb-1
- while positions[i] < 0:
- positions[i]=9
- i-=1
-
- arraypos=len(names)-1
- if (bb!=0 or (bb==0 and sbExists==False)):
- while (arraypos>bb):
- positions[arraypos]=distFromBtn
- arraypos-=1
- distFromBtn+=1
-
- for i in range (len(names)):
- if positions[i]==-1:
- print "parsePositions names:",names
- print "result:",positions
- raise FpdbError ("failed to read positions")
- return positions
-#end def parsePositions
-
-#simply parses the rake amount and returns it as an int
-def parseRake(line):
- pos=line.find("Rake")+6
- rake=float2int(line[pos:])
- return rake
-#end def parseRake
-
-def parseSiteHandNo(topline):
- """returns the hand no assigned by the poker site"""
- pos1=topline.find("#")+1
- pos2=topline.find(":")
- return topline[pos1:pos2]
-#end def parseSiteHandNo
-
-def parseTableLine(site, base, line):
- """returns a dictionary with maxSeats and tableName"""
- if site=="ps":
- pos1=line.find('\'')+1
- pos2=line.find('\'', pos1)
- #print "table:",line[pos1:pos2]
- pos3=pos2+2
- pos4=line.find("-max")
- #print "seats:",line[pos3:pos4]
- return {'maxSeats':int(line[pos3:pos4]), 'tableName':line[pos1:pos2]}
- elif site=="ftp":
- pos1=line.find("Table ")+6
- pos2=line.find("-")-1
- if base=="hold":
- maxSeats=9
- elif base=="stud":
- maxSeats=8
-
- if line.find("6 max")!=-1:
- maxSeats=6
- elif line.find("4 max")!=-1:
- maxSeats=4
- elif line.find("heads up")!=-1:
- maxSeats=2
-
- return {'maxSeats':maxSeats, 'tableName':line[pos1:pos2]}
- else:
- raise FpdbError("invalid site ID")
-#end def parseTableLine
-
-#returns the hand no assigned by the poker site
-def parseTourneyNo(topline):
- pos1=topline.find("Tournament #")+12
- pos2=topline.find(",", pos1)
- #print "parseTourneyNo pos1:",pos1," pos2:",pos2, " result:",topline[pos1:pos2]
- return topline[pos1:pos2]
-#end def parseTourneyNo
-
-#parses a win/collect line. manipulates the passed array winnings, no explicit return
-def parseWinLine(line, site, names, winnings, isTourney):
- #print "parseWinLine: line:",line
- for i in range(len(names)):
- if (line.startswith(names[i].encode("latin-1"))): #found a winner
- if isTourney:
- pos1=line.rfind("collected ")+10
- if (site=="ftp"):
- pos2=line.find(")", pos1)
- elif (site=="ps"):
- pos2=line.find(" ", pos1)
- winnings[i]+=int(line[pos1:pos2])
- else:
- pos1=line.rfind("$")+1
- if (site=="ftp"):
- pos2=line.find(")", pos1)
- elif (site=="ps"):
- pos2=line.find(" ", pos1)
- winnings[i]+=float2int(line[pos1:pos2])
-#end def parseWinLine
-
-#returns the category (as per database) string for the given line
-def recogniseCategory(line):
- if (line.find("Razz")!=-1):
- return "razz"
- elif (line.find("Hold'em")!=-1):
- return "holdem"
- elif (line.find("Omaha")!=-1 and line.find("Hi/Lo")==-1 and line.find("H/L")==-1):
- return "omahahi"
- elif (line.find("Omaha")!=-1 and (line.find("Hi/Lo")!=-1 or line.find("H/L")!=-1)):
- return "omahahilo"
- elif (line.find("Stud")!=-1 and line.find("Hi/Lo")==-1 and line.find("H/L")==-1):
- return "studhi"
- elif (line.find("Stud")!=-1 and (line.find("Hi/Lo")!=-1 or line.find("H/L")!=-1)):
- return "studhilo"
- else:
- raise FpdbError("failed to recognise category, line:"+line)
-#end def recogniseCategory
-
-#returns the int for the gametype_id for the given line
-def recogniseGametypeID(db, cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy
- #if (topline.find("HORSE")!=-1):
- # raise FpdbError("recogniseGametypeID: HORSE is not yet supported.")
-
- #note: the below variable names small_bet and big_bet are misleading, in NL/PL they mean small/big blind
- if isTourney:
- type="tour"
- pos1=topline.find("(")+1
- if (topline[pos1]=="H" or topline[pos1]=="O" or topline[pos1]=="R" or topline[pos1]=="S" or topline[pos1+2]=="C"):
- pos1=topline.find("(", pos1)+1
- pos2=topline.find("/", pos1)
- small_bet=int(topline[pos1:pos2])
- else:
- type="ring"
- pos1=topline.find("$")+1
- pos2=topline.find("/$")
- small_bet=float2int(topline[pos1:pos2])
-
- pos1=pos2+2
- if isTourney:
- pos1-=1
- if (site_id==1): #ftp
- pos2=topline.find(" ", pos1)
- elif (site_id==2): #ps
- pos2=topline.find(")")
-
- if pos2<=pos1:
- pos2=topline.find(")", pos1)
-
- if isTourney:
- big_bet=int(topline[pos1:pos2])
- else:
- big_bet=float2int(topline[pos1:pos2])
-
- if (topline.find("No Limit")!=-1):
- limit_type="nl"
- if (topline.find("Cap No")!=-1):
- limit_type="cn"
- elif (topline.find("Pot Limit")!=-1):
- limit_type="pl"
- if (topline.find("Cap Pot")!=-1):
- limit_type="cp"
- else:
- limit_type="fl"
-
- #print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type
- if (limit_type=="fl"):
- cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
- else:
- cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
- result=cursor.fetchone()
- #print "recgt1 result=",result
- #ret=result[0]
- #print "recgt1 ret=",ret
- #print "tried SELECTing gametypes.id, result:",result
-
- try:
- len(result)
- except TypeError:
- if category=="holdem" or category=="omahahi" or category=="omahahilo":
- base="hold"
- else:
- base="stud"
-
- if category=="holdem" or category=="omahahi" or category=="studhi":
- hiLo='h'
- elif category=="razz":
- hiLo='l'
- else:
- hiLo='s'
-
- if (limit_type=="fl"):
- big_blind=small_bet
- if base=="hold":
- if smallBlindLine==topline:
- raise FpdbError("invalid small blind line")
- elif isTourney:
- pos=smallBlindLine.rfind(" ")+1
- small_blind=int(smallBlindLine[pos:])
- else:
- pos=smallBlindLine.rfind("$")+1
- small_blind=float2int(smallBlindLine[pos:])
- else:
- small_blind=0
- cursor.execute("""INSERT INTO Gametypes
- (siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_blind, big_blind, small_bet, big_bet))
- #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
- else:
- cursor.execute("""INSERT INTO Gametypes
- (siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind
- #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
-
- result=(db.insert_id(),)
- #print "recgt2 result=",result
- #print "created new gametypes.id:",result
-
- #print "recgt3: result=", result
- return result[0]
-#end def recogniseGametypeID
-
-def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon):
- cursor.execute ("SELECT id FROM TourneyTypes WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s", (siteId, buyin, fee, knockout, rebuyOrAddon))
- result=cursor.fetchone()
- #print "tried SELECTing gametypes.id, result:",result
-
- try:
- len(result)
- except TypeError:#this means we need to create a new entry
- cursor.execute("""INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon) VALUES (%s, %s, %s, %s, %s)""", (siteId, buyin, fee, knockout, rebuyOrAddon))
- cursor.execute("SELECT id FROM TourneyTypes WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s", (siteId, buyin, fee, knockout, rebuyOrAddon))
- result=cursor.fetchone()
- return result[0]
-#end def recogniseTourneyTypeId
-
-#returns the SQL ids of the names given in an array
-def recognisePlayerIDs(cursor, names, site_id):
- result = []
- for i in range (len(names)):
- cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
- tmp=cursor.fetchall()
- if (len(tmp)==0): #new player
- cursor.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (names[i], site_id))
- #print "Number of players rows inserted: %d" % cursor.rowcount
- cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
- tmp=cursor.fetchall()
- #print "recognisePlayerIDs, names[i]:",names[i],"tmp:",tmp
- result.append(tmp[0][0])
- return result
-#end def recognisePlayerIDs
-
-#recognises the name in the given line and returns its array position in the given array
-def recognisePlayerNo(line, names, atype):
- #print "recogniseplayerno, names:",names
- for i in range (len(names)):
- if (atype=="unbet"):
- if (line.endswith(names[i].encode("latin-1"))):
- return (i)
- elif (line.startswith("Dealt to ")):
- #print "recognisePlayerNo, card precut, line:",line
- tmp=line[9:]
- #print "recognisePlayerNo, card postcut, tmp:",tmp
- if (tmp.startswith(names[i].encode("latin-1"))):
- return (i)
- elif (line.startswith("Seat ")):
- if (line.startswith("Seat 10")):
- tmp=line[9:]
- else:
- tmp=line[8:]
-
- if (tmp.startswith(names[i].encode("latin-1"))):
- return (i)
- else:
- if (line.startswith(names[i].encode("latin-1"))):
- return (i)
- #if we're here we mustve failed
- raise FpdbError ("failed to recognise player in: "+line+" atype:"+atype)
-#end def recognisePlayerNo
-
-#returns the site abbreviation for the given site
-def recogniseSite(line):
- if (line.startswith("Full Tilt Poker")):
- return "ftp"
- elif (line.startswith("PokerStars")):
- return "ps"
- else:
- raise FpdbError("failed to recognise site, line:"+line)
-#end def recogniseSite
-
-#returns the ID of the given site
-def recogniseSiteID(cursor, site):
- if (site=="ftp"):
- return 1
- #cursor.execute("SELECT id FROM Sites WHERE name = ('Full Tilt Poker')")
- elif (site=="ps"):
- return 2
- #cursor.execute("SELECT id FROM Sites WHERE name = ('PokerStars')")
- else:
- raise FpdbError("invalid site in recogniseSiteID: "+site)
- return cursor.fetchall()[0][0]
-#end def recogniseSiteID
-
-#removes trailing \n from the given array
-def removeTrailingEOL(arr):
- for i in range(len(arr)):
- if (arr[i].endswith("\n")):
- #print "arr[i] before removetrailingEOL:", arr[i]
- arr[i]=arr[i][:-1]
- #print "arr[i] after removetrailingEOL:", arr[i]
- return arr
-#end def removeTrailingEOL
-
-#splits the rake according to the proportion of pot won. manipulates the second passed array.
-def splitRake(winnings, rakes, totalRake):
- winnercnt=0
- totalWin=0
- for i in range(len(winnings)):
- if winnings[i]!=0:
- winnercnt+=1
- totalWin+=winnings[i]
- firstWinner=i
- if winnercnt==1:
- rakes[firstWinner]=totalRake
- else:
- totalWin=float(totalWin)
- for i in range(len(winnings)):
- if winnings[i]!=0:
- winPortion=winnings[i]/totalWin
- rakes[i]=totalRake*winPortion
-#end def splitRake
-
-def storeActions(cursor, handsPlayersIds, actionTypes, allIns, actionAmounts, actionNos):
-#stores into table hands_actions
- #print "start of storeActions, actionNos:",actionNos
- #print " action_amounts:",action_amounts
- for i in range (len(actionTypes)): #iterate through streets
- for j in range (len(actionTypes[i])): #iterate through names
- for k in range (len(actionTypes[i][j])): #iterate through individual actions of that player on that street
- cursor.execute ("INSERT INTO HandsActions (handPlayerId, street, actionNo, action, allIn, amount) VALUES (%s, %s, %s, %s, %s, %s)"
- , (handsPlayersIds[j], i, actionNos[i][j][k], actionTypes[i][j][k], allIns[i][j][k], actionAmounts[i][j][k]))
-#end def storeActions
-
-def store_board_cards(cursor, hands_id, board_values, board_suits):
-#stores into table board_cards
- cursor.execute ("""INSERT INTO BoardCards (handId, card1Value, card1Suit,
- card2Value, card2Suit, card3Value, card3Suit, card4Value, card4Suit,
- card5Value, card5Suit) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
- (hands_id, board_values[0], board_suits[0], board_values[1], board_suits[1],
- board_values[2], board_suits[2], board_values[3], board_suits[3],
- board_values[4], board_suits[4]))
-#end def store_board_cards
-
-def storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats):
-#stores into table hands
- cursor.execute ("INSERT INTO Hands (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats) VALUES (%s, %s, %s, %s, %s, %s, %s)", (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.datetime.today(), maxSeats))
- #todo: find a better way of doing this...
- #cursor.execute("SELECT id FROM Hands WHERE siteHandNo=%s AND gametypeId=%s", (site_hand_no, gametype_id))
- #return cursor.fetchall()[0][0]
- return db.insert_id() # mysql only
-#end def storeHands
-
-def store_hands_players_holdem_omaha(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos):
- result=[]
- if (category=="holdem"):
- for i in range (len(player_ids)):
- cursor.execute ("""
- INSERT INTO HandsPlayers
- (handId, playerId, startCash, position,
- card1Value, card1Suit, card2Value, card2Suit, winnings, rake, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], positions[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- winnings[i], rakes[i], seatNos[i]))
- #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
- #result.append(cursor.fetchall()[0][0])
- result.append( db.insert_id() ) # mysql only
- elif (category=="omahahi" or category=="omahahilo"):
- for i in range (len(player_ids)):
- cursor.execute ("""INSERT INTO HandsPlayers
- (handId, playerId, startCash, position,
- card1Value, card1Suit, card2Value, card2Suit,
- card3Value, card3Suit, card4Value, card4Suit, winnings, rake, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], positions[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
- winnings[i], rakes[i], seatNos[i]))
- #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
- #result.append(cursor.fetchall()[0][0])
- result.append( db.insert_id() ) # mysql only
- else:
- raise FpdbError("invalid category")
- return result
-#end def store_hands_players_holdem_omaha
-
-def store_hands_players_stud(db, cursor, hands_id, player_ids, start_cashes, antes,
- card_values, card_suits, winnings, rakes, seatNos):
-#stores hands_players rows for stud/razz games. returns an array of the resulting IDs
- result=[]
- #print "before inserts in store_hands_players_stud, antes:", antes
- for i in range (len(player_ids)):
- cursor.execute ("""INSERT INTO HandsPlayers
- (handId, playerId, startCash, ante,
- card1Value, card1Suit, card2Value, card2Suit,
- card3Value, card3Suit, card4Value, card4Suit,
- card5Value, card5Suit, card6Value, card6Suit,
- card7Value, card7Suit, winnings, rake, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
- %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], antes[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
- card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
- card_values[i][6], card_suits[i][6], winnings[i], rakes[i], seatNos[i]))
- #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
- #result.append(cursor.fetchall()[0][0])
- result.append( db.insert_id() ) # mysql only
- return result
-#end def store_hands_players_stud
-
-def store_hands_players_holdem_omaha_tourney(db, cursor, category, hands_id, player_ids,
- start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
-#stores hands_players for tourney holdem/omaha hands
- result=[]
- for i in range (len(player_ids)):
- if len(card_values[0])==2:
- cursor.execute ("""INSERT INTO HandsPlayers
- (handId, playerId, startCash, position,
- card1Value, card1Suit, card2Value, card2Suit,
- winnings, rake, tourneysPlayersId, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], positions[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
- elif len(card_values[0])==4:
- cursor.execute ("""INSERT INTO HandsPlayers
- (handId, playerId, startCash, position,
- card1Value, card1Suit, card2Value, card2Suit,
- card3Value, card3Suit, card4Value, card4Suit,
- winnings, rake, tourneysPlayersId, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], positions[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
- winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
- else:
- raise FpdbError ("invalid card_values length:"+str(len(card_values[0])))
- #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
- #result.append(cursor.fetchall()[0][0])
- result.append( db.insert_id() ) # mysql only
-
- return result
-#end def store_hands_players_holdem_omaha_tourney
-
-def store_hands_players_stud_tourney(db, cursor, hands_id, player_ids, start_cashes,
- antes, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
-#stores hands_players for tourney stud/razz hands
- result=[]
- for i in range (len(player_ids)):
- cursor.execute ("""INSERT INTO HandsPlayers
- (handId, playerId, startCash, ante,
- card1Value, card1Suit, card2Value, card2Suit,
- card3Value, card3Suit, card4Value, card4Suit,
- card5Value, card5Suit, card6Value, card6Suit,
- card7Value, card7Suit, winnings, rake, tourneysPlayersId, seatNo)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
- %s, %s, %s, %s, %s, %s)""",
- (hands_id, player_ids[i], start_cashes[i], antes[i],
- card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
- card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
- card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
- card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
- #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
- #result.append(cursor.fetchall()[0][0])
- result.append( db.insert_id() ) # mysql only
- return result
-#end def store_hands_players_stud_tourney
-
-def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo
- ,winnings, totalWinnings, positions, actionTypes, actionAmounts):
- """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_3B4BChance=[]
- street0_3B4BDone=[]
- street1Seen=[]
- street2Seen=[]
- street3Seen=[]
- street4Seen=[]
- sawShowdown=[]
- street1Aggr=[]
- street2Aggr=[]
- street3Aggr=[]
- street4Aggr=[]
- otherRaisedStreet1=[]
- otherRaisedStreet2=[]
- otherRaisedStreet3=[]
- otherRaisedStreet4=[]
- foldToOtherRaisedStreet1=[]
- foldToOtherRaisedStreet2=[]
- foldToOtherRaisedStreet3=[]
- foldToOtherRaisedStreet4=[]
- wonWhenSeenStreet1=[]
-
- wonAtSD=[]
- stealAttemptChance=[]
- stealAttempted=[]
- hudDataPositions=[]
-
- firstPfRaiseByNo=-1
- firstPfRaiserId=-1
- firstPfRaiserNo=-1
- firstPfCallByNo=-1
- firstPfCallerId=-1
- for i in range(len(actionTypeByNo[0])):
- if actionTypeByNo[0][i][1]=="bet":
- firstPfRaiseByNo=i
- firstPfRaiserId=actionTypeByNo[0][i][0]
- for j in range(len(player_ids)):
- if player_ids[j]==firstPfRaiserId:
- firstPfRaiserNo=j
- break
- break
- for i in range(len(actionTypeByNo[0])):
- if actionTypeByNo[0][i][1]=="call":
- firstPfCallByNo=i
- firstPfCallerId=actionTypeByNo[0][i][0]
- break
-
- cutoffId=-1
- buttonId=-1
- sbId=-1
- bbId=-1
- if base=="hold":
- for player in range(len(positions)):
- if positions==1:
- cutoffId=player_ids[player]
- if positions==0:
- buttonId=player_ids[player]
- if positions=='S':
- sbId=player_ids[player]
- if positions=='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 range (len(player_ids)):
- #set default values
- myStreet0VPI=False
- myStreet0Aggr=False
- myStreet0_3B4BChance=False
- myStreet0_3B4BDone=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
-
- #calculate VPIP and PFR
- street=0
- heroPfRaiseCount=0
- for count in range (len(action_types[street][player])):#finally individual actions
- currentAction=action_types[street][player][count]
- if currentAction=="bet":
- myStreet0Aggr=True
- if (currentAction=="bet" or currentAction=="call"):
- myStreet0VPI=True
-
- #PF3B4BChance and PF3B4B
- pfFold=-1
- pfRaise=-1
- if firstPfRaiseByNo!=-1:
- for i in range(len(actionTypeByNo[0])):
- if actionTypeByNo[0][i][0]==player_ids[player]:
- if actionTypeByNo[0][i][1]=="bet" and pfRaise==-1 and i>firstPfRaiseByNo:
- pfRaise=i
- if actionTypeByNo[0][i][1]=="fold" and pfFold==-1:
- pfFold=i
- if pfFold==-1 or pfFold>firstPfRaiseByNo:
- myStreet0_3B4BChance=True
- if pfRaise>firstPfRaiseByNo:
- myStreet0_3B4BDone=True
-
- #steal calculations
- if base=="hold":
- if len(player_ids)>=5: #no point otherwise
- if positions[player]==1:
- if firstPfRaiserId==player_ids[player]:
- myStealAttemptChance=True
- myStealAttempted=True
- elif firstPfRaiserId==buttonId or firstPfRaiserId==sbId or firstPfRaiserId==bbId or firstPfRaiserId==-1:
- myStealAttemptChance=True
- if positions[player]==0:
- if firstPfRaiserId==player_ids[player]:
- myStealAttemptChance=True
- myStealAttempted=True
- elif firstPfRaiserId==sbId or firstPfRaiserId==bbId or firstPfRaiserId==-1:
- myStealAttemptChance=True
- if positions[player]=='S':
- if firstPfRaiserId==player_ids[player]:
- myStealAttemptChance=True
- myStealAttempted=True
- elif firstPfRaiserId==bbId or firstPfRaiserId==-1:
- myStealAttemptChance=True
- if positions[player]=='B':
- pass
-
- if myStealAttempted:
- someoneStole=True
-
-
- #calculate saw* values
- isAllIn=False
- for i in range(len(allIns[0][player])):
- if allIns[0][player][i]:
- isAllIn=True
- if (len(action_types[1][player])>0 or isAllIn):
- myStreet1Seen=True
-
- for i in range(len(allIns[1][player])):
- if allIns[1][player][i]:
- isAllIn=True
- if (len(action_types[2][player])>0 or isAllIn):
- myStreet2Seen=True
-
- for i in range(len(allIns[2][player])):
- if allIns[2][player][i]:
- isAllIn=True
- if (len(action_types[3][player])>0 or isAllIn):
- myStreet3Seen=True
-
- #print "base:", base
- if base=="hold":
- mySawShowdown=True
- for count in range (len(action_types[3][player])):
- if action_types[3][player][count]=="fold":
- mySawShowdown=False
- else:
- #print "in else"
- for i in range(len(allIns[3][player])):
- if allIns[3][player][i]:
- isAllIn=True
- if (len(action_types[4][player])>0 or isAllIn):
- #print "in if"
- myStreet4Seen=True
-
- mySawShowdown=True
- for count in range (len(action_types[4][player])):
- if action_types[4][player][count]=="fold":
- mySawShowdown=False
-
-
- #flop stuff
- street=1
- if myStreet1Seen:
- for count in range(len(action_types[street][player])):
- if action_types[street][player][count]=="bet":
- myStreet1Aggr=True
-
- for otherPlayer in range (len(player_ids)):
- if player==otherPlayer:
- pass
- else:
- for countOther in range (len(action_types[street][otherPlayer])):
- if action_types[street][otherPlayer][countOther]=="bet":
- myOtherRaisedStreet1=True
- for countOtherFold in range (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:
- for count in range(len(action_types[street][player])):
- if action_types[street][player][count]=="bet":
- myStreet2Aggr=True
-
- for otherPlayer in range (len(player_ids)):
- if player==otherPlayer:
- pass
- else:
- for countOther in range (len(action_types[street][otherPlayer])):
- if action_types[street][otherPlayer][countOther]=="bet":
- myOtherRaisedStreet2=True
- for countOtherFold in range (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:
- for count in range(len(action_types[street][player])):
- if action_types[street][player][count]=="bet":
- myStreet3Aggr=True
-
- for otherPlayer in range (len(player_ids)):
- if player==otherPlayer:
- pass
- else:
- for countOther in range (len(action_types[street][otherPlayer])):
- if action_types[street][otherPlayer][countOther]=="bet":
- myOtherRaisedStreet3=True
- for countOtherFold in range (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:
- for count in range(len(action_types[street][player])):
- if action_types[street][player][count]=="bet":
- myStreet4Aggr=True
-
- for otherPlayer in range (len(player_ids)):
- if player==otherPlayer:
- pass
- else:
- for countOther in range (len(action_types[street][otherPlayer])):
- if action_types[street][otherPlayer][countOther]=="bet":
- myOtherRaisedStreet4=True
- for countOtherFold in range (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_3B4BChance.append(myStreet0_3B4BChance)
- street0_3B4BDone.append(myStreet0_3B4BDone)
- 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<=7:
- 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
-
- #add each array to the to-be-returned dictionary
- result={'street0VPI':street0VPI}
- result['street0Aggr']=street0Aggr
- result['street0_3B4BChance']=street0_3B4BChance
- result['street0_3B4BDone']=street0_3B4BDone
- 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
-
- #now the various steal values
- foldBbToStealChance=[]
- foldedBbToSteal=[]
- foldSbToStealChance=[]
- foldedSbToSteal=[]
- for player in range (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 range (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 range (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 range (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 range (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 range (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 range (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 range (len(player_ids)):
- #print "pl=", pl
- myTotalProfit=winnings[pl] # still need to deduct costs
- for i in range (len(actionTypes)): #iterate through streets
- #for j in range (len(actionTypes[i])): #iterate through names (using pl loop above)
- for k in range (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
-
-def generateFoldToCB(street, playerIDs, didStreetCB, streetCBDone, foldToStreetCBChance, foldToStreetCBDone, actionTypeByNo):
- """fills the passed foldToStreetCB* arrays appropriately depending on the given street"""
- #print "beginning of generateFoldToCB, street:", street, "len(actionTypeByNo):", len(actionTypeByNo)
- #print "len(actionTypeByNo[street]):",len(actionTypeByNo[street])
- firstCBReaction=0
- for action in range(len(actionTypeByNo[street])):
- if actionTypeByNo[street][action][1]=="bet":
- for player in didStreetCB:
- if player==actionTypeByNo[street][action][0] and firstCBReaction==0:
- firstCBReaction=action+1
- break
-
- for action in actionTypeByNo[street][firstCBReaction:]:
- for player in range(len(playerIDs)):
- if playerIDs[player]==action[0]:
- foldToStreetCBChance[player]=True
- if action[1]=="fold":
- foldToStreetCBDone[player]=True
-#end def generateFoldToCB
-
-def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
-# if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
-
- #print "storeHudCache, len(playerIds)=", len(playerIds), " len(vpip)=" \
- #, len(hudImportData['street0VPI']), " len(totprof)=", len(hudImportData['totalProfit'])
- for player in range (len(playerIds)):
- if base=="hold":
- cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player]))
- else:
- cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s", (gametypeId, playerIds[player], len(playerIds)))
- row=cursor.fetchone()
- #print "gametypeId:", gametypeId, "playerIds[player]",playerIds[player], "len(playerIds):",len(playerIds), "row:",row
-
- try: len(row)
- except TypeError:
- row=[]
-
- if (len(row)==0):
- #print "new huddata row"
- doInsert=True
- row=[]
- row.append(0)#blank for id
- row.append(gametypeId)
- row.append(playerIds[player])
- row.append(len(playerIds))#seats
- for i in range(len(hudImportData)+2):
- row.append(0)
-
- else:
- doInsert=False
- newrow=[]
- for i in range(len(row)):
- newrow.append(row[i])
- row=newrow
-
- if base=="hold":
- row[4]=hudImportData['position'][player]
- else:
- row[4]=0
- row[5]=1 #tourneysGametypeId
- row[6]+=1 #HDs
- if hudImportData['street0VPI'][player]: row[7]+=1
- if hudImportData['street0Aggr'][player]: row[8]+=1
- if hudImportData['street0_3B4BChance'][player]: row[9]+=1
- if hudImportData['street0_3B4BDone'][player]: row[10]+=1
- if hudImportData['street1Seen'][player]: row[11]+=1
- if hudImportData['street2Seen'][player]: row[12]+=1
- if hudImportData['street3Seen'][player]: row[13]+=1
- if hudImportData['street4Seen'][player]: row[14]+=1
- if hudImportData['sawShowdown'][player]: row[15]+=1
- if hudImportData['street1Aggr'][player]: row[16]+=1
- if hudImportData['street2Aggr'][player]: row[17]+=1
- if hudImportData['street3Aggr'][player]: row[18]+=1
- if hudImportData['street4Aggr'][player]: row[19]+=1
- if hudImportData['otherRaisedStreet1'][player]: row[20]+=1
- if hudImportData['otherRaisedStreet2'][player]: row[21]+=1
- if hudImportData['otherRaisedStreet3'][player]: row[22]+=1
- if hudImportData['otherRaisedStreet4'][player]: row[23]+=1
- if hudImportData['foldToOtherRaisedStreet1'][player]: row[24]+=1
- if hudImportData['foldToOtherRaisedStreet2'][player]: row[25]+=1
- if hudImportData['foldToOtherRaisedStreet3'][player]: row[26]+=1
- if hudImportData['foldToOtherRaisedStreet4'][player]: row[27]+=1
- if hudImportData['wonWhenSeenStreet1'][player]!=0.0: row[28]+=hudImportData['wonWhenSeenStreet1'][player]
- if hudImportData['wonAtSD'][player]!=0.0: row[29]+=hudImportData['wonAtSD'][player]
- if hudImportData['stealAttemptChance'][player]: row[30]+=1
- if hudImportData['stealAttempted'][player]: row[31]+=1
- if hudImportData['foldBbToStealChance'][player]: row[32]+=1
- if hudImportData['foldedBbToSteal'][player]: row[33]+=1
- if hudImportData['foldSbToStealChance'][player]: row[34]+=1
- if hudImportData['foldedSbToSteal'][player]: row[35]+=1
-
- if hudImportData['street1CBChance'][player]: row[36]+=1
- if hudImportData['street1CBDone'][player]: row[37]+=1
- if hudImportData['street2CBChance'][player]: row[38]+=1
- if hudImportData['street2CBDone'][player]: row[39]+=1
- if hudImportData['street3CBChance'][player]: row[40]+=1
- if hudImportData['street3CBDone'][player]: row[41]+=1
- if hudImportData['street4CBChance'][player]: row[42]+=1
- if hudImportData['street4CBDone'][player]: row[43]+=1
-
- if hudImportData['foldToStreet1CBChance'][player]: row[44]+=1
- if hudImportData['foldToStreet1CBDone'][player]: row[45]+=1
- if hudImportData['foldToStreet2CBChance'][player]: row[46]+=1
- if hudImportData['foldToStreet2CBDone'][player]: row[47]+=1
- if hudImportData['foldToStreet3CBChance'][player]: row[48]+=1
- if hudImportData['foldToStreet3CBDone'][player]: row[49]+=1
- if hudImportData['foldToStreet4CBChance'][player]: row[50]+=1
- if hudImportData['foldToStreet4CBDone'][player]: row[51]+=1
-
- #print "player=", player
- #print "len(totalProfit)=", len(hudImportData['totalProfit'])
- if hudImportData['totalProfit'][player]:
- row[52]+=hudImportData['totalProfit'][player]
-
- if hudImportData['street1CheckCallRaiseChance'][player]: row[53]+=1
- if hudImportData['street1CheckCallRaiseDone'][player]: row[54]+=1
- if hudImportData['street2CheckCallRaiseChance'][player]: row[55]+=1
- if hudImportData['street2CheckCallRaiseDone'][player]: row[56]+=1
- if hudImportData['street3CheckCallRaiseChance'][player]: row[57]+=1
- if hudImportData['street3CheckCallRaiseDone'][player]: row[58]+=1
- if hudImportData['street4CheckCallRaiseChance'][player]: row[59]+=1
- if hudImportData['street4CheckCallRaiseDone'][player]: row[60]+=1
-
- if doInsert:
- #print "playerid before insert:",row[2]
- cursor.execute("""INSERT INTO HudCache
- (gametypeId, playerId, activeSeats, position, tourneyTypeId,
- HDs, street0VPI, street0Aggr, street0_3B4BChance, street0_3B4BDone,
- street1Seen, street2Seen, street3Seen, street4Seen, sawShowdown,
- street1Aggr, street2Aggr, street3Aggr, street4Aggr, otherRaisedStreet1,
- otherRaisedStreet2, otherRaisedStreet3, otherRaisedStreet4, foldToOtherRaisedStreet1, foldToOtherRaisedStreet2,
- foldToOtherRaisedStreet3, foldToOtherRaisedStreet4, wonWhenSeenStreet1, wonAtSD, stealAttemptChance,
- stealAttempted, foldBbToStealChance, foldedBbToSteal, foldSbToStealChance, foldedSbToSteal,
- street1CBChance, street1CBDone, street2CBChance, street2CBDone, street3CBChance,
- street3CBDone, street4CBChance, street4CBDone, foldToStreet1CBChance, foldToStreet1CBDone,
- foldToStreet2CBChance, foldToStreet2CBDone, foldToStreet3CBChance, foldToStreet3CBDone, foldToStreet4CBChance,
- foldToStreet4CBDone, totalProfit, street1CheckCallRaiseChance, street1CheckCallRaiseDone, street2CheckCallRaiseChance,
- street2CheckCallRaiseDone, street3CheckCallRaiseChance, street3CheckCallRaiseDone, street4CheckCallRaiseChance, street4CheckCallRaiseDone)
- 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, %s,
- %s, %s, %s, %s, %s)""", (row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19], row[20], row[21], row[22], row[23], row[24], row[25], row[26], row[27], row[28], row[29], row[30], row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40], row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50], row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60]))
- else:
- #print "storing updated hud data line"
- cursor.execute("""UPDATE HudCache
- SET HDs=%s, street0VPI=%s, street0Aggr=%s, street0_3B4BChance=%s, street0_3B4BDone=%s,
- street1Seen=%s, street2Seen=%s, street3Seen=%s, street4Seen=%s, sawShowdown=%s,
- street1Aggr=%s, street2Aggr=%s, street3Aggr=%s, street4Aggr=%s, otherRaisedStreet1=%s,
- otherRaisedStreet2=%s, otherRaisedStreet3=%s, otherRaisedStreet4=%s, foldToOtherRaisedStreet1=%s, foldToOtherRaisedStreet2=%s,
- foldToOtherRaisedStreet3=%s, foldToOtherRaisedStreet4=%s, wonWhenSeenStreet1=%s, wonAtSD=%s, stealAttemptChance=%s,
- stealAttempted=%s, foldBbToStealChance=%s, foldedBbToSteal=%s, foldSbToStealChance=%s, foldedSbToSteal=%s,
- street1CBChance=%s, street1CBDone=%s, street2CBChance=%s, street2CBDone=%s, street3CBChance=%s,
- street3CBDone=%s, street4CBChance=%s, street4CBDone=%s, foldToStreet1CBChance=%s, foldToStreet1CBDone=%s,
- foldToStreet2CBChance=%s, foldToStreet2CBDone=%s, foldToStreet3CBChance=%s, foldToStreet3CBDone=%s, foldToStreet4CBChance=%s,
- foldToStreet4CBDone=%s, totalProfit=%s, street1CheckCallRaiseChance=%s, street1CheckCallRaiseDone=%s, street2CheckCallRaiseChance=%s,
- street2CheckCallRaiseDone=%s, street3CheckCallRaiseChance=%s, street3CheckCallRaiseDone=%s, street4CheckCallRaiseChance=%s, street4CheckCallRaiseDone=%s
- WHERE gametypeId=%s AND playerId=%s AND activeSeats=%s AND position=%s AND tourneyTypeId=%s""", (row[6], row[7], row[8], row[9], row[10],
- row[11], row[12], row[13], row[14], row[15],
- row[16], row[17], row[18], row[19], row[20],
- row[21], row[22], row[23], row[24], row[25],
- row[26], row[27], row[28], row[29], row[30],
- row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40],
- row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50],
- row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60],
- row[1], row[2], row[3], str(row[4]), row[5]))
-# else:
-# print "todo: implement storeHudCache for stud base"
-#end def storeHudCache
-
-def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime):
- cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
- tmp=cursor.fetchone()
- #print "tried SELECTing tourneys.id, result:",tmp
-
- try:
- len(tmp)
- except TypeError:#means we have to create new one
- cursor.execute("""INSERT INTO Tourneys
- (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)
- VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime))
- cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
- tmp=cursor.fetchone()
- #print "created new tourneys.id:",tmp
- return tmp[0]
-#end def store_tourneys
-
-def store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings):
- result=[]
- #print "in store_tourneys_players. tourney_id:",tourney_id
- #print "player_ids:",player_ids
- #print "payin_amounts:",payin_amounts
- #print "ranks:",ranks
- #print "winnings:",winnings
- for i in range (len(player_ids)):
- cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", (tourney_id, player_ids[i]))
- tmp=cursor.fetchone()
- #print "tried SELECTing tourneys_players.id:",tmp
-
- try:
- len(tmp)
- except TypeError:
- cursor.execute("""INSERT INTO TourneysPlayers
- (tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""",
- (tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i]))
-
- cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s",
- (tourney_id, player_ids[i]))
- tmp=cursor.fetchone()
- #print "created new tourneys_players.id:",tmp
- result.append(tmp[0])
- return result
-#end def store_tourneys_players
+#!/usr/bin/python
+
+#Copyright 2008 Steffen Jobbagy-Felso
+#This program is free software: you can redistribute it and/or modify
+#it under the terms of the GNU Affero General Public License as published by
+#the Free Software Foundation, version 3 of the License.
+#
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+#GNU General Public License for more details.
+#
+#You should have received a copy of the GNU Affero General Public License
+#along with this program. If not, see .
+#In the "official" distribution you can find the license in
+#agpl-3.0.txt in the docs folder of the package.
+
+#This file contains simple functions for fpdb
+
+import datetime
+import re
+
+PS=1
+FTP=2
+
+MYSQL_INNODB=2
+PGSQL=3
+SQLITE=4
+
+
+class DuplicateError(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+class FpdbError(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+# gets value for last auto-increment key generated
+# returns -1 if a problem occurs
+def getLastInsertId(backend, conn, cursor):
+ if backend == MYSQL_INNODB:
+ ret = conn.insert_id()
+ if ret < 1 or ret > 999999999:
+ print "getLastInsertId(): problem fetching insert_id? ret=", ret
+ ret = -1
+ elif backend == PGSQL:
+ # some options:
+ # currval(hands_id_seq) - use name of implicit seq here
+ # lastval() - still needs sequences set up?
+ # insert ... returning is useful syntax (but postgres specific?)
+ # see rules (fancy trigger type things)
+ cursor.execute ("SELECT lastval()")
+ row = cursor.fetchone()
+ if not row:
+ print "getLastInsertId(%s): problem fetching lastval? row=" % seq, row
+ ret = -1
+ else:
+ ret = row[0]
+ elif backend == SQLITE:
+ # don't know how to do this in sqlite
+ print "getLastInsertId(): not coded for sqlite yet"
+ ret = -1
+ else:
+ print "getLastInsertId(): unknown backend ", backend
+ ret = -1
+ return ret
+#end def getLastInsertId
+
+#returns an array of the total money paid. intending to add rebuys/addons here
+def calcPayin(count, buyin, fee):
+ result=[]
+ for i in range(count):
+ result.append (buyin+fee)
+ return result
+#end def calcPayin
+
+def checkPositions(positions):
+ """verifies that these positions are valid"""
+ for i in range (len(positions)):
+ pos=positions[i]
+ try:#todo: use type recognition instead of error
+ if (len(pos)!=1):
+ raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+pos) #dont need to str() here
+ except TypeError:#->not string->is int->fine
+ pass
+
+ ### RHH modified to allow for "position 9" here (pos==9 is when you're a dead hand before the BB
+ if (pos!="B" and pos!="S" and pos!=0 and pos!=1 and pos!=2 and pos!=3 and pos!=4 and pos!=5 and pos!=6 and pos!=7 and pos!=9):
+ raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+str(pos))
+#end def fpdb_simple.checkPositions
+
+#classifies each line for further processing in later code. Manipulates the passed arrays.
+def classifyLines(hand, category, lineTypes, lineStreets):
+ currentStreet="predeal"
+ done=False #set this to true once we reach the last relevant line (the summary, except rake, is all repeats)
+ for i in range (len(hand)):
+ if (done):
+ if (hand[i].find("[")==-1 or hand[i].find("mucked [")==-1):
+ lineTypes.append("ignore")
+ else: #it's storing a mucked card
+ lineTypes.append("cards")
+ elif (hand[i].startswith("Dealt to")):
+ lineTypes.append("cards")
+ elif (i==0):
+ lineTypes.append("header")
+ elif (hand[i].startswith("Seat ") and ((hand[i].find("in chips")!=-1) or (hand[i].find("($")!=-1))):
+ lineTypes.append("name")
+ elif (isActionLine(hand[i])):
+ lineTypes.append("action")
+ if (hand[i].find(" posts ")!=-1 or hand[i].find(" posts the ")!=-1):#need to set this here so the "action" of posting blinds is registered properly
+ currentStreet="preflop"
+ elif (isWinLine(hand[i])):
+ lineTypes.append("win")
+ elif (hand[i].startswith("Total pot ") and hand[i].find("Rake")!=-1):
+ lineTypes.append("rake")
+ done=True
+ elif (hand[i]=="*** SHOW DOWN ***" or hand[i]=="*** SUMMARY ***"):
+ lineTypes.append("ignore")
+ #print "in classifyLine, showdown or summary"
+ elif (hand[i].find(" antes ")!=-1 or hand[i].find(" posts the ante ")!=-1):
+ lineTypes.append("ante")
+ elif (hand[i].startswith("*** FLOP *** [")):
+ lineTypes.append("cards")
+ currentStreet="flop"
+ elif (hand[i].startswith("*** TURN *** [")):
+ lineTypes.append("cards")
+ currentStreet="turn"
+ elif (hand[i].startswith("*** RIVER *** [")):
+ lineTypes.append("cards")
+ currentStreet="river"
+ elif (hand[i].startswith("*** 3")):
+ lineTypes.append("ignore")
+ currentStreet=0
+ elif (hand[i].startswith("*** 4")):
+ lineTypes.append("ignore")
+ currentStreet=1
+ elif (hand[i].startswith("*** 5")):
+ lineTypes.append("ignore")
+ currentStreet=2
+ elif (hand[i].startswith("*** 6")):
+ lineTypes.append("ignore")
+ currentStreet=3
+ elif (hand[i].startswith("*** 7") or hand[i]=="*** RIVER ***"):
+ lineTypes.append("ignore")
+ currentStreet=4
+ elif (hand[i].find(" shows [")!=-1):
+ lineTypes.append("cards")
+ elif (hand[i].startswith("Table '")):
+ lineTypes.append("table")
+ else:
+ raise FpdbError("unrecognised linetype in:"+hand[i])
+ lineStreets.append(currentStreet)
+#end def classifyLines
+
+def convert3B4B(site, category, limit_type, actionTypes, actionAmounts):
+ """calculates the actual bet amounts in the given amount array and changes it accordingly."""
+ for i in range (len(actionTypes)):
+ for j in range (len(actionTypes[i])):
+ bets=[]
+ for k in range (len(actionTypes[i][j])):
+ if (actionTypes[i][j][k]=="bet"):
+ bets.append((i,j,k))
+ if (len(bets)==2):
+ #print "len(bets) 2 or higher, need to correct it. bets:",bets,"len:",len(bets)
+ amount2=actionAmounts[bets[1][0]][bets[1][1]][bets[1][2]]
+ amount1=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]
+ actionAmounts[bets[1][0]][bets[1][1]][bets[1][2]]=amount2-amount1
+ elif (len(bets)>2):
+ fail=True
+ #todo: run correction for below
+ if (site=="ps" and category=="holdem" and limit_type=="nl" and len(bets)==3):
+ fail=False
+ if (site=="ftp" and category=="omahahi" and limit_type=="pl" and len(bets)==3):
+ fail=False
+
+ if fail:
+ print "len(bets)>2 in convert3B4B, i didnt think this is possible. i:",i,"j:",j,"k:",k
+ print "actionTypes:",actionTypes
+ raise FpdbError ("too many bets in convert3B4B")
+ #print "actionAmounts postConvert",actionAmounts
+#end def convert3B4B(actionTypes, actionAmounts)
+
+#Corrects the bet amount if the player had to pay blinds
+def convertBlindBet(actionTypes, actionAmounts):
+ i=0#setting street to pre-flop
+ for j in range (len(actionTypes[i])):#playerloop
+ blinds=[]
+ bets=[]
+ for k in range (len(actionTypes[i][j])):
+ if (actionTypes[i][j][k]=="blind"):
+ blinds.append((i,j,k))
+
+ if (len(blinds)>0 and actionTypes[i][j][k]=="bet"):
+ bets.append((i,j,k))
+ if (len(bets)==1):
+ blind_amount=actionAmounts[blinds[0][0]][blinds[0][1]][blinds[0][2]]
+ bet_amount=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]
+ actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]=bet_amount-blind_amount
+#end def convertBlindBet
+
+#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
+#todo: make this use convertCardValuesBoard
+def convertCardValues(arr):
+ for i in range (len(arr)):
+ for j in range (len(arr[i])):
+ if (arr[i][j]=="A"):
+ arr[i][j]=14
+ elif (arr[i][j]=="K"):
+ arr[i][j]=13
+ elif (arr[i][j]=="Q"):
+ arr[i][j]=12
+ elif (arr[i][j]=="J"):
+ arr[i][j]=11
+ elif (arr[i][j]=="T"):
+ arr[i][j]=10
+ else:
+ arr[i][j]=int(arr[i][j])
+#end def convertCardValues
+
+#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
+def convertCardValuesBoard(arr):
+ for i in range (len(arr)):
+ if (arr[i]=="A"):
+ arr[i]=14
+ elif (arr[i]=="K"):
+ arr[i]=13
+ elif (arr[i]=="Q"):
+ arr[i]=12
+ elif (arr[i]=="J"):
+ arr[i]=11
+ elif (arr[i]=="T"):
+ arr[i]=10
+ else:
+ arr[i]=int(arr[i])
+#end def convertCardValuesBoard
+
+#this creates the 2D/3D arrays. manipulates the passed arrays instead of returning.
+def createArrays(category, seats, card_values, card_suits, antes, winnings, rakes, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
+ for i in range(seats):#create second dimension arrays
+ tmp=[]
+ card_values.append(tmp)
+ tmp=[]
+ card_suits.append(tmp)
+ antes.append(0)
+ winnings.append(0)
+ rakes.append(0)
+
+ if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
+ streetCount=4
+ else:
+ streetCount=5
+
+ for i in range(streetCount): #build the first dimension array, for streets
+ tmp=[]
+ action_types.append(tmp)
+ tmp=[]
+ allIns.append(tmp)
+ tmp=[]
+ action_amounts.append(tmp)
+ tmp=[]
+ actionNos.append(tmp)
+ tmp=[]
+ actionTypeByNo.append(tmp)
+ for j in range (seats): #second dimension arrays: players
+ tmp=[]
+ action_types[i].append(tmp)
+ tmp=[]
+ allIns[i].append(tmp)
+ tmp=[]
+ action_amounts[i].append(tmp)
+ tmp=[]
+ actionNos[i].append(tmp)
+ if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
+ pass
+ elif (category=="razz" or category=="studhi" or category=="studhilo"):#need to fill card arrays.
+ for i in range(seats):
+ for j in range (7):
+ card_values[i].append(0)
+ card_suits[i].append("x")
+ else:
+ raise FpdbError("invalid category")
+#end def createArrays
+
+def fill_board_cards(board_values, board_suits):
+#fill up the two board card arrays
+ while (len(board_values)<5):
+ board_values.append(0)
+ board_suits.append("x")
+#end def fill_board_cards
+
+def fillCardArrays(player_count, base, category, card_values, card_suits):
+ """fills up the two card arrays"""
+ if (category=="holdem"):
+ cardCount=2
+ elif (category=="omahahi" or category=="omahahilo"):
+ cardCount=4
+ elif base=="stud":
+ cardCount=7
+ else:
+ raise fpdb_simple.FpdbError ("invalid category:", category)
+
+ for i in range (player_count):
+ while (len(card_values[i])=1):
+ raise DuplicateError ("dupl")
+#end isAlreadyInDB
+
+def isRebuyOrAddon(topline):
+ """isRebuyOrAddon not implemented yet"""
+ return False
+#end def isRebuyOrAddon
+
+#returns whether the passed topline indicates a tournament or not
+def isTourney(topline):
+ if (topline.find("Tournament")!=-1):
+ return True
+ else:
+ return False
+#end def isTourney
+
+#returns boolean whether the passed line is a win line
+def isWinLine(line):
+ if (line.find("wins the pot")!=-1):
+ return True
+ elif (line.find("ties for the high pot")!=-1):
+ return True
+ elif (line.find("ties for the high main pot")!=-1):
+ return True
+ elif (line.find("ties for the high side pot")!=-1):
+ return True
+ elif (line.find("ties for the low pot")!=-1):
+ return True
+ elif (line.find("ties for the low main pot")!=-1):
+ return True
+ elif (line.find("ties for the low side pot")!=-1):
+ return True
+ elif (line.find("ties for the main pot")!=-1): #for ftp tied main pot of split pot
+ return True
+ elif (line.find("ties for the pot")!=-1): #for ftp tie
+ return True
+ elif (line.find("ties for the side pot")!=-1): #for ftp tied split pots
+ return True
+ elif (line.find("wins side pot #")!=-1): #for ftp multi split pots
+ return True
+ elif (line.find("wins the low main pot")!=-1):
+ return True
+ elif (line.find("wins the low pot")!=-1):
+ return True
+ elif (line.find("wins the low side pot")!=-1):
+ return True
+ elif (line.find("wins the high main pot")!=-1):
+ return True
+ elif (line.find("wins the high pot")!=-1):
+ return True
+ elif (line.find("wins the high side pot")!=-1):
+ return True
+ elif (line.find("wins the main pot")!=-1):
+ return True
+ elif (line.find("wins the side pot")!=-1): #for ftp split pots
+ return True
+ elif (line.find("collected")!=-1):
+ return True
+ else:
+ return False #not raising error here, any unknown line wouldve been detected in isActionLine already
+#end def isWinLine
+
+#returns the amount of cash/chips put into the put in the given action line
+def parseActionAmount(line, atype, site, isTourney):
+ #if (line.endswith(" and is all-in")):
+ # line=line[:-14]
+ #elif (line.endswith(", and is all in")):
+ # line=line[:-15]
+
+ if line.endswith(", and is capped"):#ideally we should recognise this as an all-in if category is capXl
+ line=line[:-15]
+ if line.endswith(" and is capped"):
+ line=line[:-14]
+
+
+ if (atype=="fold"):
+ amount=0
+ elif (atype=="check"):
+ amount=0
+ elif (atype=="unbet" and site=="ftp"):
+ pos1=line.find("$")+1
+ pos2=line.find(" returned to")
+ amount=float2int(line[pos1:pos2])
+ elif (atype=="unbet" and site=="ps"):
+ #print "ps unbet, line:",line
+ pos1=line.find("$")+1
+ if pos1==0:
+ pos1=line.find("(")+1
+ pos2=line.find(")")
+ amount=float2int(line[pos1:pos2])
+ elif (atype=="bet" and site=="ps" and line.find(": raises $")!=-1 and line.find("to $")!=-1):
+ pos=line.find("to $")+4
+ amount=float2int(line[pos:])
+ else:
+ if not isTourney:
+ pos=line.rfind("$")+1
+ #print "parseActionAmount, line:", line, "line[pos:]:", line[pos:]
+ amount=float2int(line[pos:])
+ else:
+ #print "line:"+line+"EOL"
+ pos=line.rfind(" ")+1
+ #print "pos:",pos
+ #print "pos of 20:", line.find("20")
+ amount=int(line[pos:])
+
+ if atype=="unbet":
+ amount*=-1
+ return amount
+#end def parseActionAmount
+
+#doesnt return anything, simply changes the passed arrays action_types and
+# action_amounts. For stud this expects numeric streets (3-7), for
+# holdem/omaha it expects predeal, preflop, flop, turn or river
+def parseActionLine(site, base, isTourney, line, street, playerIDs, names, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
+ if (street=="predeal" or street=="preflop"):
+ street=0
+ elif (street=="flop"):
+ street=1
+ elif (street=="turn"):
+ street=2
+ elif (street=="river"):
+ street=3
+
+ nextActionNo=0
+ for player in range(len(actionNos[street])):
+ for count in range(len(actionNos[street][player])):
+ if actionNos[street][player][count]>=nextActionNo:
+ nextActionNo=actionNos[street][player][count]+1
+
+ line, allIn=goesAllInOnThisLine(line)
+ atype=parseActionType(line)
+ playerno=recognisePlayerNo(line, names, atype)
+ amount=parseActionAmount(line, atype, site, isTourney)
+
+ action_types[street][playerno].append(atype)
+ allIns[street][playerno].append(allIn)
+ action_amounts[street][playerno].append(amount)
+ actionNos[street][playerno].append(nextActionNo)
+ tmp=(playerIDs[playerno], atype)
+ actionTypeByNo[street].append(tmp)
+#end def parseActionLine
+
+def goesAllInOnThisLine(line):
+ """returns whether the player went all-in on this line and removes the all-in text from the line."""
+ isAllIn=False
+ if (line.endswith(" and is all-in")):
+ line=line[:-14]
+ isAllIn=True
+ elif (line.endswith(", and is all in")):
+ line=line[:-15]
+ isAllIn=True
+ return (line, isAllIn)
+#end def goesAllInOnThisLine
+
+#returns the action type code (see table design) of the given action line
+def parseActionType(line):
+ if (line.startswith("Uncalled bet")):
+ return "unbet"
+ elif (line.endswith("folds")):
+ return "fold"
+ elif (line.endswith("checks")):
+ return "check"
+ elif (line.find("calls")!=-1):
+ return "call"
+ elif (line.find("brings in for")!=-1):
+ return "blind"
+ elif (line.find("completes it to")!=-1):
+ return "bet"
+ #todo: what if someone completes instead of bringing in?
+ elif (line.find(" posts $")!=-1):
+ return "blind"
+ elif (line.find(" posts a dead ")!=-1):
+ return "blind"
+ elif (line.find(": posts small blind ")!=-1):
+ return "blind"
+ elif (line.find(" posts the small blind of $")!=-1):
+ return "blind"
+ elif (line.find(": posts big blind ")!=-1):
+ return "blind"
+ elif (line.find(" posts the big blind of $")!=-1):
+ return "blind"
+ elif (line.find(": posts small & big blinds $")!=-1):
+ return "blind"
+ #todo: seperately record voluntary blind payments made to join table out of turn
+ elif (line.find("bets")!=-1):
+ return "bet"
+ elif (line.find("raises")!=-1):
+ return "bet"
+ else:
+ raise FpdbError ("failed to recognise actiontype in parseActionLine in: "+line)
+#end def parseActionType
+
+#parses the ante out of the given line and checks which player paid it, updates antes accordingly.
+def parseAnteLine(line, site, isTourney, names, antes):
+ for i in range(len(names)):
+ if (line.startswith(names[i].encode("latin-1"))): #found the ante'er
+ pos=line.rfind("$")+1
+ if not isTourney:
+ antes[i]+=float2int(line[pos:])
+ else:
+ if line.find("all-in")==-1:
+ pos=line.rfind(" ")+1
+ antes[i]+=int(line[pos:])
+ else:
+ pos1=line.rfind("ante")+5
+ pos2=line.find(" ",pos1)
+ antes[i]+=int(line[pos1:pos2])
+ #print "parseAnteLine line: ", line, "antes[i]", antes[i], "antes", antes
+#end def parseAntes
+
+#returns the buyin of a tourney in cents
+def parseBuyin(topline):
+ pos1=topline.find("$")+1
+ pos2=topline.find("+")
+ return float2int(topline[pos1:pos2])
+#end def parseBuyin
+
+#parses a card line and changes the passed arrays accordingly
+#todo: reorganise this messy method
+def parseCardLine(site, category, street, line, names, cardValues, cardSuits, boardValues, boardSuits):
+ if (line.startswith("Dealt to ") or line.find(" shows [")!=-1 or line.find("mucked [")!=-1):
+ playerNo=recognisePlayerNo(line, names, "card") #anything but unbet will be ok for that string
+
+ pos=line.rfind("[")+1
+ if (category=="holdem"):
+ for i in (pos, pos+3):
+ cardValues[playerNo].append(line[i:i+1])
+ cardSuits[playerNo].append(line[i+1:i+2])
+ if (len(cardValues[playerNo])!=2):
+ if cardValues[playerNo][0]==cardValues[playerNo][2] and cardSuits[playerNo][1]==cardSuits[playerNo][3]: #two tests will do
+ cardValues[playerNo]=cardValues[playerNo][0:2]
+ cardSuits[playerNo]=cardSuits[playerNo][0:2]
+ else:
+ print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
+ raise FpdbError("read too many/too few holecards in parseCardLine")
+ elif (category=="omahahi" or category=="omahahilo"):
+ for i in (pos, pos+3, pos+6, pos+9):
+ cardValues[playerNo].append(line[i:i+1])
+ cardSuits[playerNo].append(line[i+1:i+2])
+ if (len(cardValues[playerNo])!=4):
+ if cardValues[playerNo][0]==cardValues[playerNo][4] and cardSuits[playerNo][3]==cardSuits[playerNo][7]: #two tests will do
+ cardValues[playerNo]=cardValues[playerNo][0:4]
+ cardSuits[playerNo]=cardSuits[playerNo][0:4]
+ else:
+ print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
+ raise FpdbError("read too many/too few holecards in parseCardLine")
+ elif (category=="razz" or category=="studhi" or category=="studhilo"):
+ if (line.find("shows")==-1):
+ #print "parseCardLine(in stud if), street:", street
+ if line[pos+2]=="]": #-> not (hero and 3rd street)
+ cardValues[playerNo][street+2]=line[pos:pos+1]
+ cardSuits[playerNo][street+2]=line[pos+1:pos+2]
+ else:
+ #print "hero card1:", line[pos:pos+2], "hero card2:", line[pos+3:pos+5], "hero card3:", line[pos+6:pos+8],
+ cardValues[playerNo][street]=line[pos:pos+1]
+ cardSuits[playerNo][street]=line[pos+1:pos+2]
+ cardValues[playerNo][street+1]=line[pos+3:pos+4]
+ cardSuits[playerNo][street+1]=line[pos+4:pos+5]
+ cardValues[playerNo][street+2]=line[pos+6:pos+7]
+ cardSuits[playerNo][street+2]=line[pos+7:pos+8]
+ else:
+ #print "parseCardLine(in stud else), street:", street
+ cardValues[playerNo][0]=line[pos:pos+1]
+ cardSuits[playerNo][0]=line[pos+1:pos+2]
+ pos+=3
+ cardValues[playerNo][1]=line[pos:pos+1]
+ cardSuits[playerNo][1]=line[pos+1:pos+2]
+ if street==4:
+ pos=pos=line.rfind("]")-2
+ cardValues[playerNo][6]=line[pos:pos+1]
+ cardSuits[playerNo][6]=line[pos+1:pos+2]
+ #print "cardValues:", cardValues
+ #print "cardSuits:", cardSuits
+ else:
+ print "line:",line,"street:",street
+ raise FpdbError("invalid category")
+ #print "end of parseCardLine/playercards, cardValues:",cardValues
+ elif (line.startswith("*** FLOP ***")):
+ pos=line.find("[")+1
+ for i in (pos, pos+3, pos+6):
+ boardValues.append(line[i:i+1])
+ boardSuits.append(line[i+1:i+2])
+ #print boardValues
+ elif (line.startswith("*** TURN ***") or line.startswith("*** RIVER ***")):
+ pos=line.find("[")+1
+ pos=line.find("[", pos+1)+1
+ boardValues.append(line[pos:pos+1])
+ boardSuits.append(line[pos+1:pos+2])
+ #print boardValues
+ else:
+ raise FpdbError ("unrecognised line:"+line)
+#end def parseCardLine
+
+def parseCashesAndSeatNos(lines, site):
+ """parses the startCashes and seatNos of each player out of the given lines and returns them as a dictionary of two arrays"""
+ cashes = []
+ seatNos = []
+ for i in range (len(lines)):
+ pos2=lines[i].find(":")
+ seatNos.append(int(lines[i][5:pos2]))
+
+ pos1=lines[i].rfind("($")+2
+ if pos1==1: #for tourneys - it's 1 instead of -1 due to adding 2 above
+ pos1=lines[i].rfind("(")+1
+ if (site=="ftp"):
+ pos2=lines[i].rfind(")")
+ elif (site=="ps"):
+ pos2=lines[i].find(" in chips")
+ cashes.append(float2int(lines[i][pos1:pos2]))
+ return {'startCashes':cashes, 'seatNos':seatNos}
+#end def parseCashesAndSeatNos
+
+#returns the buyin of a tourney in cents
+def parseFee(topline):
+ pos1=topline.find("$")+1
+ pos1=topline.find("$",pos1)+1
+ pos2=topline.find(" ", pos1)
+ return float2int(topline[pos1:pos2])
+#end def parsefee
+
+#returns a datetime object with the starttime indicated in the given topline
+def parseHandStartTime(topline, site):
+ #convert x:13:35 to 0x:13:35
+ counter=0
+ while (True):
+ pos=topline.find(" "+str(counter)+":")
+ if (pos!=-1):
+ topline=topline[0:pos+1]+"0"+topline[pos+1:]
+ counter+=1
+ if counter==10: break
+
+ isUTC=False
+ if site=="ftp":
+ pos = topline.find(" ", len(topline)-26)+1
+ tmp = topline[pos:]
+ #print "year:", tmp[14:18], "month", tmp[19:21], "day", tmp[22:24], "hour", tmp[0:2], "minute", tmp[3:5], "second", tmp[6:8]
+ result = datetime.datetime(int(tmp[14:18]), int(tmp[19:21]), int(tmp[22:24]), int(tmp[0:2]), int(tmp[3:5]), int(tmp[6:8]))
+ elif site=="ps":
+ if topline.find("UTC")!=-1:
+ pos1 = topline.find("-")+2
+ pos2 = topline.find("UTC")
+ tmp=topline[pos1:pos2]
+ isUTC=True
+ else:
+ tmp=topline[-30:]
+ #print "parsehandStartTime, tmp:", tmp
+ pos = tmp.find("-")+2
+ tmp = tmp[pos:]
+ #Need to match either
+ # 2008/09/07 06:23:14 ET or
+ # 2008/08/17 - 01:14:43 (ET)
+ m = re.match('(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P
[0-9]{2}):(?P[0-9]{2}):(?P[0-9]{2})',tmp)
+ #print "year:", int(m.group('YEAR')), "month", int(m.group('MON')), "day", int(m.group('DAY')), "hour", int(m.group('HR')), "minute", int(m.group('MIN')), "second", int(m.group('SEC'))
+ result = datetime.datetime(int(m.group('YEAR')), int(m.group('MON')), int(m.group('DAY')), int(m.group('HR')), int(m.group('MIN')), int(m.group('SEC')))
+ else:
+ raise FpdbError("invalid site in parseHandStartTime")
+
+ if (site=="ftp" or site=="ps") and not isUTC: #these use US ET
+ result+=datetime.timedelta(hours=5)
+
+ return result
+#end def parseHandStartTime
+
+#parses the names out of the given lines and returns them as an array
+def parseNames(lines):
+ result = []
+ for i in range (len(lines)):
+ pos1=lines[i].find(":")+2
+ pos2=lines[i].rfind("(")-1
+ tmp=lines[i][pos1:pos2]
+ #print "parseNames, tmp original:",tmp
+ tmp=unicode(tmp,"latin-1")
+ #print "parseNames, tmp after unicode latin-1 conversion:",tmp
+ result.append(tmp)
+ return result
+#end def parseNames
+
+#returns an array with the positions of the respective players
+def parsePositions (hand, names):
+ #prep array
+ positions=[]
+ for i in range(len(names)):
+ positions.append(-1)
+
+ #find blinds
+ sb,bb=-1,-1
+ for i in range (len(hand)):
+ if (sb==-1 and hand[i].find("small blind")!=-1 and hand[i].find("dead small blind")==-1):
+ sb=hand[i]
+ #print "sb:",sb
+ if (bb==-1 and hand[i].find("big blind")!=-1 and hand[i].find("dead big blind")==-1):
+ bb=hand[i]
+ #print "bb:",bb
+
+ #identify blinds
+ #print "parsePositions before recognising sb/bb. names:",names
+ sbExists=True
+ if (sb!=-1):
+ sb=recognisePlayerNo(sb, names, "bet")
+ else:
+ sbExists=False
+ if (bb!=-1):
+ bb=recognisePlayerNo(bb, names, "bet")
+
+ #write blinds into array
+ if (sbExists):
+ positions[sb]="S"
+ positions[bb]="B"
+
+ #fill up rest of array
+ if (sbExists):
+ arraypos=sb-1
+ else:
+ arraypos=bb-1
+ distFromBtn=0
+ while (arraypos>=0 and arraypos != bb):
+ #print "parsePositions first while, arraypos:",arraypos,"positions:",positions
+ positions[arraypos]=distFromBtn
+ arraypos-=1
+ distFromBtn+=1
+
+ ### RHH - Changed to set the null seats before BB to "9"
+ i=bb-1
+ while positions[i] < 0:
+ positions[i]=9
+ i-=1
+
+ arraypos=len(names)-1
+ if (bb!=0 or (bb==0 and sbExists==False)):
+ while (arraypos>bb):
+ positions[arraypos]=distFromBtn
+ arraypos-=1
+ distFromBtn+=1
+
+ for i in range (len(names)):
+ if positions[i]==-1:
+ print "parsePositions names:",names
+ print "result:",positions
+ raise FpdbError ("failed to read positions")
+ return positions
+#end def parsePositions
+
+#simply parses the rake amount and returns it as an int
+def parseRake(line):
+ pos=line.find("Rake")+6
+ rake=float2int(line[pos:])
+ return rake
+#end def parseRake
+
+def parseSiteHandNo(topline):
+ """returns the hand no assigned by the poker site"""
+ pos1=topline.find("#")+1
+ pos2=topline.find(":")
+ return topline[pos1:pos2]
+#end def parseSiteHandNo
+
+def parseTableLine(site, base, line):
+ """returns a dictionary with maxSeats and tableName"""
+ if site=="ps":
+ pos1=line.find('\'')+1
+ pos2=line.find('\'', pos1)
+ #print "table:",line[pos1:pos2]
+ pos3=pos2+2
+ pos4=line.find("-max")
+ #print "seats:",line[pos3:pos4]
+ return {'maxSeats':int(line[pos3:pos4]), 'tableName':line[pos1:pos2]}
+ elif site=="ftp":
+ pos1=line.find("Table ")+6
+ pos2=line.find("-")-1
+ if base=="hold":
+ maxSeats=9
+ elif base=="stud":
+ maxSeats=8
+
+ if line.find("6 max")!=-1:
+ maxSeats=6
+ elif line.find("4 max")!=-1:
+ maxSeats=4
+ elif line.find("heads up")!=-1:
+ maxSeats=2
+
+ return {'maxSeats':maxSeats, 'tableName':line[pos1:pos2]}
+ else:
+ raise FpdbError("invalid site ID")
+#end def parseTableLine
+
+#returns the hand no assigned by the poker site
+def parseTourneyNo(topline):
+ pos1=topline.find("Tournament #")+12
+ pos2=topline.find(",", pos1)
+ #print "parseTourneyNo pos1:",pos1," pos2:",pos2, " result:",topline[pos1:pos2]
+ return topline[pos1:pos2]
+#end def parseTourneyNo
+
+#parses a win/collect line. manipulates the passed array winnings, no explicit return
+def parseWinLine(line, site, names, winnings, isTourney):
+ #print "parseWinLine: line:",line
+ for i in range(len(names)):
+ if (line.startswith(names[i].encode("latin-1"))): #found a winner
+ if isTourney:
+ pos1=line.rfind("collected ")+10
+ if (site=="ftp"):
+ pos2=line.find(")", pos1)
+ elif (site=="ps"):
+ pos2=line.find(" ", pos1)
+ winnings[i]+=int(line[pos1:pos2])
+ else:
+ pos1=line.rfind("$")+1
+ if (site=="ftp"):
+ pos2=line.find(")", pos1)
+ elif (site=="ps"):
+ pos2=line.find(" ", pos1)
+ winnings[i]+=float2int(line[pos1:pos2])
+#end def parseWinLine
+
+#returns the category (as per database) string for the given line
+def recogniseCategory(line):
+ if (line.find("Razz")!=-1):
+ return "razz"
+ elif (line.find("Hold'em")!=-1):
+ return "holdem"
+ elif (line.find("Omaha")!=-1 and line.find("Hi/Lo")==-1 and line.find("H/L")==-1):
+ return "omahahi"
+ elif (line.find("Omaha")!=-1 and (line.find("Hi/Lo")!=-1 or line.find("H/L")!=-1)):
+ return "omahahilo"
+ elif (line.find("Stud")!=-1 and line.find("Hi/Lo")==-1 and line.find("H/L")==-1):
+ return "studhi"
+ elif (line.find("Stud")!=-1 and (line.find("Hi/Lo")!=-1 or line.find("H/L")!=-1)):
+ return "studhilo"
+ else:
+ raise FpdbError("failed to recognise category, line:"+line)
+#end def recogniseCategory
+
+#returns the int for the gametype_id for the given line
+def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy
+ #if (topline.find("HORSE")!=-1):
+ # raise FpdbError("recogniseGametypeID: HORSE is not yet supported.")
+
+ #note: the below variable names small_bet and big_bet are misleading, in NL/PL they mean small/big blind
+ if isTourney:
+ type="tour"
+ pos1=topline.find("(")+1
+ if (topline[pos1]=="H" or topline[pos1]=="O" or topline[pos1]=="R" or topline[pos1]=="S" or topline[pos1+2]=="C"):
+ pos1=topline.find("(", pos1)+1
+ pos2=topline.find("/", pos1)
+ small_bet=int(topline[pos1:pos2])
+ else:
+ type="ring"
+ pos1=topline.find("$")+1
+ pos2=topline.find("/$")
+ small_bet=float2int(topline[pos1:pos2])
+
+ pos1=pos2+2
+ if isTourney:
+ pos1-=1
+ if (site_id==1): #ftp
+ pos2=topline.find(" ", pos1)
+ elif (site_id==2): #ps
+ pos2=topline.find(")")
+
+ if pos2<=pos1:
+ pos2=topline.find(")", pos1)
+
+ if isTourney:
+ big_bet=int(topline[pos1:pos2])
+ else:
+ big_bet=float2int(topline[pos1:pos2])
+
+ if (topline.find("No Limit")!=-1):
+ limit_type="nl"
+ if (topline.find("Cap No")!=-1):
+ limit_type="cn"
+ elif (topline.find("Pot Limit")!=-1):
+ limit_type="pl"
+ if (topline.find("Cap Pot")!=-1):
+ limit_type="cp"
+ else:
+ limit_type="fl"
+
+ #print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type
+ if (limit_type=="fl"):
+ cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
+ else:
+ cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
+ result=cursor.fetchone()
+ #print "recgt1 result=",result
+ #ret=result[0]
+ #print "recgt1 ret=",ret
+ #print "tried SELECTing gametypes.id, result:",result
+
+ try:
+ len(result)
+ except TypeError:
+ if category=="holdem" or category=="omahahi" or category=="omahahilo":
+ base="hold"
+ else:
+ base="stud"
+
+ if category=="holdem" or category=="omahahi" or category=="studhi":
+ hiLo='h'
+ elif category=="razz":
+ hiLo='l'
+ else:
+ hiLo='s'
+
+ if (limit_type=="fl"):
+ big_blind=small_bet
+ if base=="hold":
+ if smallBlindLine==topline:
+ raise FpdbError("invalid small blind line")
+ elif isTourney:
+ pos=smallBlindLine.rfind(" ")+1
+ small_blind=int(smallBlindLine[pos:])
+ else:
+ pos=smallBlindLine.rfind("$")+1
+ small_blind=float2int(smallBlindLine[pos:])
+ else:
+ small_blind=0
+ cursor.execute( """INSERT INTO Gametypes(siteId, type, base, category, limitType
+ ,hiLo, smallBlind, bigBlind, smallBet, bigBet)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
+ , (site_id, type, base, category, limit_type, hiLo
+ ,small_blind, big_blind, small_bet, big_bet) )
+ #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s
+ #AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
+ else:
+ cursor.execute( """INSERT INTO Gametypes(siteId, type, base, category, limitType
+ ,hiLo, smallBlind, bigBlind, smallBet, bigBet)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
+ , (site_id, type, base, category, limit_type
+ ,hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind
+ #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s
+ #AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
+
+ #result=(db.insert_id(),)
+ result=(getLastInsertId(backend,db,cursor),)
+
+ return result[0]
+#end def recogniseGametypeID
+
+def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon):
+ cursor.execute ("SELECT id FROM TourneyTypes WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s", (siteId, buyin, fee, knockout, rebuyOrAddon))
+ result=cursor.fetchone()
+ #print "tried SELECTing gametypes.id, result:",result
+
+ try:
+ len(result)
+ except TypeError:#this means we need to create a new entry
+ cursor.execute("""INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon) VALUES (%s, %s, %s, %s, %s)""", (siteId, buyin, fee, knockout, rebuyOrAddon))
+ cursor.execute("SELECT id FROM TourneyTypes WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s", (siteId, buyin, fee, knockout, rebuyOrAddon))
+ result=cursor.fetchone()
+ return result[0]
+#end def recogniseTourneyTypeId
+
+#returns the SQL ids of the names given in an array
+def recognisePlayerIDs(cursor, names, site_id):
+ result = []
+ for i in range (len(names)):
+ cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
+ tmp=cursor.fetchall()
+ if (len(tmp)==0): #new player
+ cursor.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (names[i], site_id))
+ #print "Number of players rows inserted: %d" % cursor.rowcount
+ cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
+ tmp=cursor.fetchall()
+ #print "recognisePlayerIDs, names[i]:",names[i],"tmp:",tmp
+ result.append(tmp[0][0])
+ return result
+#end def recognisePlayerIDs
+
+#recognises the name in the given line and returns its array position in the given array
+def recognisePlayerNo(line, names, atype):
+ #print "recogniseplayerno, names:",names
+ for i in range (len(names)):
+ if (atype=="unbet"):
+ if (line.endswith(names[i].encode("latin-1"))):
+ return (i)
+ elif (line.startswith("Dealt to ")):
+ #print "recognisePlayerNo, card precut, line:",line
+ tmp=line[9:]
+ #print "recognisePlayerNo, card postcut, tmp:",tmp
+ if (tmp.startswith(names[i].encode("latin-1"))):
+ return (i)
+ elif (line.startswith("Seat ")):
+ if (line.startswith("Seat 10")):
+ tmp=line[9:]
+ else:
+ tmp=line[8:]
+
+ if (tmp.startswith(names[i].encode("latin-1"))):
+ return (i)
+ else:
+ if (line.startswith(names[i].encode("latin-1"))):
+ return (i)
+ #if we're here we mustve failed
+ raise FpdbError ("failed to recognise player in: "+line+" atype:"+atype)
+#end def recognisePlayerNo
+
+#returns the site abbreviation for the given site
+def recogniseSite(line):
+ if (line.startswith("Full Tilt Poker")):
+ return "ftp"
+ elif (line.startswith("PokerStars")):
+ return "ps"
+ else:
+ raise FpdbError("failed to recognise site, line:"+line)
+#end def recogniseSite
+
+#returns the ID of the given site
+def recogniseSiteID(cursor, site):
+ if (site=="ftp"):
+ return 1
+ #cursor.execute("SELECT id FROM Sites WHERE name = ('Full Tilt Poker')")
+ elif (site=="ps"):
+ return 2
+ #cursor.execute("SELECT id FROM Sites WHERE name = ('PokerStars')")
+ else:
+ raise FpdbError("invalid site in recogniseSiteID: "+site)
+ return cursor.fetchall()[0][0]
+#end def recogniseSiteID
+
+#removes trailing \n from the given array
+def removeTrailingEOL(arr):
+ for i in range(len(arr)):
+ if (arr[i].endswith("\n")):
+ #print "arr[i] before removetrailingEOL:", arr[i]
+ arr[i]=arr[i][:-1]
+ #print "arr[i] after removetrailingEOL:", arr[i]
+ return arr
+#end def removeTrailingEOL
+
+#splits the rake according to the proportion of pot won. manipulates the second passed array.
+def splitRake(winnings, rakes, totalRake):
+ winnercnt=0
+ totalWin=0
+ for i in range(len(winnings)):
+ if winnings[i]!=0:
+ winnercnt+=1
+ totalWin+=winnings[i]
+ firstWinner=i
+ if winnercnt==1:
+ rakes[firstWinner]=totalRake
+ else:
+ totalWin=float(totalWin)
+ for i in range(len(winnings)):
+ if winnings[i]!=0:
+ winPortion=winnings[i]/totalWin
+ rakes[i]=totalRake*winPortion
+#end def splitRake
+
+def storeActions(cursor, handsPlayersIds, actionTypes, allIns, actionAmounts, actionNos):
+#stores into table hands_actions
+ #print "start of storeActions, actionNos:",actionNos
+ #print " action_amounts:",action_amounts
+ for i in range (len(actionTypes)): #iterate through streets
+ for j in range (len(actionTypes[i])): #iterate through names
+ for k in range (len(actionTypes[i][j])): #iterate through individual actions of that player on that street
+ cursor.execute ("INSERT INTO HandsActions (handPlayerId, street, actionNo, action, allIn, amount) VALUES (%s, %s, %s, %s, %s, %s)"
+ , (handsPlayersIds[j], i, actionNos[i][j][k], actionTypes[i][j][k], allIns[i][j][k], actionAmounts[i][j][k]))
+#end def storeActions
+
+def store_board_cards(cursor, hands_id, board_values, board_suits):
+#stores into table board_cards
+ cursor.execute ("""INSERT INTO BoardCards (handId, card1Value, card1Suit,
+card2Value, card2Suit, card3Value, card3Suit, card4Value, card4Suit,
+card5Value, card5Suit) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+ (hands_id, board_values[0], board_suits[0], board_values[1], board_suits[1],
+ board_values[2], board_suits[2], board_values[3], board_suits[3],
+ board_values[4], board_suits[4]))
+#end def store_board_cards
+
+def storeHands(backend, conn, cursor, site_hand_no, gametype_id
+ ,hand_start_time, names, tableName, maxSeats):
+#stores into table hands
+ cursor.execute ("INSERT INTO Hands (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats) VALUES (%s, %s, %s, %s, %s, %s, %s)", (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.datetime.today(), maxSeats))
+ #todo: find a better way of doing this...
+ #cursor.execute("SELECT id FROM Hands WHERE siteHandNo=%s AND gametypeId=%s", (site_hand_no, gametype_id))
+ #return cursor.fetchall()[0][0]
+ return getLastInsertId(backend, conn, cursor)
+ #return db.insert_id() # mysql only
+#end def storeHands
+
+def store_hands_players_holdem_omaha(backend, conn, cursor, category, hands_id, player_ids, start_cashes
+ ,positions, card_values, card_suits, winnings, rakes, seatNos):
+ result=[]
+ if (category=="holdem"):
+ for i in range (len(player_ids)):
+ cursor.execute ("""
+INSERT INTO HandsPlayers
+(handId, playerId, startCash, position,
+card1Value, card1Suit, card2Value, card2Suit, winnings, rake, seatNo)
+VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], positions[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ winnings[i], rakes[i], seatNos[i]))
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( getLastInsertId(backend, conn, cursor) ) # mysql only
+ elif (category=="omahahi" or category=="omahahilo"):
+ for i in range (len(player_ids)):
+ cursor.execute ("""INSERT INTO HandsPlayers
+(handId, playerId, startCash, position,
+card1Value, card1Suit, card2Value, card2Suit,
+card3Value, card3Suit, card4Value, card4Suit, winnings, rake, seatNo)
+VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], positions[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
+ winnings[i], rakes[i], seatNos[i]))
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( getLastInsertId(backend, conn, cursor) ) # mysql only
+ else:
+ raise FpdbError("invalid category")
+ return result
+#end def store_hands_players_holdem_omaha
+
+def store_hands_players_stud(backend, conn, cursor, hands_id, player_ids, start_cashes, antes,
+ card_values, card_suits, winnings, rakes, seatNos):
+#stores hands_players rows for stud/razz games. returns an array of the resulting IDs
+ result=[]
+ #print "before inserts in store_hands_players_stud, antes:", antes
+ for i in range (len(player_ids)):
+ cursor.execute ("""INSERT INTO HandsPlayers
+(handId, playerId, startCash, ante,
+card1Value, card1Suit, card2Value, card2Suit,
+card3Value, card3Suit, card4Value, card4Suit,
+card5Value, card5Suit, card6Value, card6Suit,
+card7Value, card7Suit, winnings, rake, seatNo)
+VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
+%s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], antes[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
+ card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
+ card_values[i][6], card_suits[i][6], winnings[i], rakes[i], seatNos[i]))
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( getLastInsertId(backend, conn, cursor) ) # mysql only
+ return result
+#end def store_hands_players_stud
+
+def store_hands_players_holdem_omaha_tourney(backend, conn, cursor, category, hands_id, player_ids
+ ,start_cashes, positions, card_values, card_suits
+ , winnings, rakes, seatNos, tourneys_players_ids):
+ #stores hands_players for tourney holdem/omaha hands
+ result=[]
+ for i in range (len(player_ids)):
+ if len(card_values[0])==2:
+ cursor.execute ("""INSERT INTO HandsPlayers
+(handId, playerId, startCash, position,
+card1Value, card1Suit, card2Value, card2Suit,
+winnings, rake, tourneysPlayersId, seatNo)
+VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], positions[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
+ elif len(card_values[0])==4:
+ cursor.execute ("""INSERT INTO HandsPlayers
+(handId, playerId, startCash, position,
+card1Value, card1Suit, card2Value, card2Suit,
+card3Value, card3Suit, card4Value, card4Suit,
+winnings, rake, tourneysPlayersId, seatNo)
+VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], positions[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
+ winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
+ else:
+ raise FpdbError ("invalid card_values length:"+str(len(card_values[0])))
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( getLastInsertId(backend, conn, cursor) ) # mysql only
+
+ return result
+#end def store_hands_players_holdem_omaha_tourney
+
+def store_hands_players_stud_tourney(backend, conn, cursor, hands_id, player_ids, start_cashes,
+ antes, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
+#stores hands_players for tourney stud/razz hands
+ result=[]
+ for i in range (len(player_ids)):
+ cursor.execute ("""INSERT INTO HandsPlayers
+(handId, playerId, startCash, ante,
+card1Value, card1Suit, card2Value, card2Suit,
+card3Value, card3Suit, card4Value, card4Suit,
+card5Value, card5Suit, card6Value, card6Suit,
+card7Value, card7Suit, winnings, rake, tourneysPlayersId, seatNo)
+VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
+%s, %s, %s, %s, %s, %s)""",
+ (hands_id, player_ids[i], start_cashes[i], antes[i],
+ card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
+ card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
+ card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
+ card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
+ #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
+ #result.append(cursor.fetchall()[0][0])
+ result.append( getLastInsertId(backend, conn, cursor) ) # mysql only
+ return result
+#end def store_hands_players_stud_tourney
+
+def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo
+ ,winnings, totalWinnings, positions, actionTypes, actionAmounts):
+ """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_3B4BChance=[]
+ street0_3B4BDone=[]
+ street1Seen=[]
+ street2Seen=[]
+ street3Seen=[]
+ street4Seen=[]
+ sawShowdown=[]
+ street1Aggr=[]
+ street2Aggr=[]
+ street3Aggr=[]
+ street4Aggr=[]
+ otherRaisedStreet1=[]
+ otherRaisedStreet2=[]
+ otherRaisedStreet3=[]
+ otherRaisedStreet4=[]
+ foldToOtherRaisedStreet1=[]
+ foldToOtherRaisedStreet2=[]
+ foldToOtherRaisedStreet3=[]
+ foldToOtherRaisedStreet4=[]
+ wonWhenSeenStreet1=[]
+
+ wonAtSD=[]
+ stealAttemptChance=[]
+ stealAttempted=[]
+ hudDataPositions=[]
+
+ firstPfRaiseByNo=-1
+ firstPfRaiserId=-1
+ firstPfRaiserNo=-1
+ firstPfCallByNo=-1
+ firstPfCallerId=-1
+ for i in range(len(actionTypeByNo[0])):
+ if actionTypeByNo[0][i][1]=="bet":
+ firstPfRaiseByNo=i
+ firstPfRaiserId=actionTypeByNo[0][i][0]
+ for j in range(len(player_ids)):
+ if player_ids[j]==firstPfRaiserId:
+ firstPfRaiserNo=j
+ break
+ break
+ for i in range(len(actionTypeByNo[0])):
+ if actionTypeByNo[0][i][1]=="call":
+ firstPfCallByNo=i
+ firstPfCallerId=actionTypeByNo[0][i][0]
+ break
+
+ cutoffId=-1
+ buttonId=-1
+ sbId=-1
+ bbId=-1
+ if base=="hold":
+ for player in range(len(positions)):
+ if positions==1:
+ cutoffId=player_ids[player]
+ if positions==0:
+ buttonId=player_ids[player]
+ if positions=='S':
+ sbId=player_ids[player]
+ if positions=='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 range (len(player_ids)):
+ #set default values
+ myStreet0VPI=False
+ myStreet0Aggr=False
+ myStreet0_3B4BChance=False
+ myStreet0_3B4BDone=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
+
+ #calculate VPIP and PFR
+ street=0
+ heroPfRaiseCount=0
+ for count in range (len(action_types[street][player])):#finally individual actions
+ currentAction=action_types[street][player][count]
+ if currentAction=="bet":
+ myStreet0Aggr=True
+ if (currentAction=="bet" or currentAction=="call"):
+ myStreet0VPI=True
+
+ #PF3B4BChance and PF3B4B
+ pfFold=-1
+ pfRaise=-1
+ if firstPfRaiseByNo!=-1:
+ for i in range(len(actionTypeByNo[0])):
+ if actionTypeByNo[0][i][0]==player_ids[player]:
+ if actionTypeByNo[0][i][1]=="bet" and pfRaise==-1 and i>firstPfRaiseByNo:
+ pfRaise=i
+ if actionTypeByNo[0][i][1]=="fold" and pfFold==-1:
+ pfFold=i
+ if pfFold==-1 or pfFold>firstPfRaiseByNo:
+ myStreet0_3B4BChance=True
+ if pfRaise>firstPfRaiseByNo:
+ myStreet0_3B4BDone=True
+
+ #steal calculations
+ if base=="hold":
+ if len(player_ids)>=5: #no point otherwise
+ if positions[player]==1:
+ if firstPfRaiserId==player_ids[player]:
+ myStealAttemptChance=True
+ myStealAttempted=True
+ elif firstPfRaiserId==buttonId or firstPfRaiserId==sbId or firstPfRaiserId==bbId or firstPfRaiserId==-1:
+ myStealAttemptChance=True
+ if positions[player]==0:
+ if firstPfRaiserId==player_ids[player]:
+ myStealAttemptChance=True
+ myStealAttempted=True
+ elif firstPfRaiserId==sbId or firstPfRaiserId==bbId or firstPfRaiserId==-1:
+ myStealAttemptChance=True
+ if positions[player]=='S':
+ if firstPfRaiserId==player_ids[player]:
+ myStealAttemptChance=True
+ myStealAttempted=True
+ elif firstPfRaiserId==bbId or firstPfRaiserId==-1:
+ myStealAttemptChance=True
+ if positions[player]=='B':
+ pass
+
+ if myStealAttempted:
+ someoneStole=True
+
+
+ #calculate saw* values
+ isAllIn=False
+ for i in range(len(allIns[0][player])):
+ if allIns[0][player][i]:
+ isAllIn=True
+ if (len(action_types[1][player])>0 or isAllIn):
+ myStreet1Seen=True
+
+ for i in range(len(allIns[1][player])):
+ if allIns[1][player][i]:
+ isAllIn=True
+ if (len(action_types[2][player])>0 or isAllIn):
+ myStreet2Seen=True
+
+ for i in range(len(allIns[2][player])):
+ if allIns[2][player][i]:
+ isAllIn=True
+ if (len(action_types[3][player])>0 or isAllIn):
+ myStreet3Seen=True
+
+ #print "base:", base
+ if base=="hold":
+ mySawShowdown=True
+ for count in range (len(action_types[3][player])):
+ if action_types[3][player][count]=="fold":
+ mySawShowdown=False
+ else:
+ #print "in else"
+ for i in range(len(allIns[3][player])):
+ if allIns[3][player][i]:
+ isAllIn=True
+ if (len(action_types[4][player])>0 or isAllIn):
+ #print "in if"
+ myStreet4Seen=True
+
+ mySawShowdown=True
+ for count in range (len(action_types[4][player])):
+ if action_types[4][player][count]=="fold":
+ mySawShowdown=False
+
+
+ #flop stuff
+ street=1
+ if myStreet1Seen:
+ for count in range(len(action_types[street][player])):
+ if action_types[street][player][count]=="bet":
+ myStreet1Aggr=True
+
+ for otherPlayer in range (len(player_ids)):
+ if player==otherPlayer:
+ pass
+ else:
+ for countOther in range (len(action_types[street][otherPlayer])):
+ if action_types[street][otherPlayer][countOther]=="bet":
+ myOtherRaisedStreet1=True
+ for countOtherFold in range (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:
+ for count in range(len(action_types[street][player])):
+ if action_types[street][player][count]=="bet":
+ myStreet2Aggr=True
+
+ for otherPlayer in range (len(player_ids)):
+ if player==otherPlayer:
+ pass
+ else:
+ for countOther in range (len(action_types[street][otherPlayer])):
+ if action_types[street][otherPlayer][countOther]=="bet":
+ myOtherRaisedStreet2=True
+ for countOtherFold in range (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:
+ for count in range(len(action_types[street][player])):
+ if action_types[street][player][count]=="bet":
+ myStreet3Aggr=True
+
+ for otherPlayer in range (len(player_ids)):
+ if player==otherPlayer:
+ pass
+ else:
+ for countOther in range (len(action_types[street][otherPlayer])):
+ if action_types[street][otherPlayer][countOther]=="bet":
+ myOtherRaisedStreet3=True
+ for countOtherFold in range (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:
+ for count in range(len(action_types[street][player])):
+ if action_types[street][player][count]=="bet":
+ myStreet4Aggr=True
+
+ for otherPlayer in range (len(player_ids)):
+ if player==otherPlayer:
+ pass
+ else:
+ for countOther in range (len(action_types[street][otherPlayer])):
+ if action_types[street][otherPlayer][countOther]=="bet":
+ myOtherRaisedStreet4=True
+ for countOtherFold in range (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_3B4BChance.append(myStreet0_3B4BChance)
+ street0_3B4BDone.append(myStreet0_3B4BDone)
+ 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<=7:
+ 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
+
+ #add each array to the to-be-returned dictionary
+ result={'street0VPI':street0VPI}
+ result['street0Aggr']=street0Aggr
+ result['street0_3B4BChance']=street0_3B4BChance
+ result['street0_3B4BDone']=street0_3B4BDone
+ 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
+
+ #now the various steal values
+ foldBbToStealChance=[]
+ foldedBbToSteal=[]
+ foldSbToStealChance=[]
+ foldedSbToSteal=[]
+ for player in range (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 range (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 range (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 range (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 range (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 range (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 range (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 range (len(player_ids)):
+ #print "pl=", pl
+ myTotalProfit=winnings[pl] # still need to deduct costs
+ for i in range (len(actionTypes)): #iterate through streets
+ #for j in range (len(actionTypes[i])): #iterate through names (using pl loop above)
+ for k in range (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
+
+def generateFoldToCB(street, playerIDs, didStreetCB, streetCBDone, foldToStreetCBChance, foldToStreetCBDone, actionTypeByNo):
+ """fills the passed foldToStreetCB* arrays appropriately depending on the given street"""
+ #print "beginning of generateFoldToCB, street:", street, "len(actionTypeByNo):", len(actionTypeByNo)
+ #print "len(actionTypeByNo[street]):",len(actionTypeByNo[street])
+ firstCBReaction=0
+ for action in range(len(actionTypeByNo[street])):
+ if actionTypeByNo[street][action][1]=="bet":
+ for player in didStreetCB:
+ if player==actionTypeByNo[street][action][0] and firstCBReaction==0:
+ firstCBReaction=action+1
+ break
+
+ for action in actionTypeByNo[street][firstCBReaction:]:
+ for player in range(len(playerIDs)):
+ if playerIDs[player]==action[0]:
+ foldToStreetCBChance[player]=True
+ if action[1]=="fold":
+ foldToStreetCBDone[player]=True
+#end def generateFoldToCB
+
+def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
+# if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
+
+ #print "storeHudCache, len(playerIds)=", len(playerIds), " len(vpip)=" \
+ #, len(hudImportData['street0VPI']), " len(totprof)=", len(hudImportData['totalProfit'])
+ for player in range (len(playerIds)):
+ if base=="hold":
+ cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player]))
+ else:
+ cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s", (gametypeId, playerIds[player], len(playerIds)))
+ row=cursor.fetchone()
+ #print "gametypeId:", gametypeId, "playerIds[player]",playerIds[player], "len(playerIds):",len(playerIds), "row:",row
+
+ try: len(row)
+ except TypeError:
+ row=[]
+
+ if (len(row)==0):
+ #print "new huddata row"
+ doInsert=True
+ row=[]
+ row.append(0)#blank for id
+ row.append(gametypeId)
+ row.append(playerIds[player])
+ row.append(len(playerIds))#seats
+ for i in range(len(hudImportData)+2):
+ row.append(0)
+
+ else:
+ doInsert=False
+ newrow=[]
+ for i in range(len(row)):
+ newrow.append(row[i])
+ row=newrow
+
+ if base=="hold":
+ row[4]=hudImportData['position'][player]
+ else:
+ row[4]=0
+ row[5]=1 #tourneysGametypeId
+ row[6]+=1 #HDs
+ if hudImportData['street0VPI'][player]: row[7]+=1
+ if hudImportData['street0Aggr'][player]: row[8]+=1
+ if hudImportData['street0_3B4BChance'][player]: row[9]+=1
+ if hudImportData['street0_3B4BDone'][player]: row[10]+=1
+ if hudImportData['street1Seen'][player]: row[11]+=1
+ if hudImportData['street2Seen'][player]: row[12]+=1
+ if hudImportData['street3Seen'][player]: row[13]+=1
+ if hudImportData['street4Seen'][player]: row[14]+=1
+ if hudImportData['sawShowdown'][player]: row[15]+=1
+ if hudImportData['street1Aggr'][player]: row[16]+=1
+ if hudImportData['street2Aggr'][player]: row[17]+=1
+ if hudImportData['street3Aggr'][player]: row[18]+=1
+ if hudImportData['street4Aggr'][player]: row[19]+=1
+ if hudImportData['otherRaisedStreet1'][player]: row[20]+=1
+ if hudImportData['otherRaisedStreet2'][player]: row[21]+=1
+ if hudImportData['otherRaisedStreet3'][player]: row[22]+=1
+ if hudImportData['otherRaisedStreet4'][player]: row[23]+=1
+ if hudImportData['foldToOtherRaisedStreet1'][player]: row[24]+=1
+ if hudImportData['foldToOtherRaisedStreet2'][player]: row[25]+=1
+ if hudImportData['foldToOtherRaisedStreet3'][player]: row[26]+=1
+ if hudImportData['foldToOtherRaisedStreet4'][player]: row[27]+=1
+ if hudImportData['wonWhenSeenStreet1'][player]!=0.0: row[28]+=hudImportData['wonWhenSeenStreet1'][player]
+ if hudImportData['wonAtSD'][player]!=0.0: row[29]+=hudImportData['wonAtSD'][player]
+ if hudImportData['stealAttemptChance'][player]: row[30]+=1
+ if hudImportData['stealAttempted'][player]: row[31]+=1
+ if hudImportData['foldBbToStealChance'][player]: row[32]+=1
+ if hudImportData['foldedBbToSteal'][player]: row[33]+=1
+ if hudImportData['foldSbToStealChance'][player]: row[34]+=1
+ if hudImportData['foldedSbToSteal'][player]: row[35]+=1
+
+ if hudImportData['street1CBChance'][player]: row[36]+=1
+ if hudImportData['street1CBDone'][player]: row[37]+=1
+ if hudImportData['street2CBChance'][player]: row[38]+=1
+ if hudImportData['street2CBDone'][player]: row[39]+=1
+ if hudImportData['street3CBChance'][player]: row[40]+=1
+ if hudImportData['street3CBDone'][player]: row[41]+=1
+ if hudImportData['street4CBChance'][player]: row[42]+=1
+ if hudImportData['street4CBDone'][player]: row[43]+=1
+
+ if hudImportData['foldToStreet1CBChance'][player]: row[44]+=1
+ if hudImportData['foldToStreet1CBDone'][player]: row[45]+=1
+ if hudImportData['foldToStreet2CBChance'][player]: row[46]+=1
+ if hudImportData['foldToStreet2CBDone'][player]: row[47]+=1
+ if hudImportData['foldToStreet3CBChance'][player]: row[48]+=1
+ if hudImportData['foldToStreet3CBDone'][player]: row[49]+=1
+ if hudImportData['foldToStreet4CBChance'][player]: row[50]+=1
+ if hudImportData['foldToStreet4CBDone'][player]: row[51]+=1
+
+ #print "player=", player
+ #print "len(totalProfit)=", len(hudImportData['totalProfit'])
+ if hudImportData['totalProfit'][player]:
+ row[52]+=hudImportData['totalProfit'][player]
+
+ if hudImportData['street1CheckCallRaiseChance'][player]: row[53]+=1
+ if hudImportData['street1CheckCallRaiseDone'][player]: row[54]+=1
+ if hudImportData['street2CheckCallRaiseChance'][player]: row[55]+=1
+ if hudImportData['street2CheckCallRaiseDone'][player]: row[56]+=1
+ if hudImportData['street3CheckCallRaiseChance'][player]: row[57]+=1
+ if hudImportData['street3CheckCallRaiseDone'][player]: row[58]+=1
+ if hudImportData['street4CheckCallRaiseChance'][player]: row[59]+=1
+ if hudImportData['street4CheckCallRaiseDone'][player]: row[60]+=1
+
+ if doInsert:
+ #print "playerid before insert:",row[2]
+ cursor.execute("""INSERT INTO HudCache
+(gametypeId, playerId, activeSeats, position, tourneyTypeId,
+HDs, street0VPI, street0Aggr, street0_3B4BChance, street0_3B4BDone,
+street1Seen, street2Seen, street3Seen, street4Seen, sawShowdown,
+street1Aggr, street2Aggr, street3Aggr, street4Aggr, otherRaisedStreet1,
+otherRaisedStreet2, otherRaisedStreet3, otherRaisedStreet4, foldToOtherRaisedStreet1, foldToOtherRaisedStreet2,
+foldToOtherRaisedStreet3, foldToOtherRaisedStreet4, wonWhenSeenStreet1, wonAtSD, stealAttemptChance,
+stealAttempted, foldBbToStealChance, foldedBbToSteal, foldSbToStealChance, foldedSbToSteal,
+street1CBChance, street1CBDone, street2CBChance, street2CBDone, street3CBChance,
+street3CBDone, street4CBChance, street4CBDone, foldToStreet1CBChance, foldToStreet1CBDone,
+foldToStreet2CBChance, foldToStreet2CBDone, foldToStreet3CBChance, foldToStreet3CBDone, foldToStreet4CBChance,
+foldToStreet4CBDone, totalProfit, street1CheckCallRaiseChance, street1CheckCallRaiseDone, street2CheckCallRaiseChance,
+street2CheckCallRaiseDone, street3CheckCallRaiseChance, street3CheckCallRaiseDone, street4CheckCallRaiseChance, street4CheckCallRaiseDone)
+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, %s,
+%s, %s, %s, %s, %s)""", (row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19], row[20], row[21], row[22], row[23], row[24], row[25], row[26], row[27], row[28], row[29], row[30], row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40], row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50], row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60]))
+ else:
+ #print "storing updated hud data line"
+ cursor.execute("""UPDATE HudCache
+SET HDs=%s, street0VPI=%s, street0Aggr=%s, street0_3B4BChance=%s, street0_3B4BDone=%s,
+street1Seen=%s, street2Seen=%s, street3Seen=%s, street4Seen=%s, sawShowdown=%s,
+street1Aggr=%s, street2Aggr=%s, street3Aggr=%s, street4Aggr=%s, otherRaisedStreet1=%s,
+otherRaisedStreet2=%s, otherRaisedStreet3=%s, otherRaisedStreet4=%s, foldToOtherRaisedStreet1=%s, foldToOtherRaisedStreet2=%s,
+foldToOtherRaisedStreet3=%s, foldToOtherRaisedStreet4=%s, wonWhenSeenStreet1=%s, wonAtSD=%s, stealAttemptChance=%s,
+stealAttempted=%s, foldBbToStealChance=%s, foldedBbToSteal=%s, foldSbToStealChance=%s, foldedSbToSteal=%s,
+street1CBChance=%s, street1CBDone=%s, street2CBChance=%s, street2CBDone=%s, street3CBChance=%s,
+street3CBDone=%s, street4CBChance=%s, street4CBDone=%s, foldToStreet1CBChance=%s, foldToStreet1CBDone=%s,
+foldToStreet2CBChance=%s, foldToStreet2CBDone=%s, foldToStreet3CBChance=%s, foldToStreet3CBDone=%s, foldToStreet4CBChance=%s,
+foldToStreet4CBDone=%s, totalProfit=%s, street1CheckCallRaiseChance=%s, street1CheckCallRaiseDone=%s, street2CheckCallRaiseChance=%s,
+street2CheckCallRaiseDone=%s, street3CheckCallRaiseChance=%s, street3CheckCallRaiseDone=%s, street4CheckCallRaiseChance=%s, street4CheckCallRaiseDone=%s
+WHERE gametypeId=%s AND playerId=%s AND activeSeats=%s AND position=%s AND tourneyTypeId=%s""", (row[6], row[7], row[8], row[9], row[10],
+ row[11], row[12], row[13], row[14], row[15],
+ row[16], row[17], row[18], row[19], row[20],
+ row[21], row[22], row[23], row[24], row[25],
+ row[26], row[27], row[28], row[29], row[30],
+ row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40],
+ row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50],
+ row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60],
+ row[1], row[2], row[3], str(row[4]), row[5]))
+# else:
+# print "todo: implement storeHudCache for stud base"
+#end def storeHudCache
+
+def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime):
+ cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
+ tmp=cursor.fetchone()
+ #print "tried SELECTing tourneys.id, result:",tmp
+
+ try:
+ len(tmp)
+ except TypeError:#means we have to create new one
+ cursor.execute("""INSERT INTO Tourneys
+(tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)
+VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime))
+ cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
+ tmp=cursor.fetchone()
+ #print "created new tourneys.id:",tmp
+ return tmp[0]
+#end def store_tourneys
+
+def store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings):
+ result=[]
+ #print "in store_tourneys_players. tourney_id:",tourney_id
+ #print "player_ids:",player_ids
+ #print "payin_amounts:",payin_amounts
+ #print "ranks:",ranks
+ #print "winnings:",winnings
+ for i in range (len(player_ids)):
+ cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", (tourney_id, player_ids[i]))
+ tmp=cursor.fetchone()
+ #print "tried SELECTing tourneys_players.id:",tmp
+
+ try:
+ len(tmp)
+ except TypeError:
+ cursor.execute("""INSERT INTO TourneysPlayers
+(tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""",
+ (tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i]))
+
+ cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s",
+ (tourney_id, player_ids[i]))
+ tmp=cursor.fetchone()
+ #print "created new tourneys_players.id:",tmp
+ result.append(tmp[0])
+ return result
+#end def store_tourneys_players
From 7d4bded3d5b7076ecf2074309bf9d6407160d3c4 Mon Sep 17 00:00:00 2001
From: eblade
Date: Tue, 9 Dec 2008 01:43:13 -0500
Subject: [PATCH 26/32] make sure we close each handle opened by ProcessOpen in
the win32 calls
---
pyfpdb/Hud.py | 1 +
pyfpdb/Tables.py | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py
index 80ec9a82..aaa9b42d 100644
--- a/pyfpdb/Hud.py
+++ b/pyfpdb/Hud.py
@@ -307,6 +307,7 @@ class Stat_Window:
pass
if event.button == 1: # left button event
+ # TODO: make position saving save sizes as well?
if event.state & gtk.gdk.SHIFT_MASK:
self.window.begin_resize_drag(gtk.gdk.WINDOW_EDGE_SOUTH_EAST, event.button, int(event.x_root), int(event.y_root), event.time)
else:
diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py
index 9f5360e2..d2cb2a24 100755
--- a/pyfpdb/Tables.py
+++ b/pyfpdb/Tables.py
@@ -248,7 +248,9 @@ def get_nt_exe(hwnd):
"""Finds the name of the executable that the given window handle belongs to."""
processid = win32process.GetWindowThreadProcessId(hwnd)
pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, processid[1])
- return win32process.GetModuleFileNameEx(pshandle, 0)
+ exename = win32process.GetModuleFileNameEx(pshandle, 0)
+ win32api.CloseHandle(pshandle)
+ return exename
def decode_windows(c, title, hwnd):
"""Gets window parameters from the window title and handle--Windows."""
From 9dd6f36df635d4d02df5a286644ceddc7c9a8c8c Mon Sep 17 00:00:00 2001
From: eblade
Date: Tue, 9 Dec 2008 07:51:41 -0500
Subject: [PATCH 27/32] add Hud::update_table_position(), tracks table.x and
table.y, repositions all stat_windows within. triggered each update(), and
when the Reposition Stats menu option is selected. fix windows code to use
same gdkhandle variables as unix code
---
pyfpdb/Hud.py | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py
index aaa9b42d..03ba1696 100644
--- a/pyfpdb/Hud.py
+++ b/pyfpdb/Hud.py
@@ -120,6 +120,19 @@ class Hud:
self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle) #
self.main_window.set_destroy_with_parent(True)
+
+ def update_table_position(self):
+ (x, y) = self.main_window.parentgdkhandle.get_origin()
+ if self.table.x != x or self.table.y != y:
+ self.table.x = x
+ self.table.y = y
+ self.main_window.move(x, y)
+ adj = self.adj_seats(self.hand, self.config)
+ loc = self.config.get_locations(self.table.site, self.max)
+ for i in range(1, self.max + 1):
+ (x, y) = loc[adj[i]]
+ if self.stat_windows.has_key(i):
+ self.stat_windows[i].relocate(x, y)
def on_button_press(self, widget, event):
if event.button == 1:
@@ -137,9 +150,7 @@ class Hud:
self.deleted = True
def reposition_windows(self, *args):
- for w in self.stat_windows:
- self.stat_windows[w].window.move(self.stat_windows[w].x,
- self.stat_windows[w].y)
+ self.update_table_position()
def debug_stat_windows(self, *args):
print self.table, "\n", self.main_window.window.get_transient_for()
@@ -216,6 +227,7 @@ class Hud:
def update(self, hand, config, stat_dict):
self.hand = hand # this is the last hand, so it is available later
+ self.update_table_position()
for s in stat_dict.keys():
try:
self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id']
@@ -260,9 +272,9 @@ class Hud:
for w in tl_windows:
if w[1] == unique_name:
#win32gui.ShowWindow(w[0], win32con.SW_HIDE)
- window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number))
+ self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number))
self.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
- self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle)
+ self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle)
#win32gui.ShowWindow(w[0], win32con.SW_SHOW)
style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
From 7516d17a40999fdd0638221f8b9998c3ddc96b4d Mon Sep 17 00:00:00 2001
From: eblade
Date: Tue, 9 Dec 2008 08:21:50 -0500
Subject: [PATCH 28/32] add 0.5 sec auto-timer to auto-run
update_table_position
---
pyfpdb/Hud.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py
index 03ba1696..a98c1421 100644
--- a/pyfpdb/Hud.py
+++ b/pyfpdb/Hud.py
@@ -224,6 +224,8 @@ class Hud:
if not game_params['aux'] == "":
aux_params = config.get_aux_parameters(game_params['aux'])
self.aux_windows.append(eval("%s.%s(gtk.Window(), config, 'fpdb')" % (aux_params['module'], aux_params['class'])))
+
+ gobject.timeout_add(0.5, update_table_position)
def update(self, hand, config, stat_dict):
self.hand = hand # this is the last hand, so it is available later
From 5e23b55361b855efb50efdd3ce802a5f44d60594 Mon Sep 17 00:00:00 2001
From: eblade
Date: Tue, 9 Dec 2008 08:35:19 -0500
Subject: [PATCH 29/32] specify right function name to timer, duh
---
pyfpdb/Hud.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py
index a98c1421..dcc7298c 100644
--- a/pyfpdb/Hud.py
+++ b/pyfpdb/Hud.py
@@ -225,7 +225,7 @@ class Hud:
aux_params = config.get_aux_parameters(game_params['aux'])
self.aux_windows.append(eval("%s.%s(gtk.Window(), config, 'fpdb')" % (aux_params['module'], aux_params['class'])))
- gobject.timeout_add(0.5, update_table_position)
+ gobject.timeout_add(0.5, self.update_table_position)
def update(self, hand, config, stat_dict):
self.hand = hand # this is the last hand, so it is available later
From 1a43ccf2da33afe0482d1178e935ff8384b77ead Mon Sep 17 00:00:00 2001
From: sqlcoder
Date: Tue, 9 Dec 2008 23:38:40 +0000
Subject: [PATCH 30/32] remove redundant unique keyword in create table
statements
---
pyfpdb/FpdbSQLQueries.py | 46 ++++++++++++++++++++--------------------
1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/pyfpdb/FpdbSQLQueries.py b/pyfpdb/FpdbSQLQueries.py
index a3d918ac..f5b4f400 100644
--- a/pyfpdb/FpdbSQLQueries.py
+++ b/pyfpdb/FpdbSQLQueries.py
@@ -73,13 +73,13 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createSitesTable'] = """CREATE TABLE Sites (
- id SMALLINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
name varchar(32) NOT NULL,
currency char(3) NOT NULL)
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createSitesTable'] = """CREATE TABLE Sites (
- id SERIAL UNIQUE, PRIMARY KEY (id),
+ id SERIAL, PRIMARY KEY (id),
name varchar(32),
currency char(3))"""
elif(self.dbname == 'SQLite'):
@@ -92,7 +92,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
- id SMALLINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
type char(4) NOT NULL,
base char(4) NOT NULL,
@@ -106,7 +106,7 @@ class FpdbSQLQueries:
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
- id SERIAL UNIQUE, PRIMARY KEY (id),
+ id SERIAL, PRIMARY KEY (id),
siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
type char(4),
base char(4),
@@ -127,7 +127,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createPlayersTable'] = """CREATE TABLE Players (
- id INT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
name VARCHAR(32) CHARACTER SET utf8 NOT NULL,
siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
comment text,
@@ -135,7 +135,7 @@ class FpdbSQLQueries:
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createPlayersTable'] = """CREATE TABLE Players (
- id SERIAL UNIQUE, PRIMARY KEY (id),
+ id SERIAL, PRIMARY KEY (id),
name VARCHAR(32),
siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
comment text,
@@ -150,7 +150,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
description varchar(50) NOT NULL,
@@ -160,7 +160,7 @@ class FpdbSQLQueries:
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
+ id BIGSERIAL, PRIMARY KEY (id),
playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
description varchar(50),
@@ -177,7 +177,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createHandsTable'] = """CREATE TABLE Hands (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
tableName VARCHAR(20) NOT NULL,
siteHandNo BIGINT NOT NULL,
gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
@@ -190,7 +190,7 @@ class FpdbSQLQueries:
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createHandsTable'] = """CREATE TABLE Hands (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
+ id BIGSERIAL, PRIMARY KEY (id),
tableName VARCHAR(20),
siteHandNo BIGINT,
gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
@@ -210,7 +210,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createBoardCardsTable'] = """CREATE TABLE BoardCards (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
handId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
card1Value smallint NOT NULL,
card1Suit char(1) NOT NULL,
@@ -225,7 +225,7 @@ class FpdbSQLQueries:
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createBoardCardsTable'] = """CREATE TABLE BoardCards (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
+ id BIGSERIAL, PRIMARY KEY (id),
handId BIGINT, FOREIGN KEY (handId) REFERENCES Hands(id),
card1Value smallint,
card1Suit char(1),
@@ -247,7 +247,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
- id SMALLINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
buyin INT NOT NULL,
fee INT NOT NULL,
@@ -272,7 +272,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
- id INT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
tourneyTypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
siteTourneyNo BIGINT NOT NULL,
entries INT NOT NULL,
@@ -283,7 +283,7 @@ class FpdbSQLQueries:
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
- id SERIAL UNIQUE, PRIMARY KEY (id),
+ id SERIAL, PRIMARY KEY (id),
tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
siteTourneyNo BIGINT,
entries INT,
@@ -300,7 +300,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
handId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
startCash INT NOT NULL,
@@ -332,7 +332,7 @@ class FpdbSQLQueries:
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
+ id BIGSERIAL, PRIMARY KEY (id),
handId BIGINT, FOREIGN KEY (handId) REFERENCES Hands(id),
playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
startCash INT,
@@ -370,7 +370,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
tourneyId INT UNSIGNED NOT NULL, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id),
playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
payinAmount INT NOT NULL,
@@ -381,7 +381,7 @@ class FpdbSQLQueries:
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
+ id BIGSERIAL, PRIMARY KEY (id),
tourneyId INT, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id),
playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
payinAmount INT,
@@ -399,7 +399,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
handPlayerId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handPlayerId) REFERENCES HandsPlayers(id),
street SMALLINT NOT NULL,
actionNo SMALLINT NOT NULL,
@@ -411,7 +411,7 @@ class FpdbSQLQueries:
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
+ id BIGSERIAL, PRIMARY KEY (id),
handPlayerId BIGINT, FOREIGN KEY (handPlayerId) REFERENCES HandsPlayers(id),
street SMALLINT,
actionNo SMALLINT,
@@ -430,7 +430,7 @@ class FpdbSQLQueries:
if(self.dbname == 'MySQL InnoDB'):
self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
- id BIGINT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
+ id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id),
activeSeats SMALLINT NOT NULL,
@@ -503,7 +503,7 @@ class FpdbSQLQueries:
ENGINE=INNODB"""
elif(self.dbname == 'PostgreSQL'):
self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
- id BIGSERIAL UNIQUE, PRIMARY KEY (id),
+ id BIGSERIAL, PRIMARY KEY (id),
gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
activeSeats SMALLINT,
From c8d12cfe612b8c5a53692a358c025a56c08b1ba6 Mon Sep 17 00:00:00 2001
From: steffen123
Date: Wed, 10 Dec 2008 03:55:12 +0000
Subject: [PATCH 31/32] p144 - updated table design after comments on draw
tables
---
create-release.sh | 4 ++--
docs/tabledesign.html | 20 +++++++++++++++-----
pyfpdb/CliFpdb.py | 0
pyfpdb/Configuration.py | 0
pyfpdb/HUD_main.py | 0
pyfpdb/fpdb.py | 0
6 files changed, 17 insertions(+), 7 deletions(-)
mode change 100644 => 100755 pyfpdb/CliFpdb.py
mode change 100644 => 100755 pyfpdb/Configuration.py
mode change 100644 => 100755 pyfpdb/HUD_main.py
mode change 100644 => 100755 pyfpdb/fpdb.py
diff --git a/create-release.sh b/create-release.sh
index bdc4333a..9f28a7ac 100755
--- a/create-release.sh
+++ b/create-release.sh
@@ -29,8 +29,8 @@ cp -R regression-test fpdb-$1/
cp -R utils fpdb-$1/
cd fpdb-$1
-zip -r ../../fpdb-1.0_$1.zip *
-tar -cf - * | bzip2 >> ../../fpdb-1.0_$1.tar.bz2
+zip -r releases/fpdb-1.0_$1.zip *
+tar -cf - * | bzip2 >> releases/fpdb-1.0_$1.tar.bz2
cd ..
rm -r fpdb-$1
diff --git a/docs/tabledesign.html b/docs/tabledesign.html
index ce39d4bc..e148b9cf 100644
--- a/docs/tabledesign.html
+++ b/docs/tabledesign.html
@@ -312,11 +312,10 @@ The program itself is licensed under AGPLv3, see agpl-3.0.txt
Table HandsPlayers
-cardX: can be 1 through 20, one for each card. In holdem only 1-2 of these are used, in omaha 1-4, in stud/razz 1-7, in single draw games 1-10 is used and in badugi 1-16 (4*4) is used.
-For the draw games: the first 5 (badugi: 4) cards are the initial cards, the next 5 (badugi: 4) are after the first draw. If a player keeps some cards then those cards' spaces are filled with "k", short for "kept".
-Example 1: If a player gets 2-6 spades for his first five cards and decides to throw away the 4 and then gets a 7 of spades then the first 10 fields of cardXValue would be as follows: 2, 3, 4, 5, 6, k, k, 7, k, k
-Example 2: If a player gets 2, 3, 5, 8, J of spades for his first five cards and decides to throw away the 2 and the 3 and then gets a Q and K of spades then the first 10 fields of cardXValue would be as follows: 2, 3, 5, 8, J, Q, K, k, k, k
-Note that it will k in the space of which card was there previously, so in example 2 where the player kept the last 3 cards, the last 3 fields of the first draw (ie. card8-10Value) are replaced with k.
+cardX: can be 1 through 20, one for each card. In holdem only 1-2 of these are used, in omaha 1-4, in stud/razz 1-7, in single draw 1-10, in tripple draw all 20 and in badugi 1-16 (4*4).
+For the draw games: the first 5 (badugi: 4) cards are the initial cards, the next 5 (badugi: 4) are after the first draw, etc.
+Example 1: If a player gets 2-6 spades for his first five cards and decides to throw away the 4 and then gets a 7 of spades then the first 10 fields of cardXValue would be as follows: 2, 3, 4, 5, 6, 2, 3, 5, 6, 7
+Example 2: If a player gets 2, 3, 5, 8, J of spades for his first five cards and decides to throw away the 2 and the 3 and then gets a Q and K of spades then the first 10 fields of cardXValue would be as follows: 2, 3, 5, 8, J, 5, 8, J, Q, K.
I did not separate this into an extra table because I felt the lost space is not sufficiently large. Also the benefit for searching is far less relevant.
@@ -370,6 +369,17 @@ Note that it will k in the space of which card was there previously, so in examp
char(1) |
h=hearts, s=spades, d=diamonds, c=clubs, unknown/no card=x |
+
+ cardXDiscarded |
+ boolean |
+ Whether the card was discarded (this only applies to draw games, X can be 1 through 15 since the final cards can obviously not be discarded). |
+
+
+ DrawnX |
+ smallint |
+ X can be 1 through 3.
+ This field denotes how many cards the player has drawn on each draw. |
+
winnings |
int |
diff --git a/pyfpdb/CliFpdb.py b/pyfpdb/CliFpdb.py
old mode 100644
new mode 100755
diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py
old mode 100644
new mode 100755
diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py
old mode 100644
new mode 100755
diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py
old mode 100644
new mode 100755
From 9ca0574d7854ec164c27ec0c36500e750d5bc0b0 Mon Sep 17 00:00:00 2001
From: Worros
Date: Wed, 10 Dec 2008 21:21:43 +0900
Subject: [PATCH 32/32] Really basic check that username exists
---
pyfpdb/GuiPlayerStats.py | 65 ++++++++++++++++++++--------------------
1 file changed, 33 insertions(+), 32 deletions(-)
diff --git a/pyfpdb/GuiPlayerStats.py b/pyfpdb/GuiPlayerStats.py
index 7d689228..a4baea41 100644
--- a/pyfpdb/GuiPlayerStats.py
+++ b/pyfpdb/GuiPlayerStats.py
@@ -46,41 +46,42 @@ class GuiPlayerStats (threading.Thread):
result = self.cursor.execute(self.sql.query['getPlayerId'], self.heroes[self.activesite])
result = self.db.cursor.fetchall()
- pid = result[0][0]
- tmp = tmp.replace("", "(" + str(pid) + ")")
- self.cursor.execute(tmp)
- result = self.db.cursor.fetchall()
- cols = 18
- rows = len(result)+1 # +1 for title row
- self.stats_table = gtk.Table(rows, cols, False)
- self.stats_table.set_col_spacings(4)
- self.stats_table.show()
- vbox.add(self.stats_table)
+ if not result == ():
+ pid = result[0][0]
+ tmp = tmp.replace("", "(" + str(pid) + ")")
+ self.cursor.execute(tmp)
+ result = self.db.cursor.fetchall()
+ cols = 18
+ rows = len(result)+1 # +1 for title row
+ self.stats_table = gtk.Table(rows, cols, False)
+ self.stats_table.set_col_spacings(4)
+ self.stats_table.show()
+ vbox.add(self.stats_table)
- # Create header row
- titles = ("GID", "base", "Style", "Site", "$BB", "Hands", "VPIP", "PFR", "saw_f", "sawsd", "wtsdwsf", "wmsd", "FlAFq", "TuAFq", "RvAFq", "PFAFq", "Net($)", "BB/100")
+ # Create header row
+ titles = ("GID", "base", "Style", "Site", "$BB", "Hands", "VPIP", "PFR", "saw_f", "sawsd", "wtsdwsf", "wmsd", "FlAFq", "TuAFq", "RvAFq", "PFAFq", "Net($)", "BB/100")
- col = 0
- row = 0
- for t in titles:
- l = gtk.Label(titles[col])
- l.show()
- self.stats_table.attach(l, col, col+1, row, row+1)
- col +=1
+ col = 0
+ row = 0
+ for t in titles:
+ l = gtk.Label(titles[col])
+ l.show()
+ self.stats_table.attach(l, col, col+1, row, row+1)
+ col +=1
- for row in range(rows-1):
- for col in range(cols):
- if(row%2 == 0):
- bgcolor = "white"
- else:
- bgcolor = "lightgrey"
- eb = gtk.EventBox()
- eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bgcolor))
- l = gtk.Label(result[row-1][col])
- eb.add(l)
- self.stats_table.attach(eb, col, col+1, row+1, row+2)
- l.show()
- eb.show()
+ for row in range(rows-1):
+ for col in range(cols):
+ if(row%2 == 0):
+ bgcolor = "white"
+ else:
+ bgcolor = "lightgrey"
+ eb = gtk.EventBox()
+ eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bgcolor))
+ l = gtk.Label(result[row-1][col])
+ eb.add(l)
+ self.stats_table.attach(eb, col, col+1, row+1, row+2)
+ l.show()
+ eb.show()
def fillPlayerFrame(self, vbox):