Merge branch 'master' of git://git.assembla.com/fpdboz
Conflicts: pyfpdb/Configuration.py pyfpdb/HUD_main.py
This commit is contained in:
commit
c1f599d555
|
@ -10,7 +10,8 @@ Architecture: all
|
|||
Section: games
|
||||
Priority: extra
|
||||
Depends: ${python:Depends}, python-gtk2, python-matplotlib,
|
||||
python-support, mysql-server | postgresql | python-pysqlite2,
|
||||
python-support, python-xlib,
|
||||
mysql-server | postgresql | python-pysqlite2,
|
||||
python-psycopg2 | python-mysqldb
|
||||
Suggests: wine
|
||||
Description: free poker database with HUD
|
||||
|
|
|
@ -6,17 +6,17 @@ Handles HUD configuration files.
|
|||
"""
|
||||
# Copyright 2008, 2009, 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
|
||||
|
@ -54,8 +54,10 @@ def get_exec_path():
|
|||
"""Returns the path to the fpdb.(py|exe) file we are executing"""
|
||||
if hasattr(sys, "frozen"): # compiled by py2exe
|
||||
return os.path.dirname(sys.executable)
|
||||
else:
|
||||
return os.path.dirname(sys.path[0])
|
||||
else:
|
||||
print "argv=", sys.argv
|
||||
pathname = os.path.dirname(sys.argv[0])
|
||||
return os.path.abspath(pathname)
|
||||
|
||||
def get_config(file_name, fallback = True):
|
||||
"""Looks in exec dir and in self.default_config_path for a config file."""
|
||||
|
@ -162,7 +164,7 @@ class Layout:
|
|||
if node.hasAttribute('fav_seat'): self.fav_seat = int( node.getAttribute('fav_seat') )
|
||||
self.width = int( node.getAttribute('width') )
|
||||
self.height = int( node.getAttribute('height') )
|
||||
|
||||
|
||||
self.location = []
|
||||
self.location = map(lambda x: None, range(self.max+1)) # fill array with max seats+1 empty entries
|
||||
|
||||
|
@ -181,7 +183,7 @@ class Layout:
|
|||
temp = temp + " Locations = "
|
||||
for i in range(1, len(self.location)):
|
||||
temp = temp + "(%d,%d)" % self.location[i]
|
||||
|
||||
|
||||
return temp + "\n"
|
||||
|
||||
class Site:
|
||||
|
@ -191,7 +193,7 @@ class Site:
|
|||
if os.path.exists(path):
|
||||
return os.path.abspath(path)
|
||||
return path
|
||||
|
||||
|
||||
self.site_name = node.getAttribute("site_name")
|
||||
self.table_finder = node.getAttribute("table_finder")
|
||||
self.screen_name = node.getAttribute("screen_name")
|
||||
|
@ -211,7 +213,7 @@ class Site:
|
|||
self.ypad = node.getAttribute("ypad")
|
||||
self.layout = {}
|
||||
|
||||
print "Loading site", self.site_name
|
||||
print "Loading site", self.site_name
|
||||
|
||||
for layout_node in node.getElementsByTagName('layout'):
|
||||
lo = Layout(layout_node)
|
||||
|
@ -224,7 +226,7 @@ class Site:
|
|||
self.hudopacity = 1.0 if self.hudopacity == "" else float(self.hudopacity)
|
||||
|
||||
if self.use_frames == "": self.use_frames = False
|
||||
if self.font == "": self.font = "Sans"
|
||||
if self.font == "": self.font = "Sans"
|
||||
if self.hudbgcolor == "": self.hudbgcolor = "#000000"
|
||||
if self.hudfgcolor == "": self.hudfgcolor = "#FFFFFF"
|
||||
|
||||
|
@ -236,20 +238,20 @@ class Site:
|
|||
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")
|
||||
|
@ -282,9 +284,9 @@ class Game:
|
|||
stat.hudprefix = stat_node.getAttribute("hudprefix")
|
||||
stat.hudsuffix = stat_node.getAttribute("hudsuffix")
|
||||
stat.hudcolor = stat_node.getAttribute("hudcolor")
|
||||
|
||||
|
||||
self.stats[stat.stat_name] = stat
|
||||
|
||||
|
||||
def __str__(self):
|
||||
temp = "Game = " + self.game_name + "\n"
|
||||
temp = temp + " rows = %d\n" % self.rows
|
||||
|
@ -292,12 +294,12 @@ class Game:
|
|||
temp = temp + " xpad = %d\n" % self.xpad
|
||||
temp = temp + " ypad = %d\n" % self.ypad
|
||||
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")
|
||||
|
@ -308,7 +310,7 @@ class Database:
|
|||
self.db_selected = string_to_bool(node.getAttribute("default"), default=False)
|
||||
log.debug("Database db_name:'%(name)s' db_server:'%(server)s' db_ip:'%(ip)s' db_user:'%(user)s' db_pass (not logged) selected:'%(sel)s'" \
|
||||
% { 'name':self.db_name, 'server':self.db_server, 'ip':self.db_ip, 'user':self.db_user, 'sel':self.db_selected} )
|
||||
|
||||
|
||||
def __str__(self):
|
||||
temp = 'Database = ' + self.db_name + '\n'
|
||||
for key in dir(self):
|
||||
|
@ -356,7 +358,7 @@ class Popup:
|
|||
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:
|
||||
|
@ -381,16 +383,16 @@ class HudUI:
|
|||
self.node = node
|
||||
self.label = node.getAttribute('label')
|
||||
#
|
||||
self.hud_style = node.getAttribute('stat_range')
|
||||
self.hud_days = node.getAttribute('stat_days')
|
||||
self.aggregate_ring = string_to_bool(node.getAttribute('aggregate_ring_game_stats'))
|
||||
self.aggregate_tour = string_to_bool(node.getAttribute('aggregate_tourney_stats'))
|
||||
self.hud_style = node.getAttribute('stat_aggregation_range')
|
||||
self.hud_days = node.getAttribute('aggregation_days')
|
||||
self.agg_bb_mult = node.getAttribute('aggregation_level_multiplier')
|
||||
#
|
||||
self.h_aggregate_ring = string_to_bool(node.getAttribute('aggregate_hero_ring_game_stats'))
|
||||
self.h_aggregate_tour = string_to_bool(node.getAttribute('aggregate_hero_tourney_stats'))
|
||||
self.h_hud_style = node.getAttribute('hero_stat_aggregation_range')
|
||||
self.h_hud_days = node.getAttribute('hero_aggregation_days')
|
||||
self.h_hud_style = node.getAttribute('hero_stat_range')
|
||||
self.h_hud_days = node.getAttribute('hero_stat_days')
|
||||
self.h_aggregate_ring = string_to_bool(node.getAttribute('aggregate_hero_ring_game_stats'))
|
||||
self.h_aggregate_tour = string_to_bool(node.getAttribute('aggregate_hero_tourney_stats'))
|
||||
self.h_agg_bb_mult = node.getAttribute('hero_aggregation_level_multiplier')
|
||||
|
||||
|
||||
|
@ -405,7 +407,7 @@ class Tv:
|
|||
self.combinedPostflop = string_to_bool(node.getAttribute("combinedPostflop"), default=True)
|
||||
|
||||
def __str__(self):
|
||||
return (" combinedStealFold = %s\n combined2B3B = %s\n combinedPostflop = %s\n" %
|
||||
return (" combinedStealFold = %s\n combined2B3B = %s\n combinedPostflop = %s\n" %
|
||||
(self.combinedStealFold, self.combined2B3B, self.combinedPostflop) )
|
||||
|
||||
class Config:
|
||||
|
@ -429,7 +431,7 @@ class Config:
|
|||
print "\nReading configuration file %s\n" % file
|
||||
try:
|
||||
doc = xml.dom.minidom.parse(file)
|
||||
except:
|
||||
except:
|
||||
log.error("Error parsing %s. See error log file." % (file))
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
print "press enter to continue"
|
||||
|
@ -457,9 +459,9 @@ class Config:
|
|||
for game_node in doc.getElementsByTagName("game"):
|
||||
game = Game(node = game_node)
|
||||
self.supported_games[game.game_name] = game
|
||||
|
||||
|
||||
# parse databases defined by user in the <supported_databases> section
|
||||
# the user may select the actual database to use via commandline or by setting the selected="bool"
|
||||
# the user may select the actual database to use via commandline or by setting the selected="bool"
|
||||
# attribute of the tag. if no database is explicitely selected, we use the first one we come across
|
||||
# s_dbs = doc.getElementsByTagName("supported_databases")
|
||||
#TODO: do we want to take all <database> tags or all <database> tags contained in <supported_databases>
|
||||
|
@ -471,7 +473,7 @@ class Config:
|
|||
if self.db_selected is None or db.db_selected:
|
||||
self.db_selected = db.db_name
|
||||
self.supported_databases[db.db_name] = db
|
||||
#TODO: if the user may passes '' (empty string) as database name via command line, his choice is ignored
|
||||
#TODO: if the user may passes '' (empty string) as database name via command line, his choice is ignored
|
||||
# ..when we parse the xml we allow for ''. there has to be a decission if to allow '' or not
|
||||
if dbname and dbname in self.supported_databases:
|
||||
self.db_selected = dbname
|
||||
|
@ -521,7 +523,7 @@ class Config:
|
|||
|
||||
def set_hhArchiveBase(self, path):
|
||||
self.imp.node.setAttribute("hhArchiveBase", path)
|
||||
|
||||
|
||||
def find_default_conf(self):
|
||||
if os.name == 'posix':
|
||||
config_path = os.path.join(os.path.expanduser("~"), '.fpdb', 'default.conf')
|
||||
|
@ -553,7 +555,7 @@ class Config:
|
|||
|
||||
def get_layout_node(self, site_node, layout):
|
||||
for layout_node in site_node.getElementsByTagName("layout"):
|
||||
if layout_node.getAttribute("max") is None:
|
||||
if layout_node.getAttribute("max") is None:
|
||||
return None
|
||||
if int( layout_node.getAttribute("max") ) == int( layout ):
|
||||
return layout_node
|
||||
|
@ -637,7 +639,7 @@ class Config:
|
|||
elif self.supported_databases[name].db_server== DATABASE_TYPE_POSTGRESQL:
|
||||
db['db-backend'] = 3
|
||||
elif self.supported_databases[name].db_server== DATABASE_TYPE_SQLITE:
|
||||
db['db-backend'] = 4
|
||||
db['db-backend'] = 4
|
||||
else:
|
||||
raise ValueError('Unsupported database backend: %s' % self.supported_databases[name].db_server)
|
||||
return db
|
||||
|
@ -658,7 +660,7 @@ class Config:
|
|||
if db_server is not None: self.supported_databases[db_name].dp_server = db_server
|
||||
if db_type is not None: self.supported_databases[db_name].dp_type = db_type
|
||||
return
|
||||
|
||||
|
||||
def getDefaultSite(self):
|
||||
"Returns first enabled site or None"
|
||||
for site_name,site in self.supported_sites.iteritems():
|
||||
|
@ -721,7 +723,7 @@ class Config:
|
|||
|
||||
return hui
|
||||
|
||||
|
||||
|
||||
def get_import_parameters(self):
|
||||
imp = {}
|
||||
try: imp['callFpdbHud'] = self.imp.callFpdbHud
|
||||
|
@ -747,10 +749,10 @@ class Config:
|
|||
path = os.path.expanduser(self.supported_sites[site].HH_path)
|
||||
assert(os.path.isdir(path) or os.path.isfile(path)) # maybe it should try another site?
|
||||
paths['hud-defaultPath'] = paths['bulkImport-defaultPath'] = path
|
||||
except AssertionError:
|
||||
except AssertionError:
|
||||
paths['hud-defaultPath'] = paths['bulkImport-defaultPath'] = "** ERROR DEFAULT PATH IN CONFIG DOES NOT EXIST **"
|
||||
return paths
|
||||
|
||||
|
||||
def get_frames(self, site = "PokerStars"):
|
||||
if site not in self.supported_sites: return False
|
||||
return self.supported_sites[site].use_frames == True
|
||||
|
@ -770,7 +772,7 @@ class Config:
|
|||
else:
|
||||
colors['hudfgcolor'] = self.supported_sites[site].hudfgcolor
|
||||
return colors
|
||||
|
||||
|
||||
def get_default_font(self, site='PokerStars'):
|
||||
font = "Sans"
|
||||
font_size = "8"
|
||||
|
@ -789,17 +791,17 @@ class Config:
|
|||
if location is not None:
|
||||
return location.location
|
||||
return (
|
||||
( 0, 0), (684, 61), (689, 239), (692, 346),
|
||||
( 0, 0), (684, 61), (689, 239), (692, 346),
|
||||
(586, 393), (421, 440), (267, 440), ( 0, 361),
|
||||
( 0, 280), (121, 280), ( 46, 30)
|
||||
( 0, 280), (121, 280), ( 46, 30)
|
||||
)
|
||||
|
||||
|
||||
def get_aux_locations(self, aux = "mucked", max = "9"):
|
||||
|
||||
|
||||
try:
|
||||
locations = self.aux_windows[aux].layout[max].location
|
||||
except:
|
||||
locations = ( ( 0, 0), (684, 61), (689, 239), (692, 346),
|
||||
locations = ( ( 0, 0), (684, 61), (689, 239), (692, 346),
|
||||
(586, 393), (421, 440), (267, 440), ( 0, 361),
|
||||
( 0, 280), (121, 280), ( 46, 30) )
|
||||
return locations
|
||||
|
@ -810,7 +812,7 @@ class Config:
|
|||
return self.supported_sites.keys()
|
||||
else:
|
||||
return [site_name for (site_name, site) in self.supported_sites.items() if site.enabled]
|
||||
|
||||
|
||||
def get_site_parameters(self, site):
|
||||
"""Returns a dict of the site parameters for the specified site"""
|
||||
parms = {}
|
||||
|
@ -833,7 +835,7 @@ class Config:
|
|||
return parms
|
||||
|
||||
def set_site_parameters(self, site_name, converter = None, decoder = None,
|
||||
hudbgcolor = None, hudfgcolor = None,
|
||||
hudbgcolor = None, hudfgcolor = None,
|
||||
hudopacity = None, screen_name = None,
|
||||
site_path = None, table_finder = None,
|
||||
HH_path = None, enabled = None,
|
||||
|
@ -871,7 +873,7 @@ class Config:
|
|||
|
||||
return param
|
||||
return None
|
||||
|
||||
|
||||
def get_game_parameters(self, name):
|
||||
"""Get the configuration parameters for the named game."""
|
||||
param = {}
|
||||
|
@ -897,7 +899,7 @@ class Config:
|
|||
|
||||
if __name__== "__main__":
|
||||
c = Config()
|
||||
|
||||
|
||||
print "\n----------- SUPPORTED SITES -----------"
|
||||
for s in c.supported_sites.keys():
|
||||
print c.supported_sites[s]
|
||||
|
@ -924,7 +926,7 @@ if __name__== "__main__":
|
|||
for w in c.hhcs.keys():
|
||||
print c.hhcs[w]
|
||||
print "----------- END HAND HISTORY CONVERTERS -----------"
|
||||
|
||||
|
||||
print "\n----------- POPUP WINDOW FORMATS -----------"
|
||||
for w in c.popup_windows.keys():
|
||||
print c.popup_windows[w]
|
||||
|
@ -940,7 +942,7 @@ if __name__== "__main__":
|
|||
|
||||
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()
|
||||
|
@ -951,7 +953,7 @@ if __name__== "__main__":
|
|||
print c.get_aux_parameters(mw)
|
||||
|
||||
print "mucked locations =", c.get_aux_locations('mucked', 9)
|
||||
# c.edit_aux_layout('mucked', 9, locations = [(487, 113), (555, 469), (572, 276), (522, 345),
|
||||
# c.edit_aux_layout('mucked', 9, locations = [(487, 113), (555, 469), (572, 276), (522, 345),
|
||||
# (333, 354), (217, 341), (150, 273), (150, 169), (230, 115)])
|
||||
# print "mucked locations =", c.get_aux_locations('mucked', 9)
|
||||
|
||||
|
|
|
@ -432,16 +432,14 @@ class Database:
|
|||
print "*** Database Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
|
||||
def get_stats_from_hand( self, hand, type # type is "ring" or "tour"
|
||||
, hud_params = {'aggregate_tour':False, 'aggregate_ring':False, 'hud_style':'A', 'hud_days':30, 'agg_bb_mult':100
|
||||
,'h_aggregate_tour':False, 'h_aggregate_ring':False, 'h_hud_style':'S', 'h_hud_days':30, 'h_agg_bb_mult':100}
|
||||
, hud_params = {'hud_style':'A', 'agg_bb_mult':1000
|
||||
,'h_hud_style':'S', 'h_agg_bb_mult':1000}
|
||||
, hero_id = -1
|
||||
):
|
||||
aggregate = hud_params['aggregate_tour'] if type == "tour" else hud_params['aggregate_ring']
|
||||
hud_style = hud_params['hud_style']
|
||||
agg_bb_mult = hud_params['agg_bb_mult'] if aggregate else 1
|
||||
h_aggregate = hud_params['h_aggregate_tour'] if type == "tour" else hud_params['h_aggregate_ring']
|
||||
agg_bb_mult = hud_params['agg_bb_mult']
|
||||
h_hud_style = hud_params['h_hud_style']
|
||||
h_agg_bb_mult = hud_params['h_agg_bb_mult'] if h_aggregate else 1
|
||||
h_agg_bb_mult = hud_params['h_agg_bb_mult']
|
||||
stat_dict = {}
|
||||
|
||||
if hud_style == 'S' or h_hud_style == 'S':
|
||||
|
@ -456,6 +454,10 @@ class Database:
|
|||
stylekey = '0000000' # all stylekey values should be higher than this
|
||||
elif hud_style == 'S':
|
||||
stylekey = 'zzzzzzz' # all stylekey values should be lower than this
|
||||
else:
|
||||
stylekey = '0000000'
|
||||
log.info('hud_style: %s' % hud_style)
|
||||
|
||||
#elif hud_style == 'H':
|
||||
# stylekey = date_nhands_ago needs array by player here ...
|
||||
|
||||
|
@ -465,16 +467,15 @@ class Database:
|
|||
h_stylekey = '0000000' # all stylekey values should be higher than this
|
||||
elif h_hud_style == 'S':
|
||||
h_stylekey = 'zzzzzzz' # all stylekey values should be lower than this
|
||||
else:
|
||||
h_stylekey = '000000'
|
||||
log.info('h_hud_style: %s' % h_hud_style)
|
||||
|
||||
#elif h_hud_style == 'H':
|
||||
# h_stylekey = date_nhands_ago needs array by player here ...
|
||||
|
||||
#if aggregate: always use aggregate query now: use agg_bb_mult of 1 for no aggregation:
|
||||
query = 'get_stats_from_hand_aggregated'
|
||||
subs = (hand, hero_id, stylekey, agg_bb_mult, agg_bb_mult, hero_id, h_stylekey, h_agg_bb_mult, h_agg_bb_mult)
|
||||
#print "agg query subs:", subs
|
||||
#else:
|
||||
# query = 'get_stats_from_hand'
|
||||
# subs = (hand, stylekey)
|
||||
|
||||
#print "get stats: hud style =", hud_style, "query =", query, "subs =", subs
|
||||
c = self.connection.cursor()
|
||||
|
@ -1384,6 +1385,13 @@ class Database:
|
|||
pids[p],
|
||||
pdata[p]['startCash'],
|
||||
pdata[p]['seatNo'],
|
||||
pdata[p]['card1'],
|
||||
pdata[p]['card2'],
|
||||
pdata[p]['card3'],
|
||||
pdata[p]['card4'],
|
||||
pdata[p]['card5'],
|
||||
pdata[p]['card6'],
|
||||
pdata[p]['card7'],
|
||||
pdata[p]['winnings'],
|
||||
pdata[p]['street0VPI'],
|
||||
pdata[p]['street1Seen'],
|
||||
|
@ -1402,6 +1410,13 @@ class Database:
|
|||
playerId,
|
||||
startCash,
|
||||
seatNo,
|
||||
card1,
|
||||
card2,
|
||||
card3,
|
||||
card4,
|
||||
card5,
|
||||
card6,
|
||||
card7,
|
||||
winnings,
|
||||
street0VPI,
|
||||
street1Seen,
|
||||
|
@ -1415,6 +1430,8 @@ class Database:
|
|||
street4Aggr
|
||||
)
|
||||
VALUES (
|
||||
%s, %s,
|
||||
%s, %s, %s, %s, %s,
|
||||
%s, %s, %s, %s, %s,
|
||||
%s, %s, %s, %s, %s,
|
||||
%s, %s, %s, %s, %s
|
||||
|
@ -1422,10 +1439,6 @@ class Database:
|
|||
|
||||
# position,
|
||||
# tourneyTypeId,
|
||||
# card1,
|
||||
# card2,
|
||||
# card3,
|
||||
# card4,
|
||||
# startCards,
|
||||
# rake,
|
||||
# totalProfit,
|
||||
|
|
|
@ -81,12 +81,13 @@ class DerivedStats():
|
|||
self.hands['boardcard5'] = cards[4]
|
||||
|
||||
#print "DEBUG: self.getStreetTotals = (%s, %s, %s, %s, %s)" % hand.getStreetTotals()
|
||||
#FIXME: Pot size still in decimal, needs to be converted to cents
|
||||
(self.hands['street1Pot'],
|
||||
self.hands['street2Pot'],
|
||||
self.hands['street3Pot'],
|
||||
self.hands['street4Pot'],
|
||||
self.hands['showdownPot']) = hand.getStreetTotals()
|
||||
totals = hand.getStreetTotals()
|
||||
totals = [int(100*i) for i in totals]
|
||||
self.hands['street1Pot'] = totals[0]
|
||||
self.hands['street2Pot'] = totals[1]
|
||||
self.hands['street3Pot'] = totals[2]
|
||||
self.hands['street4Pot'] = totals[3]
|
||||
self.hands['showdownPot'] = totals[4]
|
||||
|
||||
self.vpip(hand) # Gives playersVpi (num of players vpip)
|
||||
#print "DEBUG: vpip: %s" %(self.hands['playersVpi'])
|
||||
|
@ -115,695 +116,22 @@ class DerivedStats():
|
|||
for i, street in enumerate(hand.actionStreets[1:]):
|
||||
self.aggr(self.hand, i)
|
||||
|
||||
default_holecards = ["Xx", "Xx", "Xx", "Xx"]
|
||||
|
||||
for street in hand.holeStreets:
|
||||
for player in hand.players:
|
||||
for i in range(1,8): self.handsplayers[player[1]]['card%d' % i] = 0
|
||||
if player[1] in hand.holecards[street].keys():
|
||||
self.handsplayers[player[1]]['card1'] = Card.encodeCard(hand.holecards[street][player[1]][1][0])
|
||||
self.handsplayers[player[1]]['card2'] = Card.encodeCard(hand.holecards[street][player[1]][1][1])
|
||||
try:
|
||||
self.handsplayers[player[1]]['card3'] = Card.encodeCard(hand.holecards[street][player[1]][1][2])
|
||||
self.handsplayers[player[1]]['card4'] = Card.encodeCard(hand.holecards[street][player[1]][1][3])
|
||||
except IndexError:
|
||||
# Just means no player cards for that street/game - continue
|
||||
pass
|
||||
|
||||
def assembleHudCache(self, hand):
|
||||
# # def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo
|
||||
# # ,winnings, totalWinnings, positions, actionTypes, actionAmounts, antes):
|
||||
# #"""calculates data for the HUD during import. IMPORTANT: if you change this method make
|
||||
# # sure to also change the following storage method and table_viewer.prepare_data if necessary
|
||||
# #"""
|
||||
# #print "generateHudCacheData, len(player_ids)=", len(player_ids)
|
||||
# #setup subarrays of the result dictionary.
|
||||
# street0VPI=[]
|
||||
# street0Aggr=[]
|
||||
# street0_3BChance=[]
|
||||
# street0_3BDone=[]
|
||||
# street1Seen=[]
|
||||
# street2Seen=[]
|
||||
# street3Seen=[]
|
||||
# street4Seen=[]
|
||||
# sawShowdown=[]
|
||||
# street1Aggr=[]
|
||||
# street2Aggr=[]
|
||||
# street3Aggr=[]
|
||||
# street4Aggr=[]
|
||||
# otherRaisedStreet1=[]
|
||||
# otherRaisedStreet2=[]
|
||||
# otherRaisedStreet3=[]
|
||||
# otherRaisedStreet4=[]
|
||||
# foldToOtherRaisedStreet1=[]
|
||||
# foldToOtherRaisedStreet2=[]
|
||||
# foldToOtherRaisedStreet3=[]
|
||||
# foldToOtherRaisedStreet4=[]
|
||||
# wonWhenSeenStreet1=[]
|
||||
#
|
||||
# wonAtSD=[]
|
||||
# stealAttemptChance=[]
|
||||
# stealAttempted=[]
|
||||
# hudDataPositions=[]
|
||||
#
|
||||
# street0Calls=[]
|
||||
# street1Calls=[]
|
||||
# street2Calls=[]
|
||||
# street3Calls=[]
|
||||
# street4Calls=[]
|
||||
# street0Bets=[]
|
||||
# street1Bets=[]
|
||||
# street2Bets=[]
|
||||
# street3Bets=[]
|
||||
# street4Bets=[]
|
||||
# #street0Raises=[]
|
||||
# #street1Raises=[]
|
||||
# #street2Raises=[]
|
||||
# #street3Raises=[]
|
||||
# #street4Raises=[]
|
||||
#
|
||||
# # Summary figures for hand table:
|
||||
# result={}
|
||||
# result['playersVpi']=0
|
||||
# result['playersAtStreet1']=0
|
||||
# result['playersAtStreet2']=0
|
||||
# result['playersAtStreet3']=0
|
||||
# result['playersAtStreet4']=0
|
||||
# result['playersAtShowdown']=0
|
||||
# result['street0Raises']=0
|
||||
# result['street1Raises']=0
|
||||
# result['street2Raises']=0
|
||||
# result['street3Raises']=0
|
||||
# result['street4Raises']=0
|
||||
# result['street1Pot']=0
|
||||
# result['street2Pot']=0
|
||||
# result['street3Pot']=0
|
||||
# result['street4Pot']=0
|
||||
# result['showdownPot']=0
|
||||
#
|
||||
# firstPfRaiseByNo=-1
|
||||
# firstPfRaiserId=-1
|
||||
# firstPfRaiserNo=-1
|
||||
# firstPfCallByNo=-1
|
||||
# firstPfCallerId=-1
|
||||
#
|
||||
# for i, action in enumerate(actionTypeByNo[0]):
|
||||
# if action[1] == "bet":
|
||||
# firstPfRaiseByNo = i
|
||||
# firstPfRaiserId = action[0]
|
||||
# for j, pid in enumerate(player_ids):
|
||||
# if pid == firstPfRaiserId:
|
||||
# firstPfRaiserNo = j
|
||||
# break
|
||||
# break
|
||||
# for i, action in enumerate(actionTypeByNo[0]):
|
||||
# if action[1] == "call":
|
||||
# firstPfCallByNo = i
|
||||
# firstPfCallerId = action[0]
|
||||
# break
|
||||
# firstPlayId = firstPfCallerId
|
||||
# if firstPfRaiseByNo <> -1:
|
||||
# if firstPfRaiseByNo < firstPfCallByNo or firstPfCallByNo == -1:
|
||||
# firstPlayId = firstPfRaiserId
|
||||
#
|
||||
#
|
||||
# cutoffId=-1
|
||||
# buttonId=-1
|
||||
# sbId=-1
|
||||
# bbId=-1
|
||||
# if base=="hold":
|
||||
# for player, pos in enumerate(positions):
|
||||
# if pos == 1:
|
||||
# cutoffId = player_ids[player]
|
||||
# if pos == 0:
|
||||
# buttonId = player_ids[player]
|
||||
# if pos == 'S':
|
||||
# sbId = player_ids[player]
|
||||
# if pos == 'B':
|
||||
# bbId = player_ids[player]
|
||||
#
|
||||
# someoneStole=False
|
||||
#
|
||||
# #run a loop for each player preparing the actual values that will be commited to SQL
|
||||
# for player in xrange(len(player_ids)):
|
||||
# #set default values
|
||||
# myStreet0VPI=False
|
||||
# myStreet0Aggr=False
|
||||
# myStreet0_3BChance=False
|
||||
# myStreet0_3BDone=False
|
||||
# myStreet1Seen=False
|
||||
# myStreet2Seen=False
|
||||
# myStreet3Seen=False
|
||||
# myStreet4Seen=False
|
||||
# mySawShowdown=False
|
||||
# myStreet1Aggr=False
|
||||
# myStreet2Aggr=False
|
||||
# myStreet3Aggr=False
|
||||
# myStreet4Aggr=False
|
||||
# myOtherRaisedStreet1=False
|
||||
# myOtherRaisedStreet2=False
|
||||
# myOtherRaisedStreet3=False
|
||||
# myOtherRaisedStreet4=False
|
||||
# myFoldToOtherRaisedStreet1=False
|
||||
# myFoldToOtherRaisedStreet2=False
|
||||
# myFoldToOtherRaisedStreet3=False
|
||||
# myFoldToOtherRaisedStreet4=False
|
||||
# myWonWhenSeenStreet1=0.0
|
||||
# myWonAtSD=0.0
|
||||
# myStealAttemptChance=False
|
||||
# myStealAttempted=False
|
||||
# myStreet0Calls=0
|
||||
# myStreet1Calls=0
|
||||
# myStreet2Calls=0
|
||||
# myStreet3Calls=0
|
||||
# myStreet4Calls=0
|
||||
# myStreet0Bets=0
|
||||
# myStreet1Bets=0
|
||||
# myStreet2Bets=0
|
||||
# myStreet3Bets=0
|
||||
# myStreet4Bets=0
|
||||
# #myStreet0Raises=0
|
||||
# #myStreet1Raises=0
|
||||
# #myStreet2Raises=0
|
||||
# #myStreet3Raises=0
|
||||
# #myStreet4Raises=0
|
||||
#
|
||||
# #calculate VPIP and PFR
|
||||
# street=0
|
||||
# heroPfRaiseCount=0
|
||||
# for currentAction in action_types[street][player]: # finally individual actions
|
||||
# if currentAction == "bet":
|
||||
# myStreet0Aggr = True
|
||||
# if currentAction == "bet" or currentAction == "call":
|
||||
# myStreet0VPI = True
|
||||
#
|
||||
# if myStreet0VPI:
|
||||
# result['playersVpi'] += 1
|
||||
# myStreet0Calls = action_types[street][player].count('call')
|
||||
# myStreet0Bets = action_types[street][player].count('bet')
|
||||
# # street0Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||
# result['street0Raises'] += myStreet0Bets
|
||||
#
|
||||
# #PF3BChance and PF3B
|
||||
# pfFold=-1
|
||||
# pfRaise=-1
|
||||
# if firstPfRaiseByNo != -1:
|
||||
# for i, actionType in enumerate(actionTypeByNo[0]):
|
||||
# if actionType[0] == player_ids[player]:
|
||||
# if actionType[1] == "bet" and pfRaise == -1 and i > firstPfRaiseByNo:
|
||||
# pfRaise = i
|
||||
# if actionType[1] == "fold" and pfFold == -1:
|
||||
# pfFold = i
|
||||
# if pfFold == -1 or pfFold > firstPfRaiseByNo:
|
||||
# myStreet0_3BChance = True
|
||||
# if pfRaise > firstPfRaiseByNo:
|
||||
# myStreet0_3BDone = True
|
||||
#
|
||||
# #steal calculations
|
||||
# if base=="hold":
|
||||
# if len(player_ids)>=3: # no point otherwise # was 5, use 3 to match pokertracker definition
|
||||
# if positions[player]==1:
|
||||
# if firstPfRaiserId==player_ids[player] \
|
||||
# and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo):
|
||||
# myStealAttempted=True
|
||||
# myStealAttemptChance=True
|
||||
# if firstPlayId==cutoffId or firstPlayId==buttonId or firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1:
|
||||
# myStealAttemptChance=True
|
||||
# if positions[player]==0:
|
||||
# if firstPfRaiserId==player_ids[player] \
|
||||
# and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo):
|
||||
# myStealAttempted=True
|
||||
# myStealAttemptChance=True
|
||||
# if firstPlayId==buttonId or firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1:
|
||||
# myStealAttemptChance=True
|
||||
# if positions[player]=='S':
|
||||
# if firstPfRaiserId==player_ids[player] \
|
||||
# and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo):
|
||||
# myStealAttempted=True
|
||||
# myStealAttemptChance=True
|
||||
# if firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1:
|
||||
# myStealAttemptChance=True
|
||||
# if positions[player]=='B':
|
||||
# pass
|
||||
#
|
||||
# if myStealAttempted:
|
||||
# someoneStole=True
|
||||
#
|
||||
#
|
||||
# #calculate saw* values
|
||||
# isAllIn = False
|
||||
# if any(i for i in allIns[0][player]):
|
||||
# isAllIn = True
|
||||
# if (len(action_types[1][player])>0 or isAllIn):
|
||||
# myStreet1Seen = True
|
||||
#
|
||||
# if any(i for i in allIns[1][player]):
|
||||
# isAllIn = True
|
||||
# if (len(action_types[2][player])>0 or isAllIn):
|
||||
# myStreet2Seen = True
|
||||
#
|
||||
# if any(i for i in allIns[2][player]):
|
||||
# isAllIn = True
|
||||
# if (len(action_types[3][player])>0 or isAllIn):
|
||||
# myStreet3Seen = True
|
||||
#
|
||||
# #print "base:", base
|
||||
# if base=="hold":
|
||||
# mySawShowdown = True
|
||||
# if any(actiontype == "fold" for actiontype in action_types[3][player]):
|
||||
# mySawShowdown = False
|
||||
# else:
|
||||
# #print "in else"
|
||||
# if any(i for i in allIns[3][player]):
|
||||
# isAllIn = True
|
||||
# if (len(action_types[4][player])>0 or isAllIn):
|
||||
# #print "in if"
|
||||
# myStreet4Seen = True
|
||||
#
|
||||
# mySawShowdown = True
|
||||
# if any(actiontype == "fold" for actiontype in action_types[4][player]):
|
||||
# mySawShowdown = False
|
||||
#
|
||||
# if myStreet1Seen:
|
||||
# result['playersAtStreet1'] += 1
|
||||
# if myStreet2Seen:
|
||||
# result['playersAtStreet2'] += 1
|
||||
# if myStreet3Seen:
|
||||
# result['playersAtStreet3'] += 1
|
||||
# if myStreet4Seen:
|
||||
# result['playersAtStreet4'] += 1
|
||||
# if mySawShowdown:
|
||||
# result['playersAtShowdown'] += 1
|
||||
#
|
||||
# #flop stuff
|
||||
# street=1
|
||||
# if myStreet1Seen:
|
||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
||||
# myStreet1Aggr = True
|
||||
#
|
||||
# myStreet1Calls = action_types[street][player].count('call')
|
||||
# myStreet1Bets = action_types[street][player].count('bet')
|
||||
# # street1Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||
# result['street1Raises'] += myStreet1Bets
|
||||
#
|
||||
# for otherPlayer in xrange(len(player_ids)):
|
||||
# if player==otherPlayer:
|
||||
# pass
|
||||
# else:
|
||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
||||
# myOtherRaisedStreet1=True
|
||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
||||
# if action_types[street][player][countOtherFold]=="fold":
|
||||
# myFoldToOtherRaisedStreet1=True
|
||||
#
|
||||
# #turn stuff - copy of flop with different vars
|
||||
# street=2
|
||||
# if myStreet2Seen:
|
||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
||||
# myStreet2Aggr = True
|
||||
#
|
||||
# myStreet2Calls = action_types[street][player].count('call')
|
||||
# myStreet2Bets = action_types[street][player].count('bet')
|
||||
# # street2Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||
# result['street2Raises'] += myStreet2Bets
|
||||
#
|
||||
# for otherPlayer in xrange(len(player_ids)):
|
||||
# if player==otherPlayer:
|
||||
# pass
|
||||
# else:
|
||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
||||
# myOtherRaisedStreet2=True
|
||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
||||
# if action_types[street][player][countOtherFold]=="fold":
|
||||
# myFoldToOtherRaisedStreet2=True
|
||||
#
|
||||
# #river stuff - copy of flop with different vars
|
||||
# street=3
|
||||
# if myStreet3Seen:
|
||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
||||
# myStreet3Aggr = True
|
||||
#
|
||||
# myStreet3Calls = action_types[street][player].count('call')
|
||||
# myStreet3Bets = action_types[street][player].count('bet')
|
||||
# # street3Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||
# result['street3Raises'] += myStreet3Bets
|
||||
#
|
||||
# for otherPlayer in xrange(len(player_ids)):
|
||||
# if player==otherPlayer:
|
||||
# pass
|
||||
# else:
|
||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
||||
# myOtherRaisedStreet3=True
|
||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
||||
# if action_types[street][player][countOtherFold]=="fold":
|
||||
# myFoldToOtherRaisedStreet3=True
|
||||
#
|
||||
# #stud river stuff - copy of flop with different vars
|
||||
# street=4
|
||||
# if myStreet4Seen:
|
||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
||||
# myStreet4Aggr=True
|
||||
#
|
||||
# myStreet4Calls = action_types[street][player].count('call')
|
||||
# myStreet4Bets = action_types[street][player].count('bet')
|
||||
# # street4Raises = action_types[street][player].count('raise') bet count includes raises for now
|
||||
# result['street4Raises'] += myStreet4Bets
|
||||
#
|
||||
# for otherPlayer in xrange(len(player_ids)):
|
||||
# if player==otherPlayer:
|
||||
# pass
|
||||
# else:
|
||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
||||
# myOtherRaisedStreet4=True
|
||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
||||
# if action_types[street][player][countOtherFold]=="fold":
|
||||
# myFoldToOtherRaisedStreet4=True
|
||||
#
|
||||
# if winnings[player] != 0:
|
||||
# if myStreet1Seen:
|
||||
# myWonWhenSeenStreet1 = winnings[player] / float(totalWinnings)
|
||||
# if mySawShowdown:
|
||||
# myWonAtSD=myWonWhenSeenStreet1
|
||||
#
|
||||
# #add each value to the appropriate array
|
||||
# street0VPI.append(myStreet0VPI)
|
||||
# street0Aggr.append(myStreet0Aggr)
|
||||
# street0_3BChance.append(myStreet0_3BChance)
|
||||
# street0_3BDone.append(myStreet0_3BDone)
|
||||
# street1Seen.append(myStreet1Seen)
|
||||
# street2Seen.append(myStreet2Seen)
|
||||
# street3Seen.append(myStreet3Seen)
|
||||
# street4Seen.append(myStreet4Seen)
|
||||
# sawShowdown.append(mySawShowdown)
|
||||
# street1Aggr.append(myStreet1Aggr)
|
||||
# street2Aggr.append(myStreet2Aggr)
|
||||
# street3Aggr.append(myStreet3Aggr)
|
||||
# street4Aggr.append(myStreet4Aggr)
|
||||
# otherRaisedStreet1.append(myOtherRaisedStreet1)
|
||||
# otherRaisedStreet2.append(myOtherRaisedStreet2)
|
||||
# otherRaisedStreet3.append(myOtherRaisedStreet3)
|
||||
# otherRaisedStreet4.append(myOtherRaisedStreet4)
|
||||
# foldToOtherRaisedStreet1.append(myFoldToOtherRaisedStreet1)
|
||||
# foldToOtherRaisedStreet2.append(myFoldToOtherRaisedStreet2)
|
||||
# foldToOtherRaisedStreet3.append(myFoldToOtherRaisedStreet3)
|
||||
# foldToOtherRaisedStreet4.append(myFoldToOtherRaisedStreet4)
|
||||
# wonWhenSeenStreet1.append(myWonWhenSeenStreet1)
|
||||
# wonAtSD.append(myWonAtSD)
|
||||
# stealAttemptChance.append(myStealAttemptChance)
|
||||
# stealAttempted.append(myStealAttempted)
|
||||
# if base=="hold":
|
||||
# pos=positions[player]
|
||||
# if pos=='B':
|
||||
# hudDataPositions.append('B')
|
||||
# elif pos=='S':
|
||||
# hudDataPositions.append('S')
|
||||
# elif pos==0:
|
||||
# hudDataPositions.append('D')
|
||||
# elif pos==1:
|
||||
# hudDataPositions.append('C')
|
||||
# elif pos>=2 and pos<=4:
|
||||
# hudDataPositions.append('M')
|
||||
# elif pos>=5 and pos<=8:
|
||||
# hudDataPositions.append('E')
|
||||
# ### RHH Added this elif to handle being a dead hand before the BB (pos==9)
|
||||
# elif pos==9:
|
||||
# hudDataPositions.append('X')
|
||||
# else:
|
||||
# raise FpdbError("invalid position")
|
||||
# elif base=="stud":
|
||||
# #todo: stud positions and steals
|
||||
# pass
|
||||
#
|
||||
# street0Calls.append(myStreet0Calls)
|
||||
# street1Calls.append(myStreet1Calls)
|
||||
# street2Calls.append(myStreet2Calls)
|
||||
# street3Calls.append(myStreet3Calls)
|
||||
# street4Calls.append(myStreet4Calls)
|
||||
# street0Bets.append(myStreet0Bets)
|
||||
# street1Bets.append(myStreet1Bets)
|
||||
# street2Bets.append(myStreet2Bets)
|
||||
# street3Bets.append(myStreet3Bets)
|
||||
# street4Bets.append(myStreet4Bets)
|
||||
# #street0Raises.append(myStreet0Raises)
|
||||
# #street1Raises.append(myStreet1Raises)
|
||||
# #street2Raises.append(myStreet2Raises)
|
||||
# #street3Raises.append(myStreet3Raises)
|
||||
# #street4Raises.append(myStreet4Raises)
|
||||
#
|
||||
# #add each array to the to-be-returned dictionary
|
||||
# result['street0VPI']=street0VPI
|
||||
# result['street0Aggr']=street0Aggr
|
||||
# result['street0_3BChance']=street0_3BChance
|
||||
# result['street0_3BDone']=street0_3BDone
|
||||
# result['street1Seen']=street1Seen
|
||||
# result['street2Seen']=street2Seen
|
||||
# result['street3Seen']=street3Seen
|
||||
# result['street4Seen']=street4Seen
|
||||
# result['sawShowdown']=sawShowdown
|
||||
#
|
||||
# result['street1Aggr']=street1Aggr
|
||||
# result['otherRaisedStreet1']=otherRaisedStreet1
|
||||
# result['foldToOtherRaisedStreet1']=foldToOtherRaisedStreet1
|
||||
# result['street2Aggr']=street2Aggr
|
||||
# result['otherRaisedStreet2']=otherRaisedStreet2
|
||||
# result['foldToOtherRaisedStreet2']=foldToOtherRaisedStreet2
|
||||
# result['street3Aggr']=street3Aggr
|
||||
# result['otherRaisedStreet3']=otherRaisedStreet3
|
||||
# result['foldToOtherRaisedStreet3']=foldToOtherRaisedStreet3
|
||||
# result['street4Aggr']=street4Aggr
|
||||
# result['otherRaisedStreet4']=otherRaisedStreet4
|
||||
# result['foldToOtherRaisedStreet4']=foldToOtherRaisedStreet4
|
||||
# result['wonWhenSeenStreet1']=wonWhenSeenStreet1
|
||||
# result['wonAtSD']=wonAtSD
|
||||
# result['stealAttemptChance']=stealAttemptChance
|
||||
# result['stealAttempted']=stealAttempted
|
||||
# result['street0Calls']=street0Calls
|
||||
# result['street1Calls']=street1Calls
|
||||
# result['street2Calls']=street2Calls
|
||||
# result['street3Calls']=street3Calls
|
||||
# result['street4Calls']=street4Calls
|
||||
# result['street0Bets']=street0Bets
|
||||
# result['street1Bets']=street1Bets
|
||||
# result['street2Bets']=street2Bets
|
||||
# result['street3Bets']=street3Bets
|
||||
# result['street4Bets']=street4Bets
|
||||
# #result['street0Raises']=street0Raises
|
||||
# #result['street1Raises']=street1Raises
|
||||
# #result['street2Raises']=street2Raises
|
||||
# #result['street3Raises']=street3Raises
|
||||
# #result['street4Raises']=street4Raises
|
||||
#
|
||||
# #now the various steal values
|
||||
# foldBbToStealChance=[]
|
||||
# foldedBbToSteal=[]
|
||||
# foldSbToStealChance=[]
|
||||
# foldedSbToSteal=[]
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myFoldBbToStealChance=False
|
||||
# myFoldedBbToSteal=False
|
||||
# myFoldSbToStealChance=False
|
||||
# myFoldedSbToSteal=False
|
||||
#
|
||||
# if base=="hold":
|
||||
# if someoneStole and (positions[player]=='B' or positions[player]=='S') and firstPfRaiserId!=player_ids[player]:
|
||||
# street=0
|
||||
# for count in xrange(len(action_types[street][player])):#individual actions
|
||||
# if positions[player]=='B':
|
||||
# myFoldBbToStealChance=True
|
||||
# if action_types[street][player][count]=="fold":
|
||||
# myFoldedBbToSteal=True
|
||||
# if positions[player]=='S':
|
||||
# myFoldSbToStealChance=True
|
||||
# if action_types[street][player][count]=="fold":
|
||||
# myFoldedSbToSteal=True
|
||||
#
|
||||
#
|
||||
# foldBbToStealChance.append(myFoldBbToStealChance)
|
||||
# foldedBbToSteal.append(myFoldedBbToSteal)
|
||||
# foldSbToStealChance.append(myFoldSbToStealChance)
|
||||
# foldedSbToSteal.append(myFoldedSbToSteal)
|
||||
# result['foldBbToStealChance']=foldBbToStealChance
|
||||
# result['foldedBbToSteal']=foldedBbToSteal
|
||||
# result['foldSbToStealChance']=foldSbToStealChance
|
||||
# result['foldedSbToSteal']=foldedSbToSteal
|
||||
#
|
||||
# #now CB
|
||||
# street1CBChance=[]
|
||||
# street1CBDone=[]
|
||||
# didStreet1CB=[]
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myStreet1CBChance=False
|
||||
# myStreet1CBDone=False
|
||||
#
|
||||
# if street0VPI[player]:
|
||||
# myStreet1CBChance=True
|
||||
# if street1Aggr[player]:
|
||||
# myStreet1CBDone=True
|
||||
# didStreet1CB.append(player_ids[player])
|
||||
#
|
||||
# street1CBChance.append(myStreet1CBChance)
|
||||
# street1CBDone.append(myStreet1CBDone)
|
||||
# result['street1CBChance']=street1CBChance
|
||||
# result['street1CBDone']=street1CBDone
|
||||
#
|
||||
# #now 2B
|
||||
# street2CBChance=[]
|
||||
# street2CBDone=[]
|
||||
# didStreet2CB=[]
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myStreet2CBChance=False
|
||||
# myStreet2CBDone=False
|
||||
#
|
||||
# if street1CBDone[player]:
|
||||
# myStreet2CBChance=True
|
||||
# if street2Aggr[player]:
|
||||
# myStreet2CBDone=True
|
||||
# didStreet2CB.append(player_ids[player])
|
||||
#
|
||||
# street2CBChance.append(myStreet2CBChance)
|
||||
# street2CBDone.append(myStreet2CBDone)
|
||||
# result['street2CBChance']=street2CBChance
|
||||
# result['street2CBDone']=street2CBDone
|
||||
#
|
||||
# #now 3B
|
||||
# street3CBChance=[]
|
||||
# street3CBDone=[]
|
||||
# didStreet3CB=[]
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myStreet3CBChance=False
|
||||
# myStreet3CBDone=False
|
||||
#
|
||||
# if street2CBDone[player]:
|
||||
# myStreet3CBChance=True
|
||||
# if street3Aggr[player]:
|
||||
# myStreet3CBDone=True
|
||||
# didStreet3CB.append(player_ids[player])
|
||||
#
|
||||
# street3CBChance.append(myStreet3CBChance)
|
||||
# street3CBDone.append(myStreet3CBDone)
|
||||
# result['street3CBChance']=street3CBChance
|
||||
# result['street3CBDone']=street3CBDone
|
||||
#
|
||||
# #and 4B
|
||||
# street4CBChance=[]
|
||||
# street4CBDone=[]
|
||||
# didStreet4CB=[]
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myStreet4CBChance=False
|
||||
# myStreet4CBDone=False
|
||||
#
|
||||
# if street3CBDone[player]:
|
||||
# myStreet4CBChance=True
|
||||
# if street4Aggr[player]:
|
||||
# myStreet4CBDone=True
|
||||
# didStreet4CB.append(player_ids[player])
|
||||
#
|
||||
# street4CBChance.append(myStreet4CBChance)
|
||||
# street4CBDone.append(myStreet4CBDone)
|
||||
# result['street4CBChance']=street4CBChance
|
||||
# result['street4CBDone']=street4CBDone
|
||||
#
|
||||
#
|
||||
# result['position']=hudDataPositions
|
||||
#
|
||||
# foldToStreet1CBChance=[]
|
||||
# foldToStreet1CBDone=[]
|
||||
# foldToStreet2CBChance=[]
|
||||
# foldToStreet2CBDone=[]
|
||||
# foldToStreet3CBChance=[]
|
||||
# foldToStreet3CBDone=[]
|
||||
# foldToStreet4CBChance=[]
|
||||
# foldToStreet4CBDone=[]
|
||||
#
|
||||
# for player in xrange(len(player_ids)):
|
||||
# myFoldToStreet1CBChance=False
|
||||
# myFoldToStreet1CBDone=False
|
||||
# foldToStreet1CBChance.append(myFoldToStreet1CBChance)
|
||||
# foldToStreet1CBDone.append(myFoldToStreet1CBDone)
|
||||
#
|
||||
# myFoldToStreet2CBChance=False
|
||||
# myFoldToStreet2CBDone=False
|
||||
# foldToStreet2CBChance.append(myFoldToStreet2CBChance)
|
||||
# foldToStreet2CBDone.append(myFoldToStreet2CBDone)
|
||||
#
|
||||
# myFoldToStreet3CBChance=False
|
||||
# myFoldToStreet3CBDone=False
|
||||
# foldToStreet3CBChance.append(myFoldToStreet3CBChance)
|
||||
# foldToStreet3CBDone.append(myFoldToStreet3CBDone)
|
||||
#
|
||||
# myFoldToStreet4CBChance=False
|
||||
# myFoldToStreet4CBDone=False
|
||||
# foldToStreet4CBChance.append(myFoldToStreet4CBChance)
|
||||
# foldToStreet4CBDone.append(myFoldToStreet4CBDone)
|
||||
#
|
||||
# if len(didStreet1CB)>=1:
|
||||
# generateFoldToCB(1, player_ids, didStreet1CB, street1CBDone, foldToStreet1CBChance, foldToStreet1CBDone, actionTypeByNo)
|
||||
#
|
||||
# if len(didStreet2CB)>=1:
|
||||
# generateFoldToCB(2, player_ids, didStreet2CB, street2CBDone, foldToStreet2CBChance, foldToStreet2CBDone, actionTypeByNo)
|
||||
#
|
||||
# if len(didStreet3CB)>=1:
|
||||
# generateFoldToCB(3, player_ids, didStreet3CB, street3CBDone, foldToStreet3CBChance, foldToStreet3CBDone, actionTypeByNo)
|
||||
#
|
||||
# if len(didStreet4CB)>=1:
|
||||
# generateFoldToCB(4, player_ids, didStreet4CB, street4CBDone, foldToStreet4CBChance, foldToStreet4CBDone, actionTypeByNo)
|
||||
#
|
||||
# result['foldToStreet1CBChance']=foldToStreet1CBChance
|
||||
# result['foldToStreet1CBDone']=foldToStreet1CBDone
|
||||
# result['foldToStreet2CBChance']=foldToStreet2CBChance
|
||||
# result['foldToStreet2CBDone']=foldToStreet2CBDone
|
||||
# result['foldToStreet3CBChance']=foldToStreet3CBChance
|
||||
# result['foldToStreet3CBDone']=foldToStreet3CBDone
|
||||
# result['foldToStreet4CBChance']=foldToStreet4CBChance
|
||||
# result['foldToStreet4CBDone']=foldToStreet4CBDone
|
||||
#
|
||||
#
|
||||
# totalProfit=[]
|
||||
#
|
||||
# street1CheckCallRaiseChance=[]
|
||||
# street1CheckCallRaiseDone=[]
|
||||
# street2CheckCallRaiseChance=[]
|
||||
# street2CheckCallRaiseDone=[]
|
||||
# street3CheckCallRaiseChance=[]
|
||||
# street3CheckCallRaiseDone=[]
|
||||
# street4CheckCallRaiseChance=[]
|
||||
# street4CheckCallRaiseDone=[]
|
||||
# #print "b4 totprof calc, len(playerIds)=", len(player_ids)
|
||||
# for pl in xrange(len(player_ids)):
|
||||
# #print "pl=", pl
|
||||
# myTotalProfit=winnings[pl] # still need to deduct other costs
|
||||
# if antes:
|
||||
# myTotalProfit=winnings[pl] - antes[pl]
|
||||
# for i in xrange(len(actionTypes)): #iterate through streets
|
||||
# #for j in xrange(len(actionTypes[i])): #iterate through names (using pl loop above)
|
||||
# for k in xrange(len(actionTypes[i][pl])): #iterate through individual actions of that player on that street
|
||||
# myTotalProfit -= actionAmounts[i][pl][k]
|
||||
#
|
||||
# myStreet1CheckCallRaiseChance=False
|
||||
# myStreet1CheckCallRaiseDone=False
|
||||
# myStreet2CheckCallRaiseChance=False
|
||||
# myStreet2CheckCallRaiseDone=False
|
||||
# myStreet3CheckCallRaiseChance=False
|
||||
# myStreet3CheckCallRaiseDone=False
|
||||
# myStreet4CheckCallRaiseChance=False
|
||||
# myStreet4CheckCallRaiseDone=False
|
||||
#
|
||||
# #print "myTotalProfit=", myTotalProfit
|
||||
# totalProfit.append(myTotalProfit)
|
||||
# #print "totalProfit[]=", totalProfit
|
||||
#
|
||||
# street1CheckCallRaiseChance.append(myStreet1CheckCallRaiseChance)
|
||||
# street1CheckCallRaiseDone.append(myStreet1CheckCallRaiseDone)
|
||||
# street2CheckCallRaiseChance.append(myStreet2CheckCallRaiseChance)
|
||||
# street2CheckCallRaiseDone.append(myStreet2CheckCallRaiseDone)
|
||||
# street3CheckCallRaiseChance.append(myStreet3CheckCallRaiseChance)
|
||||
# street3CheckCallRaiseDone.append(myStreet3CheckCallRaiseDone)
|
||||
# street4CheckCallRaiseChance.append(myStreet4CheckCallRaiseChance)
|
||||
# street4CheckCallRaiseDone.append(myStreet4CheckCallRaiseDone)
|
||||
#
|
||||
# result['totalProfit']=totalProfit
|
||||
# #print "res[totalProfit]=", result['totalProfit']
|
||||
#
|
||||
# result['street1CheckCallRaiseChance']=street1CheckCallRaiseChance
|
||||
# result['street1CheckCallRaiseDone']=street1CheckCallRaiseDone
|
||||
# result['street2CheckCallRaiseChance']=street2CheckCallRaiseChance
|
||||
# result['street2CheckCallRaiseDone']=street2CheckCallRaiseDone
|
||||
# result['street3CheckCallRaiseChance']=street3CheckCallRaiseChance
|
||||
# result['street3CheckCallRaiseDone']=street3CheckCallRaiseDone
|
||||
# result['street4CheckCallRaiseChance']=street4CheckCallRaiseChance
|
||||
# result['street4CheckCallRaiseDone']=street4CheckCallRaiseDone
|
||||
# return result
|
||||
# #end def generateHudCacheData
|
||||
pass
|
||||
|
||||
def vpip(self, hand):
|
||||
|
@ -834,14 +162,19 @@ class DerivedStats():
|
|||
self.hands['playersAtStreet4'] = 0
|
||||
self.hands['playersAtShowdown'] = 0
|
||||
|
||||
alliners = set()
|
||||
for (i, street) in enumerate(hand.actionStreets[2:]):
|
||||
actors = {}
|
||||
for act in hand.actions[street]:
|
||||
actors[act[0]] = 1
|
||||
self.hands['playersAtStreet%s' % str(i+1)] = len(actors.keys())
|
||||
|
||||
#Need playersAtShowdown
|
||||
actors = set()
|
||||
for action in hand.actions[street]:
|
||||
if len(action) > 2 and action[-1]: # allin
|
||||
alliners.add(action[0])
|
||||
actors.add(action[0])
|
||||
if len(actors)==0 and len(alliners)<2:
|
||||
alliners = set()
|
||||
self.hands['playersAtStreet%d' % (i+1)] = len(set.union(alliners, actors))
|
||||
|
||||
actions = hand.actions[hand.actionStreets[-1]]
|
||||
self.hands['playersAtShowdown'] = len(set.union(self.pfba(actions) - self.pfba(actions, l=('folds',)), alliners))
|
||||
|
||||
def streetXRaises(self, hand):
|
||||
# self.actions[street] is a list of all actions in a tuple, contining the action as the second element
|
||||
|
@ -849,11 +182,11 @@ class DerivedStats():
|
|||
# No idea what this value is actually supposed to be
|
||||
# In theory its "num small bets paid to see flop/street4, including blind" which makes sense for limit. Not so useful for nl
|
||||
# Leaving empty for the moment,
|
||||
self.hands['street0Raises'] = 0 # /* num small bets paid to see flop/street4, including blind */
|
||||
self.hands['street1Raises'] = 0 # /* num small bets paid to see turn/street5 */
|
||||
self.hands['street2Raises'] = 0 # /* num big bets paid to see river/street6 */
|
||||
self.hands['street3Raises'] = 0 # /* num big bets paid to see sd/street7 */
|
||||
self.hands['street4Raises'] = 0 # /* num big bets paid to see showdown */
|
||||
|
||||
for i in range(5): self.hands['street%dRaises' % i] = 0
|
||||
|
||||
for (i, street) in enumerate(hand.actionStreets[1:]):
|
||||
self.hands['street%dRaises' % i] = len(filter( lambda action: action[1] in ('raises','bets'), hand.actions[street]))
|
||||
|
||||
def seen(self, hand, i):
|
||||
pas = set()
|
||||
|
@ -880,3 +213,16 @@ class DerivedStats():
|
|||
|
||||
def countPlayers(self, hand):
|
||||
pass
|
||||
|
||||
def pfba(self, actions, f=None, l=None):
|
||||
"""Helper method. Returns set of PlayersFilteredByActions
|
||||
|
||||
f - forbidden actions
|
||||
l - limited to actions
|
||||
"""
|
||||
players = set()
|
||||
for action in actions:
|
||||
if l is not None and action[1] not in l: continue
|
||||
if f is not None and action[1] in f: continue
|
||||
players.add(action[0])
|
||||
return players
|
||||
|
|
|
@ -4,7 +4,7 @@ class FpdbError(Exception):
|
|||
def __str__(self):
|
||||
return repr(self.value)
|
||||
|
||||
class FpdbParseError(FpdbError):
|
||||
class FpdbParseError(FpdbError):
|
||||
def __init__(self,value='',hid=''):
|
||||
self.value = value
|
||||
self.hid = hid
|
||||
|
@ -17,8 +17,15 @@ class FpdbParseError(FpdbError):
|
|||
class FpdbDatabaseError(FpdbError):
|
||||
pass
|
||||
|
||||
class FpdbMySQLFailedError(FpdbDatabaseError):
|
||||
class FpdbMySQLError(FpdbDatabaseError):
|
||||
pass
|
||||
|
||||
class FpdbMySQLAccessDenied(FpdbDatabaseError):
|
||||
def __init__(self, value='', errmsg=''):
|
||||
self.value = value
|
||||
self.errmsg = errmsg
|
||||
def __str__(self):
|
||||
return repr(self.value +" " + self.errmsg)
|
||||
|
||||
class DuplicateError(FpdbError):
|
||||
pass
|
||||
|
|
|
@ -53,7 +53,7 @@ class GuiBulkImport():
|
|||
# Does the lock acquisition need to be more sophisticated for multiple dirs?
|
||||
# (see comment above about what to do if pipe already open)
|
||||
if self.settings['global_lock'].acquire(False): # returns false immediately if lock not acquired
|
||||
try:
|
||||
#try:
|
||||
print "\nGlobal lock taken ..."
|
||||
self.progressbar.set_text("Importing...")
|
||||
self.progressbar.pulse()
|
||||
|
@ -116,10 +116,11 @@ class GuiBulkImport():
|
|||
|
||||
self.progressbar.set_text("Import Complete")
|
||||
self.progressbar.set_fraction(0)
|
||||
except:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "*** BulkImport Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
self.settings['global_lock'].release()
|
||||
#except:
|
||||
#err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
#print "*** BulkImport Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
#self.settings['global_lock'].release()
|
||||
self.settings['global_lock'].release()
|
||||
else:
|
||||
print "bulk-import aborted - global lock not available"
|
||||
|
||||
|
|
|
@ -216,6 +216,7 @@ class GuiGraphViewer (threading.Thread):
|
|||
#nametest = nametest.replace("L", "")
|
||||
|
||||
lims = [int(x) for x in limits if x.isdigit()]
|
||||
potlims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'pl']
|
||||
nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl']
|
||||
limittest = "and ( (gt.limitType = 'fl' and gt.bigBlind in "
|
||||
# and ( (limit and bb in()) or (nolimit and bb in ()) )
|
||||
|
@ -226,6 +227,14 @@ class GuiGraphViewer (threading.Thread):
|
|||
limittest = limittest + blindtest + ' ) '
|
||||
else:
|
||||
limittest = limittest + '(-1) ) '
|
||||
limittest = limittest + " or (gt.limitType = 'pl' and gt.bigBlind in "
|
||||
if potlims:
|
||||
blindtest = str(tuple(potlims))
|
||||
blindtest = blindtest.replace("L", "")
|
||||
blindtest = blindtest.replace(",)",")")
|
||||
limittest = limittest + blindtest + ' ) '
|
||||
else:
|
||||
limittest = limittest + '(-1) ) '
|
||||
limittest = limittest + " or (gt.limitType = 'nl' and gt.bigBlind in "
|
||||
if nolims:
|
||||
blindtest = str(tuple(nolims))
|
||||
|
@ -234,6 +243,7 @@ class GuiGraphViewer (threading.Thread):
|
|||
limittest = limittest + blindtest + ' ) )'
|
||||
else:
|
||||
limittest = limittest + '(-1) ) )'
|
||||
|
||||
if type == 'ring':
|
||||
limittest = limittest + " and gt.type = 'ring' "
|
||||
elif type == 'tour':
|
||||
|
|
|
@ -480,6 +480,7 @@ class GuiPlayerStats (threading.Thread):
|
|||
query = query.replace('<orderbyseats>', '')
|
||||
|
||||
lims = [int(x) for x in limits if x.isdigit()]
|
||||
potlims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'pl']
|
||||
nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl']
|
||||
bbtest = "and ( (gt.limitType = 'fl' and gt.bigBlind in "
|
||||
# and ( (limit and bb in()) or (nolimit and bb in ()) )
|
||||
|
@ -490,6 +491,14 @@ class GuiPlayerStats (threading.Thread):
|
|||
bbtest = bbtest + blindtest + ' ) '
|
||||
else:
|
||||
bbtest = bbtest + '(-1) ) '
|
||||
bbtest = bbtest + " or (gt.limitType = 'pl' and gt.bigBlind in "
|
||||
if potlims:
|
||||
blindtest = str(tuple(potlims))
|
||||
blindtest = blindtest.replace("L", "")
|
||||
blindtest = blindtest.replace(",)",")")
|
||||
bbtest = bbtest + blindtest + ' ) '
|
||||
else:
|
||||
bbtest = bbtest + '(-1) ) '
|
||||
bbtest = bbtest + " or (gt.limitType = 'nl' and gt.bigBlind in "
|
||||
if nolims:
|
||||
blindtest = str(tuple(nolims))
|
||||
|
@ -544,7 +553,7 @@ class GuiPlayerStats (threading.Thread):
|
|||
# set flag in self.columns to show posn column
|
||||
[x for x in self.columns if x[0] == 'plposition'][0][1] = True
|
||||
else:
|
||||
query = query.replace("<position>", "'1'")
|
||||
query = query.replace("<position>", "gt.base")
|
||||
# unset flag in self.columns to hide posn column
|
||||
[x for x in self.columns if x[0] == 'plposition'][0][1] = False
|
||||
|
||||
|
|
|
@ -4,91 +4,95 @@
|
|||
|
||||
<import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True"></import>
|
||||
|
||||
<!-- These values need some explaining
|
||||
<!-- These values determine what stats are displayed in the HUD
|
||||
|
||||
aggregate_ring_game_stats :
|
||||
The following values define how opponents' stats are done, the first 2 determine
|
||||
the time period stats are displayed for, the next 3 determine what blind levels
|
||||
are included (i.e. aggregated):
|
||||
|
||||
stat_range :
|
||||
- A/S/T
|
||||
- if set to A, includes stats from all time
|
||||
- if set to S, includes stats from current session
|
||||
- if set to T, includes stats from last N days; set value in stat_days
|
||||
- defaults to A
|
||||
|
||||
stat_days :
|
||||
- a numeric value
|
||||
- only used if stat_range is set to 'T', this value tells how many days are
|
||||
included in the stat calculation
|
||||
- defaults to 90
|
||||
- value not used by default as it depends on stat_range setting
|
||||
|
||||
aggregate_ring_game_stats :
|
||||
- True/False
|
||||
- if set to True, includes data from other blind levels
|
||||
- if set to True, opponents stats include other blind levels during ring games
|
||||
- defaults to False
|
||||
|
||||
aggregate_tourney_stats :
|
||||
- True/False
|
||||
- if set to True, includes data from other blind levels
|
||||
- if set to True, opponents stats include other blind levels during tourneys
|
||||
- defaults to True
|
||||
|
||||
stat_aggregation_range :
|
||||
- A/S/T
|
||||
- if set to A, includes stats from all time
|
||||
- if set to S, includes stats from current sessions
|
||||
- if set to T, includes stats from last N days; set value in hud_days
|
||||
- defaults to A
|
||||
|
||||
aggregation_days :
|
||||
- a numeric value
|
||||
- if hud_style is set to 'T', this value tells how many days are
|
||||
included in the stat calculation
|
||||
- defaults to 90
|
||||
- value not used by default, as depends on hud_style setting
|
||||
|
||||
aggregation_level_multiplier :
|
||||
- float value
|
||||
- defines how many blind levels are used for aggregation
|
||||
- the logic is weird, at best
|
||||
- if value is 100, almost all levels are included
|
||||
- if value is 2.1, levels from half to double the current blind
|
||||
level are included
|
||||
- if value it 1, no aggregation is performed
|
||||
- defaults to 1
|
||||
- defines how many blind levels are included in stats displayed in HUD
|
||||
- if value is M, stats for blind levels are combined if the higher level
|
||||
is less than or equal to M times the lower blind level
|
||||
- defaults to 3, meaning blind levels from 1/3 of the current level to 3
|
||||
times the current level are included in the stats displayed in the HUD
|
||||
- e.g. if current big blind is 50, stats for blind levels from big blind
|
||||
of 16.7 (50 divided by 3) to big blind of 150 (50 times 3) are included
|
||||
|
||||
|
||||
The following values define how hero's stats are done
|
||||
The following values define how hero's stats are done, the first 2 determine
|
||||
the time period stats are displayed for, the next 3 determine what blind levels
|
||||
are included (i.e. aggregated):
|
||||
|
||||
hero_stat_range :
|
||||
- A/S/T
|
||||
- if set to A, includes stats from all time
|
||||
- if set to S, includes stats from current session
|
||||
- if set to T, includes stats from last N days; set value in hero_stat_days
|
||||
- defaults to S
|
||||
|
||||
hero_stat_days :
|
||||
- a numeric value
|
||||
- if hero_stat_range is set to 'T', this value tells how many days are
|
||||
included in the stat calculation
|
||||
- defaults to 30
|
||||
- value not used by default as it depends on hero_stat_range setting
|
||||
|
||||
aggregate_hero_ring_game_stats :
|
||||
- True/False
|
||||
- if set to True, hero's data is calculated over multiple blind levels
|
||||
- if set to True, hero's stats are calculated over multiple blind levels
|
||||
- defaults to False
|
||||
|
||||
aggregate_hero_tourney_stats :
|
||||
- True/False
|
||||
- if set to True, hero's data is calculated over multiple blind levels
|
||||
- if set to True, hero's stats are calculated over multiple blind levels
|
||||
- defaults to False
|
||||
|
||||
hero_stat_aggregation_range :
|
||||
- A/S/T
|
||||
- if set to A, includes stats from all time
|
||||
- if set to S, includes stats from current sessions
|
||||
- if set to T, includes stats from last N days; set value in hud_days
|
||||
- defaults to S
|
||||
|
||||
hero_aggregation_days :
|
||||
- a numeric value
|
||||
- if hero_stat_aggregation_range is set to 'T', this value tells
|
||||
how many days are included in the stat calculation
|
||||
- defaults to 30
|
||||
- value not used by default, as depends on hud_style setting
|
||||
|
||||
hero_aggregation_level_multiplier :
|
||||
- float value
|
||||
- defines how many blind levels are used for aggregation
|
||||
- the logic is weird, at best
|
||||
- if value is 100, almost all levels are included
|
||||
- if value is 2.1, levels from half to double the current blind
|
||||
level are included
|
||||
- if value it 1, no aggregation is performed
|
||||
- defaults to 1
|
||||
- defines how many blind levels are included in stats displayed in HUD
|
||||
- if value is M, stats for blind levels are combined if the higher level
|
||||
is less than or equal to M times the lower blind level
|
||||
- defaults to 1, meaning only stats from current blind level are included
|
||||
- e.g. if set to 3 and current big blind is 50, stats for blind levels from
|
||||
16.7 (50 divided by 3) to big blind of 150 (50 times 3) are included
|
||||
-->
|
||||
<hud_ui
|
||||
stat_range="A"
|
||||
stat_days="90"
|
||||
aggregate_ring_game_stats="False"
|
||||
aggregate_tourney_stats="False"
|
||||
stat_aggregation_range="A"
|
||||
aggregation_days="90"
|
||||
aggregation_level_multiplier="1"
|
||||
aggregate_tourney_stats="True"
|
||||
aggregation_level_multiplier="3"
|
||||
|
||||
hero_stat_range="S"
|
||||
hero_stat_days="30"
|
||||
aggregate_hero_ring_game_stats="False"
|
||||
aggregate_hero_tourney_stats="True"
|
||||
hero_stat_aggregation_range="S"
|
||||
hero_aggregation_days="30"
|
||||
aggregate_hero_tourney_stats="False"
|
||||
hero_aggregation_level_multiplier="1"
|
||||
|
||||
label="FPDB Menu - Right-click
|
||||
|
|
|
@ -5,17 +5,17 @@
|
|||
Main for FreePokerTools HUD.
|
||||
"""
|
||||
# Copyright 2008, 2009, 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
|
||||
|
@ -33,7 +33,7 @@ import os
|
|||
import Options
|
||||
import traceback
|
||||
|
||||
(options, sys.argv) = Options.fpdb_options()
|
||||
(options, argv) = Options.fpdb_options()
|
||||
|
||||
if not options.errorsToConsole:
|
||||
print "Note: error output is being logged. Any major error will be reported there _only_."
|
||||
|
@ -68,34 +68,6 @@ elif os.name == 'nt':
|
|||
import Hud
|
||||
|
||||
|
||||
# HUD params:
|
||||
# - Set aggregate_ring and/or aggregate_tour to True is you want to include stats from other blind levels in the HUD display
|
||||
# - If aggregation is used, the value of agg_bb_mult determines what levels are included. If
|
||||
# agg_bb_mult is M and current blind level is L, blinds between L/M and L*M are included. e.g.
|
||||
# if agg_bb_mult is 100, almost all levels are included in all HUD displays
|
||||
# if agg_bb_mult is 2, levels from half to double the current blind level are included in the HUD
|
||||
# if agg_bb_mult is 1 only the current level is included
|
||||
# - Set hud_style to A to see stats for all-time
|
||||
# Set hud_style to S to only see stats for current session (currently this shows stats for the last 24 hours)
|
||||
# Set hud_style to T to only see stats for the last N days (uses value in hud_days)
|
||||
# - Set hud_days to N to see stats for the last N days in the HUD (only applies if hud_style is T)
|
||||
def_hud_params = { # Settings for all players apart from program owner ('hero')
|
||||
'aggregate_ring' : False
|
||||
, 'aggregate_tour' : True
|
||||
, 'hud_style' : 'A'
|
||||
, 'hud_days' : 90
|
||||
, 'agg_bb_mult' : 10000 # 1 means no aggregation
|
||||
# , 'hud_session_gap' : 30 not currently used
|
||||
# Second set of variables for hero - these settings only apply to the program owner
|
||||
, 'h_aggregate_ring' : False
|
||||
, 'h_aggregate_tour' : True
|
||||
, 'h_hud_style' : 'S' # A(ll) / S(ession) / T(ime in days)
|
||||
, 'h_hud_days' : 60
|
||||
, 'h_agg_bb_mult' : 10000 # 1 means no aggregation
|
||||
# , 'h_hud_session_gap' : 30 not currently used
|
||||
}
|
||||
|
||||
|
||||
class HUD_main(object):
|
||||
"""A main() object to own both the read_stdin thread and the gui."""
|
||||
# This class mainly provides state for controlling the multiple HUDs.
|
||||
|
@ -136,20 +108,20 @@ class HUD_main(object):
|
|||
|
||||
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, type, stat_dict, cards):
|
||||
"""type is "ring" or "tour" used to set hud_params"""
|
||||
|
||||
|
||||
def idle_func():
|
||||
|
||||
|
||||
gtk.gdk.threads_enter()
|
||||
try: # TODO: seriously need to decrease the scope of this block.. what are we expecting to error?
|
||||
# TODO: The purpose of this try/finally block is to make darn sure that threads_leave()
|
||||
# TODO: gets called. If there is an exception and threads_leave() doesn't get called we
|
||||
# TODO: gets called. If there is an exception and threads_leave() doesn't get called we
|
||||
# TODO: lock up. REB
|
||||
table.gdkhandle = gtk.gdk.window_foreign_new(table.number)
|
||||
newlabel = gtk.Label("%s - %s" % (table.site, table_name))
|
||||
self.vb.add(newlabel)
|
||||
newlabel.show()
|
||||
self.main_window.resize_children()
|
||||
|
||||
|
||||
self.hud_dict[table_name].tablehudlabel = newlabel
|
||||
self.hud_dict[table_name].create(new_hand_id, self.config, stat_dict, cards)
|
||||
for m in self.hud_dict[table_name].aux_windows:
|
||||
|
@ -166,6 +138,8 @@ class HUD_main(object):
|
|||
self.hud_dict[table_name].stat_dict = stat_dict
|
||||
self.hud_dict[table_name].cards = cards
|
||||
|
||||
# set agg_bb_mult so that aggregate_tour and aggregate_ring can be ignored,
|
||||
# agg_bb_mult == 1 means no aggregation after these if statements:
|
||||
if type == "tour" and self.hud_params['aggregate_tour'] == False:
|
||||
self.hud_dict[table_name].hud_params['agg_bb_mult'] = 1
|
||||
elif type == "ring" and self.hud_params['aggregate_ring'] == False:
|
||||
|
@ -174,16 +148,21 @@ class HUD_main(object):
|
|||
self.hud_dict[table_name].hud_params['h_agg_bb_mult'] = 1
|
||||
elif type == "ring" and self.hud_params['h_aggregate_ring'] == False:
|
||||
self.hud_dict[table_name].hud_params['h_agg_bb_mult'] = 1
|
||||
# sqlcoder: I forget why these are set to true (aren't they ignored from now on?)
|
||||
# but I think it's needed:
|
||||
self.hud_params['aggregate_ring'] == True
|
||||
self.hud_params['h_aggregate_ring'] == True
|
||||
# so maybe the tour ones should be set as well? does this fix the bug I see mentioned?
|
||||
self.hud_params['aggregate_tour'] = True
|
||||
self.hud_params['h_aggregate_tour'] == True
|
||||
|
||||
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[table_name].aux_windows]
|
||||
gobject.idle_add(idle_func)
|
||||
|
||||
|
||||
def update_HUD(self, new_hand_id, table_name, config):
|
||||
"""Update a HUD gui from inside the non-gui read_stdin thread."""
|
||||
# This is written so that only 1 thread can touch the gui--mainly
|
||||
# for compatibility with Windows. This method dispatches the
|
||||
# for compatibility with Windows. This method dispatches the
|
||||
# function idle_func() to be run by the gui thread, at its leisure.
|
||||
def idle_func():
|
||||
gtk.gdk.threads_enter()
|
||||
|
@ -193,9 +172,9 @@ class HUD_main(object):
|
|||
finally:
|
||||
gtk.gdk.threads_leave()
|
||||
return False
|
||||
|
||||
|
||||
gobject.idle_add(idle_func)
|
||||
|
||||
|
||||
def read_stdin(self): # This is the thread function
|
||||
"""Do all the non-gui heavy lifting for the HUD program."""
|
||||
|
||||
|
@ -204,6 +183,7 @@ class HUD_main(object):
|
|||
# need their own access to the database, but should open their own
|
||||
# if it is required.
|
||||
self.db_connection = Database.Database(self.config)
|
||||
|
||||
# get hero's screen names and player ids
|
||||
self.hero, self.hero_ids = {}, {}
|
||||
for site in self.config.get_supported_sites():
|
||||
|
@ -237,7 +217,7 @@ class HUD_main(object):
|
|||
|
||||
# Update an existing HUD
|
||||
if temp_key in self.hud_dict:
|
||||
# get stats using hud's specific params and get cards
|
||||
# get stats using hud's specific params and get cards
|
||||
self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days']
|
||||
, self.hud_dict[temp_key].hud_params['h_hud_days'])
|
||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_dict[temp_key].hud_params, self.hero_ids[site_id])
|
||||
|
@ -249,7 +229,7 @@ class HUD_main(object):
|
|||
self.hud_dict[temp_key].cards = cards
|
||||
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows]
|
||||
self.update_HUD(new_hand_id, temp_key, self.config)
|
||||
|
||||
|
||||
# Or create a new HUD
|
||||
else:
|
||||
# get stats using default params--also get cards
|
||||
|
|
|
@ -23,20 +23,20 @@ def fpdb_options():
|
|||
|
||||
"""Process command line options for fpdb and HUD_main."""
|
||||
parser = OptionParser()
|
||||
parser.add_option("-x", "--errorsToConsole",
|
||||
action="store_true",
|
||||
parser.add_option("-x", "--errorsToConsole",
|
||||
action="store_true",
|
||||
help="If passed error output will go to the console rather than .")
|
||||
parser.add_option("-d", "--databaseName",
|
||||
parser.add_option("-d", "--databaseName",
|
||||
dest="dbname", default="fpdb",
|
||||
help="Overrides the default database name")
|
||||
parser.add_option("-c", "--configFile",
|
||||
parser.add_option("-c", "--configFile",
|
||||
dest="config", default=None,
|
||||
help="Specifies a configuration file.")
|
||||
parser.add_option("-r", "--rerunPython",
|
||||
action="store_true",
|
||||
parser.add_option("-r", "--rerunPython",
|
||||
action="store_true",
|
||||
help="Indicates program was restarted with a different path (only allowed once).")
|
||||
(options, sys.argv) = parser.parse_args()
|
||||
return (options, sys.argv)
|
||||
(options, argv) = parser.parse_args()
|
||||
return (options, argv)
|
||||
|
||||
if __name__== "__main__":
|
||||
(options, sys.argv) = fpdb_options()
|
||||
|
@ -45,4 +45,4 @@ if __name__== "__main__":
|
|||
print "config file =", options.config
|
||||
|
||||
print "press enter to end"
|
||||
sys.stdin.readline()
|
||||
sys.stdin.readline()
|
||||
|
|
|
@ -31,18 +31,18 @@ class PokerStars(HandHistoryConverter):
|
|||
|
||||
sitename = "PokerStars"
|
||||
filetype = "text"
|
||||
codepage = "cp1252"
|
||||
codepage = ("utf8", "cp1252")
|
||||
siteId = 2 # Needs to match id entry in Sites database
|
||||
|
||||
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'} # Legal mixed games
|
||||
sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\x80", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE
|
||||
sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\xe2\x82\xac", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE
|
||||
substitutions = {
|
||||
'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes
|
||||
'LS' : "\$|\x80|\xa3" # legal currency symbols ADD Euro, Sterling, etc HERE
|
||||
'LS' : "\$|\xe2\x82\xac|" # legal currency symbols - Euro(cp1252, utf-8)
|
||||
}
|
||||
|
||||
# Static regexes
|
||||
re_GameInfo = re.compile("""
|
||||
re_GameInfo = re.compile(u"""
|
||||
PokerStars\sGame\s\#(?P<HID>[0-9]+):\s+
|
||||
(Tournament\s\# # open paren of tournament info
|
||||
(?P<TOURNO>\d+),\s
|
||||
|
@ -62,7 +62,7 @@ class PokerStars(HandHistoryConverter):
|
|||
(?P<DATETIME>.*$)""" % substitutions,
|
||||
re.MULTILINE|re.VERBOSE)
|
||||
|
||||
re_PlayerInfo = re.compile("""
|
||||
re_PlayerInfo = re.compile(u"""
|
||||
^Seat\s(?P<SEAT>[0-9]+):\s
|
||||
(?P<PNAME>.*)\s
|
||||
\((%(LS)s)?(?P<CASH>[.0-9]+)\sin\schips\)""" % substitutions,
|
||||
|
@ -373,12 +373,9 @@ if __name__ == "__main__":
|
|||
parser.add_option("-i", "--input", dest="ipath", help="parse input hand history", default="regression-test-files/stars/horse/HH20090226 Natalie V - $0.10-$0.20 - HORSE.txt")
|
||||
parser.add_option("-o", "--output", dest="opath", help="output translation to", default="-")
|
||||
parser.add_option("-f", "--follow", dest="follow", help="follow (tail -f) the input", action="store_true", default=False)
|
||||
parser.add_option("-q", "--quiet",
|
||||
action="store_const", const=logging.CRITICAL, dest="verbosity", default=logging.INFO)
|
||||
parser.add_option("-v", "--verbose",
|
||||
action="store_const", const=logging.INFO, dest="verbosity")
|
||||
parser.add_option("--vv",
|
||||
action="store_const", const=logging.DEBUG, dest="verbosity")
|
||||
#parser.add_option("-q", "--quiet", action="store_const", const=logging.CRITICAL, dest="verbosity", default=logging.INFO)
|
||||
#parser.add_option("-v", "--verbose", action="store_const", const=logging.INFO, dest="verbosity")
|
||||
#parser.add_option("--vv", action="store_const", const=logging.DEBUG, dest="verbosity")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
|
|
269
pyfpdb/SQL.py
269
pyfpdb/SQL.py
|
@ -1940,7 +1940,7 @@ class Sql:
|
|||
and h.seats <seats_test>
|
||||
<flagtest>
|
||||
<gtbigBlind_test>
|
||||
and to_char(h.handStart, 'YYYY-MM-DD') <datestest>
|
||||
and date(h.handStart) <datestest>
|
||||
group by hgameTypeId
|
||||
,hp.playerId
|
||||
,gt.base
|
||||
|
@ -1960,272 +1960,7 @@ class Sql:
|
|||
end
|
||||
<orderbyhgameTypeId>
|
||||
,upper(gt.limitType) desc
|
||||
,maxbigblind desc
|
||||
,s.name
|
||||
"""
|
||||
|
||||
if db_server == 'mysql':
|
||||
self.query['playerStats'] = """
|
||||
SELECT
|
||||
concat(upper(stats.limitType), ' '
|
||||
,concat(upper(substring(stats.category,1,1)),substring(stats.category,2) ), ' '
|
||||
,stats.name, ' '
|
||||
,cast(stats.bigBlindDesc as char)
|
||||
) AS Game
|
||||
,stats.n
|
||||
,stats.vpip
|
||||
,stats.pfr
|
||||
,stats.pf3
|
||||
,stats.steals
|
||||
,stats.saw_f
|
||||
,stats.sawsd
|
||||
,stats.wtsdwsf
|
||||
,stats.wmsd
|
||||
,stats.FlAFq
|
||||
,stats.TuAFq
|
||||
,stats.RvAFq
|
||||
,stats.PoFAFq
|
||||
,stats.Net
|
||||
,stats.BBper100
|
||||
,stats.Profitperhand
|
||||
,case when hprof2.variance = -999 then '-'
|
||||
else format(hprof2.variance, 2)
|
||||
end AS Variance
|
||||
,stats.AvgSeats
|
||||
FROM
|
||||
(select /* stats from hudcache */
|
||||
gt.base
|
||||
,gt.category
|
||||
,upper(gt.limitType) as limitType
|
||||
,s.name
|
||||
,<selectgt.bigBlind> AS bigBlindDesc
|
||||
,<hcgametypeId> AS gtId
|
||||
,sum(HDs) AS n
|
||||
,format(100.0*sum(street0VPI)/sum(HDs),1) AS vpip
|
||||
,format(100.0*sum(street0Aggr)/sum(HDs),1) AS pfr
|
||||
,case when sum(street0_3Bchance) = 0 then '0'
|
||||
else format(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),1)
|
||||
end AS pf3
|
||||
,case when sum(stealattemptchance) = 0 then '-'
|
||||
else format(100.0*sum(stealattempted)/sum(stealattemptchance),1)
|
||||
end AS steals
|
||||
,format(100.0*sum(street1Seen)/sum(HDs),1) AS saw_f
|
||||
,format(100.0*sum(sawShowdown)/sum(HDs),1) AS sawsd
|
||||
,case when sum(street1Seen) = 0 then '-'
|
||||
else format(100.0*sum(sawShowdown)/sum(street1Seen),1)
|
||||
end AS wtsdwsf
|
||||
,case when sum(sawShowdown) = 0 then '-'
|
||||
else format(100.0*sum(wonAtSD)/sum(sawShowdown),1)
|
||||
end AS wmsd
|
||||
,case when sum(street1Seen) = 0 then '-'
|
||||
else format(100.0*sum(street1Aggr)/sum(street1Seen),1)
|
||||
end AS FlAFq
|
||||
,case when sum(street2Seen) = 0 then '-'
|
||||
else format(100.0*sum(street2Aggr)/sum(street2Seen),1)
|
||||
end AS TuAFq
|
||||
,case when sum(street3Seen) = 0 then '-'
|
||||
else format(100.0*sum(street3Aggr)/sum(street3Seen),1)
|
||||
end AS RvAFq
|
||||
,case when sum(street1Seen)+sum(street2Seen)+sum(street3Seen) = 0 then '-'
|
||||
else format(100.0*(sum(street1Aggr)+sum(street2Aggr)+sum(street3Aggr))
|
||||
/(sum(street1Seen)+sum(street2Seen)+sum(street3Seen)),1)
|
||||
end AS PoFAFq
|
||||
,format(sum(totalProfit)/100.0,2) AS Net
|
||||
,format((sum(totalProfit/(gt.bigBlind+0.0))) / (sum(HDs)/100.0),2)
|
||||
AS BBper100
|
||||
,format( (sum(totalProfit)/100.0) / sum(HDs), 4) AS Profitperhand
|
||||
,format( sum(activeSeats*HDs)/(sum(HDs)+0.0), 2) AS AvgSeats
|
||||
from Gametypes gt
|
||||
inner join Sites s on s.Id = gt.siteId
|
||||
inner join HudCache hc on hc.gameTypeId = gt.Id
|
||||
where hc.playerId in <player_test>
|
||||
and <gtbigBlind_test>
|
||||
and hc.activeSeats <seats_test>
|
||||
and concat( '20', substring(hc.styleKey,2,2), '-', substring(hc.styleKey,4,2), '-'
|
||||
, substring(hc.styleKey,6,2) ) <datestest>
|
||||
group by gt.base
|
||||
,gt.category
|
||||
<groupbyseats>
|
||||
,plposition
|
||||
,upper(gt.limitType)
|
||||
,s.name
|
||||
having 1 = 1 <havingclause>
|
||||
order by pname
|
||||
,gt.base
|
||||
,gt.category
|
||||
<orderbyseats>
|
||||
,case <position> when 'B' then 'B'
|
||||
when 'S' then 'S'
|
||||
else concat('Z', <position>)
|
||||
end
|
||||
<orderbyhgameTypeId>
|
||||
,upper(gt.limitType) desc
|
||||
,maxbigblind desc
|
||||
,s.name
|
||||
"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['playerDetailedStats'] = """
|
||||
select <hgameTypeId> AS hgametypeid
|
||||
,<playerName> AS pname
|
||||
,gt.base
|
||||
,gt.category
|
||||
,upper(gt.limitType) AS limittype
|
||||
,s.name
|
||||
,min(gt.bigBlind) AS minbigblind
|
||||
,max(gt.bigBlind) AS maxbigblind
|
||||
/*,<hcgametypeId> AS gtid*/
|
||||
,<position> AS plposition
|
||||
,count(1) AS n
|
||||
,100.0*sum(cast(hp.street0VPI as <signed>integer))/count(1) AS vpip
|
||||
,100.0*sum(cast(hp.street0Aggr as <signed>integer))/count(1) AS pfr
|
||||
,case when sum(cast(hp.street0_3Bchance as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street0_3Bdone as <signed>integer))/sum(cast(hp.street0_3Bchance as <signed>integer))
|
||||
end AS pf3
|
||||
,case when sum(cast(hp.stealattemptchance as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.stealattempted as <signed>integer))/sum(cast(hp.stealattemptchance as <signed>integer))
|
||||
end AS steals
|
||||
,100.0*sum(cast(hp.street1Seen as <signed>integer))/count(1) AS saw_f
|
||||
,100.0*sum(cast(hp.sawShowdown as <signed>integer))/count(1) AS sawsd
|
||||
,case when sum(cast(hp.street1Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.sawShowdown as <signed>integer))/sum(cast(hp.street1Seen as <signed>integer))
|
||||
end AS wtsdwsf
|
||||
,case when sum(cast(hp.sawShowdown as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.wonAtSD as <signed>integer))/sum(cast(hp.sawShowdown as <signed>integer))
|
||||
end AS wmsd
|
||||
,case when sum(cast(hp.street1Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street1Aggr as <signed>integer))/sum(cast(hp.street1Seen as <signed>integer))
|
||||
end AS flafq
|
||||
,case when sum(cast(hp.street2Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street2Aggr as <signed>integer))/sum(cast(hp.street2Seen as <signed>integer))
|
||||
end AS tuafq
|
||||
,case when sum(cast(hp.street3Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street3Aggr as <signed>integer))/sum(cast(hp.street3Seen as <signed>integer))
|
||||
end AS rvafq
|
||||
,case when sum(cast(hp.street1Seen as <signed>integer))+sum(cast(hp.street2Seen as <signed>integer))+sum(cast(hp.street3Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*(sum(cast(hp.street1Aggr as <signed>integer))+sum(cast(hp.street2Aggr as <signed>integer))+sum(cast(hp.street3Aggr as <signed>integer)))
|
||||
/(sum(cast(hp.street1Seen as <signed>integer))+sum(cast(hp.street2Seen as <signed>integer))+sum(cast(hp.street3Seen as <signed>integer)))
|
||||
end AS pofafq
|
||||
,sum(hp.totalProfit)/100.0 AS net
|
||||
,sum(hp.rake)/100.0 AS rake
|
||||
,100.0*avg(hp.totalProfit/(gt.bigBlind+0.0)) AS bbper100
|
||||
,avg(hp.totalProfit)/100.0 AS profitperhand
|
||||
,100.0*avg((hp.totalProfit+hp.rake)/(gt.bigBlind+0.0)) AS bb100xr
|
||||
,avg((hp.totalProfit+hp.rake)/100.0) AS profhndxr
|
||||
,avg(h.seats+0.0) AS avgseats
|
||||
,variance(hp.totalProfit/100.0) AS variance
|
||||
from HandsPlayers hp
|
||||
inner join Hands h on (h.id = hp.handId)
|
||||
inner join Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
inner join Sites s on (s.Id = gt.siteId)
|
||||
inner join Players p on (p.Id = hp.playerId)
|
||||
where hp.playerId in <player_test>
|
||||
/*and hp.tourneysPlayersId IS NULL*/
|
||||
and h.seats <seats_test>
|
||||
<flagtest>
|
||||
<gtbigBlind_test>
|
||||
and to_char(h.handStart, 'YYYY-MM-DD') <datestest>
|
||||
group by hgameTypeId
|
||||
,pname
|
||||
,gt.base
|
||||
,gt.category
|
||||
<groupbyseats>
|
||||
,plposition
|
||||
,upper(gt.limitType)
|
||||
,s.name
|
||||
having 1 = 1 <havingclause>
|
||||
order by pname
|
||||
,gt.base
|
||||
,gt.category
|
||||
<orderbyseats>
|
||||
,case <position> when 'B' then 'B'
|
||||
when 'S' then 'S'
|
||||
when '0' then 'Y'
|
||||
else 'Z'||<position>
|
||||
end
|
||||
<orderbyhgameTypeId>
|
||||
,upper(gt.limitType) desc
|
||||
,maxbigblind desc
|
||||
,s.name
|
||||
"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['playerDetailedStats'] = """
|
||||
select <hgameTypeId> AS hgametypeid
|
||||
,gt.base
|
||||
,gt.category
|
||||
,upper(gt.limitType) AS limittype
|
||||
,s.name
|
||||
,min(gt.bigBlind) AS minbigblind
|
||||
,max(gt.bigBlind) AS maxbigblind
|
||||
/*,<hcgametypeId> AS gtid*/
|
||||
,<position> AS plposition
|
||||
,count(1) AS n
|
||||
,100.0*sum(cast(hp.street0VPI as <signed>integer))/count(1) AS vpip
|
||||
,100.0*sum(cast(hp.street0Aggr as <signed>integer))/count(1) AS pfr
|
||||
,case when sum(cast(hp.street0_3Bchance as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street0_3Bdone as <signed>integer))/sum(cast(hp.street0_3Bchance as <signed>integer))
|
||||
end AS pf3
|
||||
,case when sum(cast(hp.stealattemptchance as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.stealattempted as <signed>integer))/sum(cast(hp.stealattemptchance as <signed>integer))
|
||||
end AS steals
|
||||
,100.0*sum(cast(hp.street1Seen as <signed>integer))/count(1) AS saw_f
|
||||
,100.0*sum(cast(hp.sawShowdown as <signed>integer))/count(1) AS sawsd
|
||||
,case when sum(cast(hp.street1Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.sawShowdown as <signed>integer))/sum(cast(hp.street1Seen as <signed>integer))
|
||||
end AS wtsdwsf
|
||||
,case when sum(cast(hp.sawShowdown as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.wonAtSD as <signed>integer))/sum(cast(hp.sawShowdown as <signed>integer))
|
||||
end AS wmsd
|
||||
,case when sum(cast(hp.street1Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street1Aggr as <signed>integer))/sum(cast(hp.street1Seen as <signed>integer))
|
||||
end AS flafq
|
||||
,case when sum(cast(hp.street2Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street2Aggr as <signed>integer))/sum(cast(hp.street2Seen as <signed>integer))
|
||||
end AS tuafq
|
||||
,case when sum(cast(hp.street3Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*sum(cast(hp.street3Aggr as <signed>integer))/sum(cast(hp.street3Seen as <signed>integer))
|
||||
end AS rvafq
|
||||
,case when sum(cast(hp.street1Seen as <signed>integer))+sum(cast(hp.street2Seen as <signed>integer))+sum(cast(hp.street3Seen as <signed>integer)) = 0 then -999
|
||||
else 100.0*(sum(cast(hp.street1Aggr as <signed>integer))+sum(cast(hp.street2Aggr as <signed>integer))+sum(cast(hp.street3Aggr as <signed>integer)))
|
||||
/(sum(cast(hp.street1Seen as <signed>integer))+sum(cast(hp.street2Seen as <signed>integer))+sum(cast(hp.street3Seen as <signed>integer)))
|
||||
end AS pofafq
|
||||
,sum(hp.totalProfit)/100.0 AS net
|
||||
,sum(hp.rake)/100.0 AS rake
|
||||
,100.0*avg(hp.totalProfit/(gt.bigBlind+0.0)) AS bbper100
|
||||
,avg(hp.totalProfit)/100.0 AS profitperhand
|
||||
,100.0*avg((hp.totalProfit+hp.rake)/(gt.bigBlind+0.0)) AS bb100xr
|
||||
,avg((hp.totalProfit+hp.rake)/100.0) AS profhndxr
|
||||
,avg(h.seats+0.0) AS avgseats
|
||||
,variance(hp.totalProfit/100.0) AS variance
|
||||
from HandsPlayers hp
|
||||
inner join Hands h on (h.id = hp.handId)
|
||||
inner join Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
inner join Sites s on (s.Id = gt.siteId)
|
||||
where hp.playerId in <player_test>
|
||||
/*and hp.tourneysPlayersId IS NULL*/
|
||||
and h.seats <seats_test>
|
||||
<flagtest>
|
||||
<gtbigBlind_test>
|
||||
and to_char(h.handStart, 'YYYY-MM-DD') <datestest>
|
||||
group by hgameTypeId
|
||||
,hp.playerId
|
||||
,gt.base
|
||||
,gt.category
|
||||
<groupbyseats>
|
||||
,plposition
|
||||
,upper(gt.limitType)
|
||||
,s.name
|
||||
order by hp.playerId
|
||||
,gt.base
|
||||
,gt.category
|
||||
<orderbyseats>
|
||||
,case <position> when 'B' then 'B'
|
||||
when 'S' then 'S'
|
||||
when '0' then 'Y'
|
||||
else 'Z'||<position>
|
||||
end
|
||||
<orderbyhgameTypeId>
|
||||
,upper(gt.limitType) desc
|
||||
,maxbigblind desc
|
||||
,max(gt.bigBlind) desc
|
||||
,s.name
|
||||
"""
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ if os.name == 'nt' and sys.version[0:3] not in ('2.5', '2.6') and '-r' not in sy
|
|||
else:
|
||||
pass
|
||||
#print "debug - not changing path"
|
||||
|
||||
|
||||
if os.name == 'nt':
|
||||
import win32api
|
||||
import win32con
|
||||
|
@ -53,7 +53,7 @@ import threading
|
|||
import Options
|
||||
import string
|
||||
cl_options = string.join(sys.argv[1:])
|
||||
(options, sys.argv) = Options.fpdb_options()
|
||||
(options, argv) = Options.fpdb_options()
|
||||
|
||||
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_."
|
||||
|
@ -80,7 +80,7 @@ import SQL
|
|||
import Database
|
||||
import FpdbSQLQueries
|
||||
import Configuration
|
||||
from Exceptions import *
|
||||
import Exceptions
|
||||
|
||||
VERSION = "0.12"
|
||||
|
||||
|
@ -178,23 +178,23 @@ class fpdb:
|
|||
"""obtains db root credentials from user"""
|
||||
self.warning_box("Unimplemented: Get Root Database 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)
|
||||
|
||||
def dia_import_db(self, widget, data=None):
|
||||
self.warning_box("Unimplemented: Import Database")
|
||||
self.warning_box("Unimplemented: Import Database")
|
||||
self.obtain_global_lock()
|
||||
self.release_global_lock()
|
||||
|
||||
|
@ -211,7 +211,7 @@ class fpdb:
|
|||
# chooser.set_filename(self.profile)
|
||||
|
||||
# response = chooser.run()
|
||||
# chooser.destroy()
|
||||
# chooser.destroy()
|
||||
# if response == gtk.RESPONSE_OK:
|
||||
# self.load_profile(chooser.get_filename())
|
||||
# elif response == gtk.RESPONSE_CANCEL:
|
||||
|
@ -239,7 +239,7 @@ class fpdb:
|
|||
dia_confirm.destroy()
|
||||
if response == gtk.RESPONSE_YES:
|
||||
#if self.db.backend == self.fdb_lock.fdb.MYSQL_INNODB:
|
||||
# mysql requires locks on all tables or none - easier to release this lock
|
||||
# mysql requires locks on all tables or none - easier to release this lock
|
||||
# than lock all the other tables
|
||||
# ToDo: lock all other tables so that lock doesn't have to be released
|
||||
# self.release_global_lock()
|
||||
|
@ -252,7 +252,7 @@ class fpdb:
|
|||
print 'User cancelled recreating tables'
|
||||
#if not lock_released:
|
||||
self.release_global_lock()
|
||||
|
||||
|
||||
def dia_recreate_hudcache(self, widget, data=None):
|
||||
if self.obtain_global_lock():
|
||||
self.dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm recreating HUD cache")
|
||||
|
@ -314,7 +314,7 @@ class fpdb:
|
|||
entry.set_text(ds)
|
||||
win.destroy()
|
||||
self.dia_confirm.set_modal(True)
|
||||
|
||||
|
||||
def dia_regression_test(self, widget, data=None):
|
||||
self.warning_box("Unimplemented: Regression Test")
|
||||
self.obtain_global_lock()
|
||||
|
@ -322,7 +322,7 @@ class fpdb:
|
|||
|
||||
def dia_save_profile(self, widget, data=None):
|
||||
self.warning_box("Unimplemented: Save Profile (try saving a HUD layout, that should do it)")
|
||||
|
||||
|
||||
def diaSetupWizard(self, path):
|
||||
diaSetupWizard = gtk.Dialog(title="Fatal Error - Config File Missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
|
||||
|
||||
|
@ -453,21 +453,25 @@ class fpdb:
|
|||
self.sql = SQL.Sql(db_server = self.settings['db-server'])
|
||||
try:
|
||||
self.db = Database.Database(self.config, sql = self.sql)
|
||||
except FpdbMySQLFailedError:
|
||||
self.warning_box("Unable to connect to MySQL! Is the MySQL server running?!", "FPDB ERROR")
|
||||
except Exceptions.FpdbMySQLAccessDenied:
|
||||
self.warning_box("MySQL Server reports: Access denied. Are your permissions set correctly?")
|
||||
exit()
|
||||
except FpdbError:
|
||||
#print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
|
||||
self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
||||
sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
||||
except:
|
||||
#print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
|
||||
self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
||||
sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
||||
|
||||
# except FpdbMySQLFailedError:
|
||||
# self.warning_box("Unable to connect to MySQL! Is the MySQL server running?!", "FPDB ERROR")
|
||||
# exit()
|
||||
# except FpdbError:
|
||||
# #print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
|
||||
# self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
|
||||
# err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
# print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
||||
# sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
||||
# except:
|
||||
# #print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
|
||||
# self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
|
||||
# err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
# print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
||||
# sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
||||
|
||||
if self.db.wrongDbVersion:
|
||||
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
||||
|
@ -496,7 +500,7 @@ class fpdb:
|
|||
|
||||
# Database connected to successfully, load queries to pass on to other classes
|
||||
self.db.rollback()
|
||||
|
||||
|
||||
self.validate_config()
|
||||
|
||||
def not_implemented(self, widget, data=None):
|
||||
|
@ -624,7 +628,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
|
||||
self.window.show()
|
||||
self.load_profile()
|
||||
|
||||
|
||||
self.statusIcon = gtk.StatusIcon()
|
||||
if os.path.exists('../gfx/fpdb-cards.png'):
|
||||
self.statusIcon.set_from_file('../gfx/fpdb-cards.png')
|
||||
|
@ -643,19 +647,19 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
self.statusMenu.append(menuItem)
|
||||
self.statusIcon.connect('popup-menu', self.statusicon_menu, self.statusMenu)
|
||||
self.statusIcon.set_visible(True)
|
||||
|
||||
|
||||
self.window.connect('window-state-event', self.window_state_event_cb)
|
||||
sys.stderr.write("fpdb starting ...")
|
||||
|
||||
|
||||
def window_state_event_cb(self, window, event):
|
||||
print "window_state_event", event
|
||||
if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED:
|
||||
# -20 = GWL_EXSTYLE can't find it in the pywin32 libs
|
||||
#bits = win32api.GetWindowLong(self.window.window.handle, -20)
|
||||
#bits = bits ^ (win32con.WS_EX_TOOLWINDOW | win32con.WS_EX_APPWINDOW)
|
||||
|
||||
|
||||
#win32api.SetWindowLong(self.window.window.handle, -20, bits)
|
||||
|
||||
|
||||
if event.new_window_state & gtk.gdk.WINDOW_STATE_ICONIFIED:
|
||||
self.window.hide()
|
||||
self.window.set_skip_taskbar_hint(True)
|
||||
|
@ -665,7 +669,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
self.window.set_skip_pager_hint(False)
|
||||
# Tell GTK not to propagate this signal any further
|
||||
return True
|
||||
|
||||
|
||||
def statusicon_menu(self, widget, button, time, data = None):
|
||||
# we don't need to pass data here, since we do keep track of most all
|
||||
# our variables .. the example code that i looked at for this
|
||||
|
@ -676,7 +680,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
data.show_all()
|
||||
data.popup(None, None, None, 3, time)
|
||||
pass
|
||||
|
||||
|
||||
def statusicon_activate(self, widget, data = None):
|
||||
# Let's allow the tray icon to toggle window visibility, the way
|
||||
# most other apps work
|
||||
|
@ -686,7 +690,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
else:
|
||||
self.window.show()
|
||||
self.window.present()
|
||||
|
||||
|
||||
def warning_box(self, str, diatitle="FPDB WARNING"):
|
||||
diaWarning = gtk.Dialog(title=diatitle, parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
||||
|
||||
|
@ -697,7 +701,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
response = diaWarning.run()
|
||||
diaWarning.destroy()
|
||||
return response
|
||||
|
||||
|
||||
def validate_config(self):
|
||||
hhbase = self.config.get_import_parameters().get("hhArchiveBase")
|
||||
hhbase = os.path.expanduser(hhbase)
|
||||
|
@ -716,7 +720,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
self.warning_box("WARNING: Unable to create hand output directory. Importing is not likely to work until this is fixed.")
|
||||
elif response == gtk.RESPONSE_NO:
|
||||
self.select_hhArchiveBase()
|
||||
|
||||
|
||||
def select_hhArchiveBase(self, widget=None):
|
||||
fc = gtk.FileChooserDialog(title="Select HH Output Directory", parent=None, action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_OPEN,gtk.RESPONSE_OK), backend=None)
|
||||
fc.run()
|
||||
|
@ -726,7 +730,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
self.config.save()
|
||||
self.load_profile() # we can't do this at the end of this func because load_profile calls this func
|
||||
fc.destroy() # TODO: loop this to make sure we get valid data back from it, because the open directory thing in GTK lets you select files and not select things and other stupid bullshit
|
||||
|
||||
|
||||
def main(self):
|
||||
gtk.main()
|
||||
return 0
|
||||
|
|
|
@ -20,6 +20,7 @@ import os
|
|||
import re
|
||||
import sys
|
||||
import logging
|
||||
import math
|
||||
from time import time, strftime
|
||||
from Exceptions import *
|
||||
|
||||
|
@ -53,6 +54,10 @@ class VARIANCE:
|
|||
def finalize(self):
|
||||
return float(var(self.store))
|
||||
|
||||
class sqlitemath:
|
||||
def mod(self, a, b):
|
||||
return a%b
|
||||
|
||||
class fpdb_db:
|
||||
MYSQL_INNODB = 2
|
||||
PGSQL = 3
|
||||
|
@ -77,10 +82,10 @@ class fpdb_db:
|
|||
self.connect(backend=db['db-backend'],
|
||||
host=db['db-host'],
|
||||
database=db['db-databaseName'],
|
||||
user=db['db-user'],
|
||||
user=db['db-user'],
|
||||
password=db['db-password'])
|
||||
#end def do_connect
|
||||
|
||||
|
||||
def connect(self, backend=None, host=None, database=None,
|
||||
user=None, password=None):
|
||||
"""Connects a database with the given parameters"""
|
||||
|
@ -95,12 +100,15 @@ class fpdb_db:
|
|||
import MySQLdb
|
||||
if use_pool:
|
||||
MySQLdb = pool.manage(MySQLdb, pool_size=5)
|
||||
# try:
|
||||
self.db = MySQLdb.connect(host=host, user=user, passwd=password, db=database, use_unicode=True)
|
||||
try:
|
||||
self.db = MySQLdb.connect(host=host, user=user, passwd=password, db=database, use_unicode=True)
|
||||
#TODO: Add port option
|
||||
# except:
|
||||
# raise FpdbMySQLFailedError("MySQL connection failed")
|
||||
elif backend==fpdb_db.PGSQL:
|
||||
except MySQLdb.Error, ex:
|
||||
if ex.args[0] == 1045:
|
||||
raise FpdbMySQLAccessDenied(ex.args[0], ex.args[1])
|
||||
else:
|
||||
print "*** WARNING UNKNOWN MYSQL ERROR", ex
|
||||
elif backend == fpdb_db.PGSQL:
|
||||
import psycopg2
|
||||
import psycopg2.extensions
|
||||
if use_pool:
|
||||
|
@ -126,8 +134,8 @@ class fpdb_db:
|
|||
if not connected:
|
||||
try:
|
||||
self.db = psycopg2.connect(host = host,
|
||||
user = user,
|
||||
password = password,
|
||||
user = user,
|
||||
password = password,
|
||||
database = database)
|
||||
except:
|
||||
msg = "PostgreSQL connection to database (%s) user (%s) failed. Are you sure the DB is running?" % (database, user)
|
||||
|
@ -148,6 +156,9 @@ class fpdb_db:
|
|||
, detect_types=sqlite3.PARSE_DECLTYPES )
|
||||
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
||||
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
||||
self.db.create_function("floor", 1, math.floor)
|
||||
tmp = sqlitemath()
|
||||
self.db.create_function("mod", 2, tmp.mod)
|
||||
if use_numpy:
|
||||
self.db.create_aggregate("variance", 1, VARIANCE)
|
||||
else:
|
||||
|
@ -179,13 +190,13 @@ class fpdb_db:
|
|||
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 get_backend_name(self):
|
||||
"""Returns the name of the currently used backend"""
|
||||
if self.backend==2:
|
||||
|
@ -197,7 +208,7 @@ class fpdb_db:
|
|||
else:
|
||||
raise 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
|
||||
|
|
|
@ -927,7 +927,7 @@ def recogniseTourneyTypeId(db, siteId, tourneySiteId, buyin, fee, knockout, rebu
|
|||
except:
|
||||
cursor.execute( """SELECT id FROM TourneyTypes
|
||||
WHERE siteId=%s AND buyin=%s AND fee=%s
|
||||
AND knockout=%s AND rebuyOrAddon=%s"""
|
||||
AND knockout=%s AND rebuyOrAddon=%s""".replace('%s', db.sql.query['placeholder'])
|
||||
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
||||
result = cursor.fetchone()
|
||||
#print "tried selecting tourneytypes.id, result:", result
|
||||
|
@ -939,14 +939,14 @@ def recogniseTourneyTypeId(db, siteId, tourneySiteId, buyin, fee, knockout, rebu
|
|||
#print "insert new tourneytype record ..."
|
||||
try:
|
||||
cursor.execute( """INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon)
|
||||
VALUES (%s, %s, %s, %s, %s)"""
|
||||
VALUES (%s, %s, %s, %s, %s)""".replace('%s', db.sql.query['placeholder'])
|
||||
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
||||
ret = db.get_last_insert_id(cursor)
|
||||
except:
|
||||
#print "maybe tourneytype was created since select, try selecting again ..."
|
||||
cursor.execute( """SELECT id FROM TourneyTypes
|
||||
WHERE siteId=%s AND buyin=%s AND fee=%s
|
||||
AND knockout=%s AND rebuyOrAddon=%s"""
|
||||
AND knockout=%s AND rebuyOrAddon=%s""".replace('%s', db.sql.query['placeholder'])
|
||||
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
||||
result = cursor.fetchone()
|
||||
try:
|
||||
|
|
68
pyfpdb/test_Database.py
Normal file
68
pyfpdb/test_Database.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import sqlite3
|
||||
import fpdb_db
|
||||
import math
|
||||
|
||||
# Should probably use our wrapper classes - creating sqlite db in memory
|
||||
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
||||
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
||||
|
||||
con = sqlite3.connect(":memory:")
|
||||
con.isolation_level = None
|
||||
|
||||
#Floor function
|
||||
con.create_function("floor", 1, math.floor)
|
||||
|
||||
#Mod function
|
||||
tmp = fpdb_db.sqlitemath()
|
||||
con.create_function("mod", 2, tmp.mod)
|
||||
|
||||
# Aggregate function VARIANCE()
|
||||
con.create_aggregate("variance", 1, fpdb_db.VARIANCE)
|
||||
|
||||
|
||||
cur = con.cursor()
|
||||
|
||||
def testSQLiteVarianceFunction():
|
||||
cur.execute("CREATE TABLE test(i)")
|
||||
cur.execute("INSERT INTO test(i) values (1)")
|
||||
cur.execute("INSERT INTO test(i) values (2)")
|
||||
cur.execute("INSERT INTO test(i) values (3)")
|
||||
cur.execute("SELECT variance(i) from test")
|
||||
result = cur.fetchone()[0]
|
||||
|
||||
print "DEBUG: Testing variance function"
|
||||
print "DEBUG: result: %s expecting: 0.666666 (result-expecting ~= 0.0): %s" % (result, (result - 0.66666))
|
||||
cur.execute("DROP TABLE test")
|
||||
assert (result - 0.66666) <= 0.0001
|
||||
|
||||
def testSQLiteFloorFunction():
|
||||
vars = [0.1, 1.5, 2.6, 3.5, 4.9]
|
||||
cur.execute("CREATE TABLE test(i float)")
|
||||
for var in vars:
|
||||
cur.execute("INSERT INTO test(i) values(%f)" % var)
|
||||
cur.execute("SELECT floor(i) from test")
|
||||
result = cur.fetchall()
|
||||
print "DEBUG: result: %s" % result
|
||||
answer = 0
|
||||
for i in result:
|
||||
print "DEBUG: int(var): %s" % int(i[0])
|
||||
assert answer == int(i[0])
|
||||
answer = answer + 1
|
||||
cur.execute("DROP TABLE test")
|
||||
|
||||
def testSQLiteModFunction():
|
||||
vars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ,17, 18]
|
||||
cur.execute("CREATE TABLE test(i int)")
|
||||
for var in vars:
|
||||
cur.execute("INSERT INTO test(i) values(%i)" % var)
|
||||
cur.execute("SELECT mod(i,13) from test")
|
||||
result = cur.fetchall()
|
||||
idx = 0
|
||||
for i in result:
|
||||
print "DEBUG: int(var): %s" % i[0]
|
||||
assert vars[idx]%13 == int(i[0])
|
||||
idx = idx+1
|
||||
|
||||
assert 0 == 1
|
||||
cur.execute("DROP TABLE test")
|
Loading…
Reference in New Issue
Block a user