Merge branch 'master' of git://git.assembla.com/fpdboz
Conflicts: pyfpdb/Configuration.py pyfpdb/SQL.py note:hopefully got the merge right
This commit is contained in:
commit
6d54da1c49
|
@ -3,3 +3,4 @@
|
||||||
# When installed into .../fpdb/ the script gets mode 644
|
# When installed into .../fpdb/ the script gets mode 644
|
||||||
# Note: "dh_fixperms -Xfpdb.py" did not work, hence this hack
|
# Note: "dh_fixperms -Xfpdb.py" did not work, hence this hack
|
||||||
chmod 755 /usr/bin/fpdb
|
chmod 755 /usr/bin/fpdb
|
||||||
|
chmod 755 /usr/share/pyshared/fpdb/HUD_main.py
|
||||||
|
|
|
@ -156,9 +156,9 @@ class Site:
|
||||||
else: self.hudopacity = float(self.hudopacity)
|
else: self.hudopacity = float(self.hudopacity)
|
||||||
|
|
||||||
if self.use_frames == "": self.use_frames = False
|
if self.use_frames == "": self.use_frames = False
|
||||||
if self.font == "": self.font = "Sans"
|
if self.font == "": self.font = "Sans"
|
||||||
if self.hudbgcolor == "": self.hudbgcolor = "000000"
|
if self.hudbgcolor == "": self.hudbgcolor = "#000000"
|
||||||
if self.hudfgcolor == "": self.hudfgcolor = "FFFFFF"
|
if self.hudfgcolor == "": self.hudfgcolor = "#FFFFFF"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
temp = "Site = " + self.site_name + "\n"
|
temp = "Site = " + self.site_name + "\n"
|
||||||
|
@ -673,7 +673,7 @@ class Config:
|
||||||
# Allow to change the menu appearance
|
# Allow to change the menu appearance
|
||||||
def get_hud_ui_parameters(self):
|
def get_hud_ui_parameters(self):
|
||||||
hui = {}
|
hui = {}
|
||||||
|
|
||||||
default_text = 'FPDB Menu - Right click\nLeft-Drag to Move'
|
default_text = 'FPDB Menu - Right click\nLeft-Drag to Move'
|
||||||
try:
|
try:
|
||||||
hui['label'] = self.ui.label
|
hui['label'] = self.ui.label
|
||||||
|
|
|
@ -1144,6 +1144,7 @@ class Database:
|
||||||
c.execute("INSERT INTO Sites (name,currency) VALUES ('Betfair', 'USD')")
|
c.execute("INSERT INTO Sites (name,currency) VALUES ('Betfair', 'USD')")
|
||||||
c.execute("INSERT INTO Sites (name,currency) VALUES ('Absolute', 'USD')")
|
c.execute("INSERT INTO Sites (name,currency) VALUES ('Absolute', 'USD')")
|
||||||
c.execute("INSERT INTO Sites (name,currency) VALUES ('PartyPoker', 'USD')")
|
c.execute("INSERT INTO Sites (name,currency) VALUES ('PartyPoker', 'USD')")
|
||||||
|
c.execute("INSERT INTO Sites (name,currency) VALUES ('Partouche', 'EUR')")
|
||||||
if self.backend == self.SQLITE:
|
if self.backend == self.SQLITE:
|
||||||
c.execute("INSERT INTO TourneyTypes (id, siteId, buyin, fee) VALUES (NULL, 1, 0, 0);")
|
c.execute("INSERT INTO TourneyTypes (id, siteId, buyin, fee) VALUES (NULL, 1, 0, 0);")
|
||||||
elif self.backend == self.PGSQL:
|
elif self.backend == self.PGSQL:
|
||||||
|
@ -1263,63 +1264,6 @@ class Database:
|
||||||
print "Error during fdb.lock_for_insert:", str(sys.exc_value)
|
print "Error during fdb.lock_for_insert:", str(sys.exc_value)
|
||||||
#end def lock_for_insert
|
#end def lock_for_insert
|
||||||
|
|
||||||
def getGameTypeId(self, siteid, game):
|
|
||||||
c = self.get_cursor()
|
|
||||||
#FIXME: Fixed for NL at the moment
|
|
||||||
c.execute(self.sql.query['getGametypeNL'], (siteid, game['type'], game['category'], game['limitType'],
|
|
||||||
int(Decimal(game['sb'])*100), int(Decimal(game['bb'])*100)))
|
|
||||||
tmp = c.fetchone()
|
|
||||||
if (tmp == None):
|
|
||||||
hilo = "h"
|
|
||||||
if game['category'] in ['studhilo', 'omahahilo']:
|
|
||||||
hilo = "s"
|
|
||||||
elif game['category'] in ['razz','27_3draw','badugi']:
|
|
||||||
hilo = "l"
|
|
||||||
tmp = self.insertGameTypes( (siteid, game['type'], game['base'], game['category'], game['limitType'], hilo,
|
|
||||||
int(Decimal(game['sb'])*100), int(Decimal(game['bb'])*100), 0, 0) )
|
|
||||||
return tmp[0]
|
|
||||||
|
|
||||||
def getSqlPlayerIDs(self, pnames, siteid):
|
|
||||||
result = {}
|
|
||||||
if(self.pcache == None):
|
|
||||||
self.pcache = LambdaDict(lambda key:self.insertPlayer(key, siteid))
|
|
||||||
|
|
||||||
for player in pnames:
|
|
||||||
result[player] = self.pcache[player]
|
|
||||||
# NOTE: Using the LambdaDict does the same thing as:
|
|
||||||
#if player in self.pcache:
|
|
||||||
# #print "DEBUG: cachehit"
|
|
||||||
# pass
|
|
||||||
#else:
|
|
||||||
# self.pcache[player] = self.insertPlayer(player, siteid)
|
|
||||||
#result[player] = self.pcache[player]
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def insertPlayer(self, name, site_id):
|
|
||||||
result = None
|
|
||||||
c = self.get_cursor()
|
|
||||||
q = "SELECT name, id FROM Players WHERE siteid=%s and name=%s"
|
|
||||||
q = q.replace('%s', self.sql.query['placeholder'])
|
|
||||||
|
|
||||||
#print "DEBUG: name: %s site: %s" %(name, site_id)
|
|
||||||
|
|
||||||
c.execute (q, (site_id, name))
|
|
||||||
|
|
||||||
tmp = c.fetchone()
|
|
||||||
if (tmp == None): #new player
|
|
||||||
c.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)".replace('%s',self.sql.query['placeholder'])
|
|
||||||
,(name, site_id))
|
|
||||||
#Get last id might be faster here.
|
|
||||||
#c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
|
|
||||||
tmp = [self.get_last_insert_id(c)]
|
|
||||||
return tmp[0]
|
|
||||||
|
|
||||||
def insertGameTypes(self, row):
|
|
||||||
c = self.get_cursor()
|
|
||||||
c.execute( self.sql.query['insertGameTypes'], row )
|
|
||||||
return [self.get_last_insert_id(c)]
|
|
||||||
|
|
||||||
def store_the_hand(self, h):
|
def store_the_hand(self, h):
|
||||||
"""Take a HandToWrite object and store it in the db"""
|
"""Take a HandToWrite object and store it in the db"""
|
||||||
|
|
||||||
|
@ -1667,6 +1611,64 @@ class Database:
|
||||||
# street4CheckCallRaiseChance,
|
# street4CheckCallRaiseChance,
|
||||||
# street4CheckCallRaiseDone)
|
# street4CheckCallRaiseDone)
|
||||||
|
|
||||||
|
def getGameTypeId(self, siteid, game):
|
||||||
|
c = self.get_cursor()
|
||||||
|
#FIXME: Fixed for NL at the moment
|
||||||
|
c.execute(self.sql.query['getGametypeNL'], (siteid, game['type'], game['category'], game['limitType'],
|
||||||
|
int(Decimal(game['sb'])*100), int(Decimal(game['bb'])*100)))
|
||||||
|
tmp = c.fetchone()
|
||||||
|
if (tmp == None):
|
||||||
|
hilo = "h"
|
||||||
|
if game['category'] in ['studhilo', 'omahahilo']:
|
||||||
|
hilo = "s"
|
||||||
|
elif game['category'] in ['razz','27_3draw','badugi']:
|
||||||
|
hilo = "l"
|
||||||
|
tmp = self.insertGameTypes( (siteid, game['type'], game['base'], game['category'], game['limitType'], hilo,
|
||||||
|
int(Decimal(game['sb'])*100), int(Decimal(game['bb'])*100), 0, 0) )
|
||||||
|
return tmp[0]
|
||||||
|
|
||||||
|
def getSqlPlayerIDs(self, pnames, siteid):
|
||||||
|
result = {}
|
||||||
|
if(self.pcache == None):
|
||||||
|
self.pcache = LambdaDict(lambda key:self.insertPlayer(key, siteid))
|
||||||
|
|
||||||
|
for player in pnames:
|
||||||
|
result[player] = self.pcache[player]
|
||||||
|
# NOTE: Using the LambdaDict does the same thing as:
|
||||||
|
#if player in self.pcache:
|
||||||
|
# #print "DEBUG: cachehit"
|
||||||
|
# pass
|
||||||
|
#else:
|
||||||
|
# self.pcache[player] = self.insertPlayer(player, siteid)
|
||||||
|
#result[player] = self.pcache[player]
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def insertPlayer(self, name, site_id):
|
||||||
|
result = None
|
||||||
|
c = self.get_cursor()
|
||||||
|
q = "SELECT name, id FROM Players WHERE siteid=%s and name=%s"
|
||||||
|
q = q.replace('%s', self.sql.query['placeholder'])
|
||||||
|
|
||||||
|
#print "DEBUG: name: %s site: %s" %(name, site_id)
|
||||||
|
|
||||||
|
c.execute (q, (site_id, name))
|
||||||
|
|
||||||
|
tmp = c.fetchone()
|
||||||
|
if (tmp == None): #new player
|
||||||
|
c.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)".replace('%s',self.sql.query['placeholder'])
|
||||||
|
,(name, site_id))
|
||||||
|
#Get last id might be faster here.
|
||||||
|
#c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
|
||||||
|
tmp = [self.get_last_insert_id(c)]
|
||||||
|
return tmp[0]
|
||||||
|
|
||||||
|
def insertGameTypes(self, row):
|
||||||
|
c = self.get_cursor()
|
||||||
|
c.execute( self.sql.query['insertGameTypes'], row )
|
||||||
|
return [self.get_last_insert_id(c)]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#################################
|
#################################
|
||||||
# Finish of NEWIMPORT CODE
|
# Finish of NEWIMPORT CODE
|
||||||
|
|
|
@ -20,6 +20,7 @@ import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk
|
import gtk
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
from time import *
|
from time import *
|
||||||
#import pokereval
|
#import pokereval
|
||||||
|
@ -32,7 +33,7 @@ try:
|
||||||
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar
|
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar
|
||||||
from numpy import arange, cumsum
|
from numpy import arange, cumsum
|
||||||
from pylab import *
|
from pylab import *
|
||||||
except ImportError as inst:
|
except ImportError, inst:
|
||||||
print """Failed to load libs for graphing, graphing will not function. Please in
|
print """Failed to load libs for graphing, graphing will not function. Please in
|
||||||
stall numpy and matplotlib if you want to use graphs."""
|
stall numpy and matplotlib if you want to use graphs."""
|
||||||
print """This is of no consequence for other parts of the program, e.g. import
|
print """This is of no consequence for other parts of the program, e.g. import
|
||||||
|
|
|
@ -37,7 +37,7 @@ try:
|
||||||
# from matplotlib.dates import DateFormatter, WeekdayLocator, HourLocator, \
|
# from matplotlib.dates import DateFormatter, WeekdayLocator, HourLocator, \
|
||||||
# DayLocator, MONDAY, timezone
|
# DayLocator, MONDAY, timezone
|
||||||
|
|
||||||
except ImportError as inst:
|
except ImportError, inst:
|
||||||
print """Failed to load numpy in Session Viewer"""
|
print """Failed to load numpy in Session Viewer"""
|
||||||
print """This is of no consequence as the page is broken and only of interest to developers."""
|
print """This is of no consequence as the page is broken and only of interest to developers."""
|
||||||
print "ImportError: %s" % inst.args
|
print "ImportError: %s" % inst.args
|
||||||
|
@ -248,6 +248,8 @@ class GuiSessionViewer (threading.Thread):
|
||||||
nametest = nametest.replace("L", "")
|
nametest = nametest.replace("L", "")
|
||||||
nametest = nametest.replace(",)",")")
|
nametest = nametest.replace(",)",")")
|
||||||
q = q.replace("<player_test>", nametest)
|
q = q.replace("<player_test>", nametest)
|
||||||
|
q = q.replace("<ampersand_s>", "%s")
|
||||||
|
|
||||||
self.db.cursor.execute(q)
|
self.db.cursor.execute(q)
|
||||||
THRESHOLD = 1800
|
THRESHOLD = 1800
|
||||||
hands = self.db.cursor.fetchall()
|
hands = self.db.cursor.fetchall()
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
<import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True"></import>
|
<import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True"></import>
|
||||||
|
|
||||||
|
|
||||||
<!-- These values need some explaining
|
<!-- These values need some explaining
|
||||||
|
|
||||||
aggregate_ring_game_stats :
|
aggregate_ring_game_stats :
|
||||||
|
@ -567,6 +566,7 @@ Left-Drag to Move"
|
||||||
<hhc site="Absolute" converter="AbsoluteToFpdb"/>
|
<hhc site="Absolute" converter="AbsoluteToFpdb"/>
|
||||||
<hhc site="PartyPoker" converter="PartyPokerToFpdb"/>
|
<hhc site="PartyPoker" converter="PartyPokerToFpdb"/>
|
||||||
<hhc site="Betfair" converter="BetfairToFpdb"/>
|
<hhc site="Betfair" converter="BetfairToFpdb"/>
|
||||||
|
<hhc site="Partouche" converter="PartoucheToFpdb"/>
|
||||||
</hhcs>
|
</hhcs>
|
||||||
|
|
||||||
<supported_databases>
|
<supported_databases>
|
||||||
|
|
|
@ -189,99 +189,95 @@ class HUD_main(object):
|
||||||
# be passed to HUDs for use in the gui thread. HUD objects should not
|
# be passed to HUDs for use in the gui thread. HUD objects should not
|
||||||
# need their own access to the database, but should open their own
|
# need their own access to the database, but should open their own
|
||||||
# if it is required.
|
# if it is required.
|
||||||
try:
|
self.db_connection = Database.Database(self.config)
|
||||||
self.db_connection = Database.Database(self.config)
|
tourny_finder = re.compile('(\d+) (\d+)')
|
||||||
tourny_finder = re.compile('(\d+) (\d+)')
|
|
||||||
|
|
||||||
# get hero's screen names and player ids
|
|
||||||
self.hero, self.hero_ids = {}, {}
|
|
||||||
for site in self.config.get_supported_sites():
|
|
||||||
result = self.db_connection.get_site_id(site)
|
|
||||||
if result:
|
|
||||||
site_id = result[0][0]
|
|
||||||
self.hero[site_id] = self.config.supported_sites[site].screen_name
|
|
||||||
self.hero_ids[site_id] = self.db_connection.get_player_id(self.config, site, self.hero[site_id])
|
|
||||||
|
|
||||||
while 1: # wait for a new hand number on stdin
|
# get hero's screen names and player ids
|
||||||
new_hand_id = sys.stdin.readline()
|
self.hero, self.hero_ids = {}, {}
|
||||||
new_hand_id = string.rstrip(new_hand_id)
|
for site in self.config.get_supported_sites():
|
||||||
if new_hand_id == "": # blank line means quit
|
result = self.db_connection.get_site_id(site)
|
||||||
self.destroy()
|
if result:
|
||||||
break # this thread is not always killed immediately with gtk.main_quit()
|
site_id = result[0][0]
|
||||||
|
self.hero[site_id] = self.config.supported_sites[site].screen_name
|
||||||
|
self.hero_ids[site_id] = self.db_connection.get_player_id(self.config, site, self.hero[site_id])
|
||||||
|
|
||||||
|
while 1: # wait for a new hand number on stdin
|
||||||
|
new_hand_id = sys.stdin.readline()
|
||||||
|
new_hand_id = string.rstrip(new_hand_id)
|
||||||
|
if new_hand_id == "": # blank line means quit
|
||||||
|
self.destroy()
|
||||||
|
break # this thread is not always killed immediately with gtk.main_quit()
|
||||||
# get basic info about the new hand from the db
|
# get basic info about the new hand from the db
|
||||||
# if there is a db error, complain, skip hand, and proceed
|
# if there is a db error, complain, skip hand, and proceed
|
||||||
try:
|
try:
|
||||||
(table_name, max, poker_game, type, site_id) = self.db_connection.get_table_name(new_hand_id)
|
(table_name, max, poker_game, type, site_id) = self.db_connection.get_table_name(new_hand_id)
|
||||||
|
|
||||||
cards = self.db_connection.get_cards(new_hand_id)
|
cards = self.db_connection.get_cards(new_hand_id)
|
||||||
comm_cards = self.db_connection.get_common_cards(new_hand_id)
|
comm_cards = self.db_connection.get_common_cards(new_hand_id)
|
||||||
if comm_cards != {}: # stud!
|
if comm_cards != {}: # stud!
|
||||||
cards['common'] = comm_cards['common']
|
cards['common'] = comm_cards['common']
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
print "db error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
print "db error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
if new_hand_id: # new_hand_id is none if we had an error prior to the store
|
if new_hand_id: # new_hand_id is none if we had an error prior to the store
|
||||||
sys.stderr.write("Database error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
sys.stderr.write("Database error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
||||||
|
continue
|
||||||
|
|
||||||
|
if type == "tour": # hand is from a tournament
|
||||||
|
mat_obj = tourny_finder.search(table_name)
|
||||||
|
if mat_obj:
|
||||||
|
(tour_number, tab_number) = mat_obj.group(1, 2)
|
||||||
|
temp_key = tour_number
|
||||||
|
else: # tourney, but can't get number and table
|
||||||
|
print "could not find tournament: skipping "
|
||||||
|
#sys.stderr.write("Could not find tournament %d in hand %d. Skipping.\n" % (int(tour_number), int(new_hand_id)))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if type == "tour": # hand is from a tournament
|
else:
|
||||||
mat_obj = tourny_finder.search(table_name)
|
temp_key = table_name
|
||||||
if mat_obj:
|
|
||||||
(tour_number, tab_number) = mat_obj.group(1, 2)
|
|
||||||
temp_key = tour_number
|
|
||||||
else: # tourney, but can't get number and table
|
|
||||||
print "could not find tournament: skipping "
|
|
||||||
#sys.stderr.write("Could not find tournament %d in hand %d. Skipping.\n" % (int(tour_number), int(new_hand_id)))
|
|
||||||
continue
|
|
||||||
|
|
||||||
else:
|
|
||||||
temp_key = table_name
|
|
||||||
|
|
||||||
# Update an existing HUD
|
# Update an existing HUD
|
||||||
if temp_key in self.hud_dict:
|
if temp_key in self.hud_dict:
|
||||||
try:
|
try:
|
||||||
# get stats using hud's specific params
|
# get stats using hud's specific params
|
||||||
self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days']
|
self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days']
|
||||||
, self.hud_dict[temp_key].hud_params['h_hud_days'])
|
, self.hud_dict[temp_key].hud_params['h_hud_days'])
|
||||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_dict[temp_key].hud_params, self.hero_ids[site_id])
|
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_dict[temp_key].hud_params, self.hero_ids[site_id])
|
||||||
except:
|
except:
|
||||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
print "db get_stats error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
print "db get_stats error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
if new_hand_id: # new_hand_id is none if we had an error prior to the store
|
if new_hand_id: # new_hand_id is none if we had an error prior to the store
|
||||||
sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
||||||
continue
|
continue
|
||||||
self.hud_dict[temp_key].stat_dict = stat_dict
|
self.hud_dict[temp_key].stat_dict = stat_dict
|
||||||
self.hud_dict[temp_key].cards = cards
|
self.hud_dict[temp_key].cards = cards
|
||||||
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows]
|
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows]
|
||||||
self.update_HUD(new_hand_id, temp_key, self.config)
|
self.update_HUD(new_hand_id, temp_key, self.config)
|
||||||
|
|
||||||
# Or create a new HUD
|
# Or create a new HUD
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
# get stats using default params
|
||||||
|
self.db_connection.init_hud_stat_vars( self.hud_params['hud_days'], self.hud_params['h_hud_days'] )
|
||||||
|
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params, self.hero_ids[site_id])
|
||||||
|
except:
|
||||||
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
|
print "db get_stats error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
|
if new_hand_id: # new_hand_id is none if we had an error prior to the store
|
||||||
|
sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
||||||
|
continue
|
||||||
|
if type == "tour":
|
||||||
|
tablewindow = Tables.discover_tournament_table(self.config, tour_number, tab_number)
|
||||||
else:
|
else:
|
||||||
try:
|
tablewindow = Tables.discover_table_by_name(self.config, table_name)
|
||||||
# get stats using default params
|
if tablewindow == None:
|
||||||
self.db_connection.init_hud_stat_vars( self.hud_params['hud_days'], self.hud_params['h_hud_days'] )
|
|
||||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params, self.hero_ids[site_id])
|
|
||||||
except:
|
|
||||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
|
||||||
print "db get_stats error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
|
||||||
if new_hand_id: # new_hand_id is none if we had an error prior to the store
|
|
||||||
sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
|
|
||||||
continue
|
|
||||||
if type == "tour":
|
|
||||||
tablewindow = Tables.discover_tournament_table(self.config, tour_number, tab_number)
|
|
||||||
else:
|
|
||||||
tablewindow = Tables.discover_table_by_name(self.config, table_name)
|
|
||||||
if tablewindow == None:
|
|
||||||
# If no client window is found on the screen, complain and continue
|
# If no client window is found on the screen, complain and continue
|
||||||
if type == "tour":
|
if type == "tour":
|
||||||
table_name = "%s %s" % (tour_number, tab_number)
|
table_name = "%s %s" % (tour_number, tab_number)
|
||||||
sys.stderr.write("table name "+table_name+" not found, skipping.\n")
|
sys.stderr.write("table name "+table_name+" not found, skipping.\n")
|
||||||
else:
|
else:
|
||||||
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards)
|
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards)
|
||||||
self.db_connection.connection.rollback()
|
self.db_connection.connection.rollback()
|
||||||
except:
|
|
||||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
|
||||||
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
|
||||||
|
|
||||||
if __name__== "__main__":
|
if __name__== "__main__":
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,12 @@ from HandHistoryConverter import *
|
||||||
|
|
||||||
class PartyPokerParseError(FpdbParseError):
|
class PartyPokerParseError(FpdbParseError):
|
||||||
"Usage: raise PartyPokerParseError(<msg>[, hh=<hh>][, hid=<hid>])"
|
"Usage: raise PartyPokerParseError(<msg>[, hh=<hh>][, hid=<hid>])"
|
||||||
|
|
||||||
def __init__(self, msg='', hh=None, hid=None):
|
def __init__(self, msg='', hh=None, hid=None):
|
||||||
if hh is not None:
|
if hh is not None:
|
||||||
msg += "\n\nHand history attached below:\n" + self.wrapHh(hh)
|
msg += "\n\nHand history attached below:\n" + self.wrapHh(hh)
|
||||||
return super(PartyPokerParseError, self).__init__(hid=hid)
|
return super(PartyPokerParseError, self).__init__(msg, hid=hid)
|
||||||
#return super(PartyPokerParseError, self).__init__(msg, hid=hid)
|
|
||||||
def wrapHh(self, hh):
|
def wrapHh(self, hh):
|
||||||
return ("%(DELIMETER)s\n%(HH)s\n%(DELIMETER)s") % \
|
return ("%(DELIMETER)s\n%(HH)s\n%(DELIMETER)s") % \
|
||||||
{'DELIMETER': '#'*50, 'HH': hh}
|
{'DELIMETER': '#'*50, 'HH': hh}
|
||||||
|
@ -93,7 +94,7 @@ class PartyPoker(HandHistoryConverter):
|
||||||
""",
|
""",
|
||||||
re.MULTILINE|re.VERBOSE)
|
re.MULTILINE|re.VERBOSE)
|
||||||
|
|
||||||
re_TotalPlayers = re.compile("^Total\s+number\s+of\s+players\s*:\s*(?P<MAXSEATS>\d+)", re.MULTILINE)
|
# re_TotalPlayers = re.compile("^Total\s+number\s+of\s+players\s*:\s*(?P<MAXSEATS>\d+)", re.MULTILINE)
|
||||||
re_SplitHands = re.compile('\x00+')
|
re_SplitHands = re.compile('\x00+')
|
||||||
re_TailSplitHands = re.compile('(\x00+)')
|
re_TailSplitHands = re.compile('(\x00+)')
|
||||||
lineSplitter = '\n'
|
lineSplitter = '\n'
|
||||||
|
@ -229,7 +230,6 @@ class PartyPoker(HandHistoryConverter):
|
||||||
"Unknown game type '%s'" % mg['GAME'],
|
"Unknown game type '%s'" % mg['GAME'],
|
||||||
hh = handText)
|
hh = handText)
|
||||||
|
|
||||||
|
|
||||||
if 'TOURNO' in mg:
|
if 'TOURNO' in mg:
|
||||||
info['type'] = 'tour'
|
info['type'] = 'tour'
|
||||||
else:
|
else:
|
||||||
|
@ -237,15 +237,12 @@ class PartyPoker(HandHistoryConverter):
|
||||||
|
|
||||||
if info['type'] == 'ring':
|
if info['type'] == 'ring':
|
||||||
info['sb'], info['bb'] = ringBlinds(mg['RINGLIMIT'])
|
info['sb'], info['bb'] = ringBlinds(mg['RINGLIMIT'])
|
||||||
# FIXME: there are only $ and play money availible for cash
|
|
||||||
# to be honest, party doesn't save play money hh
|
|
||||||
info['currency'] = currencies[mg['CURRENCY']]
|
info['currency'] = currencies[mg['CURRENCY']]
|
||||||
else:
|
else:
|
||||||
info['sb'] = clearMoneyString(mg['SB'])
|
info['sb'] = clearMoneyString(mg['SB'])
|
||||||
info['bb'] = clearMoneyString(mg['BB'])
|
info['bb'] = clearMoneyString(mg['BB'])
|
||||||
info['currency'] = 'T$'
|
info['currency'] = 'T$'
|
||||||
|
|
||||||
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
|
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,8 +266,8 @@ class PartyPoker(HandHistoryConverter):
|
||||||
hh=hand.handText, hid = info['HID'])
|
hh=hand.handText, hid = info['HID'])
|
||||||
|
|
||||||
|
|
||||||
m = self.re_TotalPlayers.search(hand.handText)
|
# m = self.re_TotalPlayers.search(hand.handText)
|
||||||
if m: info.update(m.groupdict())
|
# if m: info.update(m.groupdict())
|
||||||
|
|
||||||
|
|
||||||
# FIXME: it's dirty hack
|
# FIXME: it's dirty hack
|
||||||
|
@ -318,7 +315,7 @@ class PartyPoker(HandHistoryConverter):
|
||||||
hand.tourNo = info[key]
|
hand.tourNo = info[key]
|
||||||
if key == 'BUYIN':
|
if key == 'BUYIN':
|
||||||
# FIXME: it's dirty hack T_T
|
# FIXME: it's dirty hack T_T
|
||||||
# code below assumes that rake is equal to zero
|
# code below assumes that tournament rake is equal to zero
|
||||||
cur = info[key][0] if info[key][0] not in '0123456789' else ''
|
cur = info[key][0] if info[key][0] not in '0123456789' else ''
|
||||||
hand.buyin = info[key] + '+%s0' % cur
|
hand.buyin = info[key] + '+%s0' % cur
|
||||||
if key == 'LEVEL':
|
if key == 'LEVEL':
|
||||||
|
@ -474,11 +471,9 @@ class PartyPoker(HandHistoryConverter):
|
||||||
if m.group('CARDS') is not None:
|
if m.group('CARDS') is not None:
|
||||||
cards = renderCards(m.group('CARDS'))
|
cards = renderCards(m.group('CARDS'))
|
||||||
|
|
||||||
(shown, mucked) = (False, False)
|
mucked = m.group('SHOWED') != "show"
|
||||||
if m.group('SHOWED') == "show": shown = True
|
|
||||||
else: mucked = True
|
|
||||||
|
|
||||||
hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked)
|
hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=True, mucked=mucked)
|
||||||
|
|
||||||
def ringBlinds(ringLimit):
|
def ringBlinds(ringLimit):
|
||||||
"Returns blinds for current limit in cash games"
|
"Returns blinds for current limit in cash games"
|
||||||
|
|
307
pyfpdb/SQL.py
307
pyfpdb/SQL.py
|
@ -1645,15 +1645,6 @@ class Sql:
|
||||||
where Id = %s
|
where Id = %s
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.query['get_action_from_hand'] = """
|
|
||||||
SELECT street, Players.name, HandsActions.action, HandsActions.amount, actionno
|
|
||||||
FROM Players, HandsActions, HandsPlayers
|
|
||||||
WHERE HandsPlayers.handid = %s
|
|
||||||
AND HandsPlayers.playerid = Players.id
|
|
||||||
AND HandsActions.handsPlayerId = HandsPlayers.id
|
|
||||||
ORDER BY street, actionno
|
|
||||||
"""
|
|
||||||
|
|
||||||
if db_server == 'mysql':
|
if db_server == 'mysql':
|
||||||
self.query['get_hand_1day_ago'] = """
|
self.query['get_hand_1day_ago'] = """
|
||||||
select coalesce(max(id),0)
|
select coalesce(max(id),0)
|
||||||
|
@ -1890,6 +1881,272 @@ class Sql:
|
||||||
,maxbigblind desc
|
,maxbigblind desc
|
||||||
,s.name
|
,s.name
|
||||||
"""
|
"""
|
||||||
|
elif db_server == 'sqlite':
|
||||||
|
self.query['playerDetailedStats'] = """
|
||||||
|
select <hgameTypeId> AS hgametypeid
|
||||||
|
,gt.base
|
||||||
|
,gt.category AS category
|
||||||
|
,upper(gt.limitType) AS limittype
|
||||||
|
,s.name AS 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*/
|
||||||
|
,0.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
|
||||||
|
,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':
|
elif db_server == 'sqlite':
|
||||||
self.query['playerDetailedStats'] = """
|
self.query['playerDetailedStats'] = """
|
||||||
select <hgameTypeId> AS hgametypeid
|
select <hgameTypeId> AS hgametypeid
|
||||||
|
@ -2474,6 +2731,25 @@ class Sql:
|
||||||
GROUP BY h.handStart, hp.handId, hp.totalProfit
|
GROUP BY h.handStart, hp.handId, hp.totalProfit
|
||||||
ORDER BY h.handStart"""
|
ORDER BY h.handStart"""
|
||||||
|
|
||||||
|
####################################
|
||||||
|
# Session stats query
|
||||||
|
####################################
|
||||||
|
if db_server == 'mysql':
|
||||||
|
self.query['sessionStats'] = """
|
||||||
|
SELECT UNIX_TIMESTAMP(h.handStart) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
|
||||||
|
FROM HandsPlayers hp
|
||||||
|
INNER JOIN Players pl ON (pl.id = hp.playerId)
|
||||||
|
INNER JOIN Hands h ON (h.id = hp.handId)
|
||||||
|
INNER JOIN Gametypes gt ON (gt.id = h.gametypeId)
|
||||||
|
WHERE pl.id in <player_test>
|
||||||
|
AND pl.siteId in <site_test>
|
||||||
|
AND h.handStart > '<startdate_test>'
|
||||||
|
AND h.handStart < '<enddate_test>'
|
||||||
|
<limit_test>
|
||||||
|
AND hp.tourneysPlayersId IS NULL
|
||||||
|
GROUP BY h.handStart, hp.handId, hp.totalProfit
|
||||||
|
ORDER BY h.handStart"""
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
# Session stats query
|
# Session stats query
|
||||||
####################################
|
####################################
|
||||||
|
@ -2500,7 +2776,17 @@ class Sql:
|
||||||
AND h.handStart <datestest>
|
AND h.handStart <datestest>
|
||||||
ORDER by time"""
|
ORDER by time"""
|
||||||
elif db_server == 'sqlite':
|
elif db_server == 'sqlite':
|
||||||
self.query['sessionStats'] = """ """
|
self.query['sessionStats'] = """
|
||||||
|
SELECT STRFTIME('<ampersand_s>', h.handStart) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
|
||||||
|
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 h.handStart <datestest>
|
||||||
|
ORDER by time"""
|
||||||
|
|
||||||
|
|
||||||
####################################
|
####################################
|
||||||
# Queries to rebuild/modify hudcache
|
# Queries to rebuild/modify hudcache
|
||||||
|
@ -2656,6 +2942,7 @@ class Sql:
|
||||||
,hc_position
|
,hc_position
|
||||||
,hp.tourneyTypeId
|
,hp.tourneyTypeId
|
||||||
,date_format(h.handStart, 'd%y%m%d')
|
,date_format(h.handStart, 'd%y%m%d')
|
||||||
|
>>>>>>> 28ca49d592c8e706ad6ee58dd26655bcc33fc5fb:pyfpdb/SQL.py
|
||||||
"""
|
"""
|
||||||
elif db_server == 'postgresql':
|
elif db_server == 'postgresql':
|
||||||
self.query['rebuildHudCache'] = """
|
self.query['rebuildHudCache'] = """
|
||||||
|
|
|
@ -238,7 +238,8 @@ def discover_nt_by_name(c, tablename):
|
||||||
try:
|
try:
|
||||||
# maybe it's better to make global titles[hwnd] decoding?
|
# maybe it's better to make global titles[hwnd] decoding?
|
||||||
# this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html
|
# this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html
|
||||||
if not tablename.lower() in titles[hwnd].decode(LOCALE_ENCODING).lower(): continue
|
if not tablename.lower() in titles[hwnd].decode(LOCALE_ENCODING).lower():
|
||||||
|
continue
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window
|
if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window
|
||||||
|
@ -246,8 +247,8 @@ def discover_nt_by_name(c, tablename):
|
||||||
if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows
|
if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows
|
||||||
if ' - Table ' in titles[hwnd]: continue # Absolute table Chat window.. sigh. TODO: Can we tell what site we're trying to discover for somehow in here, so i can limit this check just to AP searches?
|
if ' - Table ' in titles[hwnd]: continue # Absolute table Chat window.. sigh. TODO: Can we tell what site we're trying to discover for somehow in here, so i can limit this check just to AP searches?
|
||||||
temp = decode_windows(c, titles[hwnd], hwnd)
|
temp = decode_windows(c, titles[hwnd], hwnd)
|
||||||
#print "attach to window", temp
|
print "attach to window", temp
|
||||||
return decode_windows(c, titles[hwnd], hwnd)
|
return temp
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def discover_nt_tournament(c, tour_number, tab_number):
|
def discover_nt_tournament(c, tour_number, tab_number):
|
||||||
|
@ -257,9 +258,12 @@ def discover_nt_tournament(c, tour_number, tab_number):
|
||||||
titles ={}
|
titles ={}
|
||||||
win32gui.EnumWindows(win_enum_handler, titles)
|
win32gui.EnumWindows(win_enum_handler, titles)
|
||||||
for hwnd in titles:
|
for hwnd in titles:
|
||||||
if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows
|
# Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows
|
||||||
if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window
|
if 'Chat:' in titles[hwnd]: continue
|
||||||
if 'HUD:' in titles[hwnd]: continue # FPDB HUD window
|
# Everleaf Network HH viewer window
|
||||||
|
if 'History for table:' in titles[hwnd]: continue
|
||||||
|
# FPDB HUD window
|
||||||
|
if 'HUD:' in titles[hwnd]: continue
|
||||||
|
|
||||||
if re.search(search_string, titles[hwnd]):
|
if re.search(search_string, titles[hwnd]):
|
||||||
return decode_windows(c, titles[hwnd], hwnd)
|
return decode_windows(c, titles[hwnd], hwnd)
|
||||||
|
@ -268,22 +272,34 @@ def discover_nt_tournament(c, tour_number, tab_number):
|
||||||
def get_nt_exe(hwnd):
|
def get_nt_exe(hwnd):
|
||||||
"""Finds the name of the executable that the given window handle belongs to."""
|
"""Finds the name of the executable that the given window handle belongs to."""
|
||||||
|
|
||||||
# Request privileges to enable "debug process", so we can later use PROCESS_VM_READ, retardedly required to GetModuleFileNameEx()
|
# Request privileges to enable "debug process", so we can later use
|
||||||
|
# PROCESS_VM_READ, retardedly required to GetModuleFileNameEx()
|
||||||
priv_flags = win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY
|
priv_flags = win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY
|
||||||
hToken = win32security.OpenProcessToken (win32api.GetCurrentProcess(), priv_flags)
|
hToken = win32security.OpenProcessToken (win32api.GetCurrentProcess(),
|
||||||
|
priv_flags)
|
||||||
# enable "debug process"
|
# enable "debug process"
|
||||||
privilege_id = win32security.LookupPrivilegeValue (None, win32security.SE_DEBUG_NAME)
|
privilege_id = win32security.LookupPrivilegeValue(None,
|
||||||
old_privs = win32security.AdjustTokenPrivileges (hToken, 0, [(privilege_id, win32security.SE_PRIVILEGE_ENABLED)])
|
win32security.SE_DEBUG_NAME)
|
||||||
|
old_privs = win32security.AdjustTokenPrivileges(hToken, 0,
|
||||||
|
[(privilege_id,
|
||||||
|
win32security.SE_PRIVILEGE_ENABLED)])
|
||||||
|
|
||||||
# Open the process, and query it's filename
|
# Open the process, and query it's filename
|
||||||
processid = win32process.GetWindowThreadProcessId(hwnd)
|
processid = win32process.GetWindowThreadProcessId(hwnd)
|
||||||
pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, processid[1])
|
pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION |
|
||||||
exename = win32process.GetModuleFileNameEx(pshandle, 0)
|
win32con.PROCESS_VM_READ, False,
|
||||||
|
processid[1])
|
||||||
# clean up
|
try:
|
||||||
win32api.CloseHandle(pshandle)
|
exename = win32process.GetModuleFileNameEx(pshandle, 0)
|
||||||
win32api.CloseHandle(hToken)
|
except pywintypes.error:
|
||||||
|
# insert code to call GetProcessImageName if we can find it..
|
||||||
|
# returning None from here will hopefully break all following code
|
||||||
|
exename = None
|
||||||
|
finally:
|
||||||
|
# clean up
|
||||||
|
win32api.CloseHandle(pshandle)
|
||||||
|
win32api.CloseHandle(hToken)
|
||||||
|
|
||||||
return exename
|
return exename
|
||||||
|
|
||||||
def decode_windows(c, title, hwnd):
|
def decode_windows(c, title, hwnd):
|
||||||
|
@ -305,6 +321,8 @@ def decode_windows(c, title, hwnd):
|
||||||
info['width'] = int( width ) - 2*b_width
|
info['width'] = int( width ) - 2*b_width
|
||||||
info['height'] = int( height ) - b_width - tb_height
|
info['height'] = int( height ) - b_width - tb_height
|
||||||
info['exe'] = get_nt_exe(hwnd)
|
info['exe'] = get_nt_exe(hwnd)
|
||||||
|
print "get_nt_exe returned ", info['exe']
|
||||||
|
# TODO: 'width' here is all sorts of screwed up.
|
||||||
|
|
||||||
title_bits = re.split(' - ', info['title'])
|
title_bits = re.split(' - ', info['title'])
|
||||||
info['name'] = title_bits[0]
|
info['name'] = title_bits[0]
|
||||||
|
|
|
@ -78,7 +78,7 @@ class fpdb_db:
|
||||||
if use_pool:
|
if use_pool:
|
||||||
MySQLdb = pool.manage(MySQLdb, pool_size=5)
|
MySQLdb = pool.manage(MySQLdb, pool_size=5)
|
||||||
# try:
|
# try:
|
||||||
self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True)
|
self.db = MySQLdb.connect(host=host, user=user, passwd=password, db=database, use_unicode=True)
|
||||||
#TODO: Add port option
|
#TODO: Add port option
|
||||||
# except:
|
# except:
|
||||||
# raise FpdbMySQLFailedError("MySQL connection failed")
|
# raise FpdbMySQLFailedError("MySQL connection failed")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user