sqlcoder initial updates

This commit is contained in:
sqlcoder 2008-12-02 00:15:50 +00:00
parent 5884f2f66b
commit a824814c0a
15 changed files with 2578 additions and 2334 deletions

0
pyfpdb/CliFpdb.py Executable file → Normal file
View File

121
pyfpdb/Configuration.py Executable file → Normal file
View File

@ -57,6 +57,8 @@ class Site:
self.hudbgcolor = node.getAttribute("bgcolor") self.hudbgcolor = node.getAttribute("bgcolor")
self.hudfgcolor = node.getAttribute("fgcolor") self.hudfgcolor = node.getAttribute("fgcolor")
self.converter = node.getAttribute("converter") self.converter = node.getAttribute("converter")
self.enabled = node.getAttribute("enabled")
self.aux_window = node.getAttribute("aux_window")
self.layout = {} self.layout = {}
for layout_node in node.getElementsByTagName('layout'): for layout_node in node.getElementsByTagName('layout'):
@ -99,6 +101,7 @@ class Game:
self.db = node.getAttribute("db") self.db = node.getAttribute("db")
self.rows = int( node.getAttribute("rows") ) self.rows = int( node.getAttribute("rows") )
self.cols = int( node.getAttribute("cols") ) self.cols = int( node.getAttribute("cols") )
self.aux = node.getAttribute("aux")
self.stats = {} self.stats = {}
for stat_node in node.getElementsByTagName('stat'): for stat_node in node.getElementsByTagName('stat'):
@ -119,6 +122,7 @@ class Game:
temp = temp + " db = %s\n" % self.db temp = temp + " db = %s\n" % self.db
temp = temp + " rows = %d\n" % self.rows temp = temp + " rows = %d\n" % self.rows
temp = temp + " cols = %d\n" % self.cols temp = temp + " cols = %d\n" % self.cols
temp = temp + " aux = %s\n" % self.aux
for stat in self.stats.keys(): for stat in self.stats.keys():
temp = temp + "%s" % self.stats[stat] temp = temp + "%s" % self.stats[stat]
@ -143,18 +147,20 @@ class Database:
temp = temp + ' ' + key + " = " + value + "\n" temp = temp + ' ' + key + " = " + value + "\n"
return temp return temp
class Mucked: class Aux_window:
def __init__(self, node): def __init__(self, node):
self.name = node.getAttribute("mw_name") for (name, value) in node.attributes.items():
self.cards = node.getAttribute("deck") setattr(self, name, value)
self.card_wd = node.getAttribute("card_wd") # self.name = node.getAttribute("mw_name")
self.card_ht = node.getAttribute("card_ht") # self.cards = node.getAttribute("deck")
self.rows = node.getAttribute("rows") # self.card_wd = node.getAttribute("card_wd")
self.cols = node.getAttribute("cols") # self.card_ht = node.getAttribute("card_ht")
self.format = node.getAttribute("stud") # self.rows = node.getAttribute("rows")
# self.cols = node.getAttribute("cols")
# self.format = node.getAttribute("stud")
def __str__(self): def __str__(self):
temp = 'Mucked = ' + self.name + "\n" temp = 'Aux = ' + self.name + "\n"
for key in dir(self): for key in dir(self):
if key.startswith('__'): continue if key.startswith('__'): continue
value = getattr(self, key) value = getattr(self, key)
@ -177,11 +183,12 @@ class Popup:
class Import: class Import:
def __init__(self, node): def __init__(self, node):
self.interval = node.getAttribute("interval") self.interval = node.getAttribute("interval")
self.callFpdbHud = node.getAttribute("callFpdbHud") self.callFpdbHud = node.getAttribute("callFpdbHud")
self.hhArchiveBase = node.getAttribute("hhArchiveBase")
def __str__(self): def __str__(self):
return " interval = %s\n callFpdbHud = %s\n" % (self.interval, self.callFpdbHud) return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s" % (self.interval, self.callFpdbHud, self.hhArchiveBase)
class Tv: class Tv:
def __init__(self, node): def __init__(self, node):
@ -236,7 +243,7 @@ class Config:
self.supported_sites = {} self.supported_sites = {}
self.supported_games = {} self.supported_games = {}
self.supported_databases = {} self.supported_databases = {}
self.mucked_windows = {} self.aux_windows = {}
self.popup_windows = {} self.popup_windows = {}
# s_sites = doc.getElementsByTagName("supported_sites") # s_sites = doc.getElementsByTagName("supported_sites")
@ -255,9 +262,9 @@ class Config:
self.supported_databases[db.db_name] = db self.supported_databases[db.db_name] = db
# s_dbs = doc.getElementsByTagName("mucked_windows") # s_dbs = doc.getElementsByTagName("mucked_windows")
for mw_node in doc.getElementsByTagName("mw"): for aw_node in doc.getElementsByTagName("aw"):
mw = Mucked(node = mw_node) aw = Aux_window(node = aw_node)
self.mucked_windows[mw.name] = mw self.aux_windows[aw.name] = aw
# s_dbs = doc.getElementsByTagName("popup_windows") # s_dbs = doc.getElementsByTagName("popup_windows")
for pu_node in doc.getElementsByTagName("pu"): for pu_node in doc.getElementsByTagName("pu"):
@ -377,7 +384,6 @@ class Config:
def edit_layout(self, site_name, max, width = None, height = None, def edit_layout(self, site_name, max, width = None, height = None,
fav_seat = None, locations = None): fav_seat = None, locations = None):
print "max = ", max
site_node = self.get_site_node(site_name) site_node = self.get_site_node(site_name)
layout_node = self.get_layout_node(site_node, max) layout_node = self.get_layout_node(site_node, max)
if layout_node == None: return if layout_node == None: return
@ -437,11 +443,13 @@ class Config:
def get_import_parameters(self): def get_import_parameters(self):
imp = {} imp = {}
try: try:
imp['imp-callFpdbHud'] = self.imp.callFpdbHud imp['callFpdbHud'] = self.callFpdbHud
imp['hud-defaultInterval'] = int(self.imp.interval) imp['interval'] = self.interval
except: # Default import parameters imp['hhArchiveBase'] = self.hhArchiveBase
imp['imp-callFpdbHud'] = True except: # Default params
imp['hud-defaultInterval'] = 10 imp['callFpdbHud'] = True
imp['interval'] = 10
imp['hhArchiveBase'] = "~/.fpdb/HandHistories/"
return imp return imp
def get_default_paths(self, site = "PokerStars"): def get_default_paths(self, site = "PokerStars"):
@ -480,6 +488,10 @@ class Config:
( 0, 280), (121, 280), ( 46, 30) ) ( 0, 280), (121, 280), ( 46, 30) )
return locations return locations
def get_supported_sites(self):
"""Returns the list of supported sites."""
return self.supported_sites.keys()
def get_site_parameters(self, site): def get_site_parameters(self, site):
"""Returns a dict of the site parameters for the specified site""" """Returns a dict of the site parameters for the specified site"""
if not self.supported_sites.has_key(site): if not self.supported_sites.has_key(site):
@ -494,13 +506,16 @@ class Config:
parms["site_path"] = self.supported_sites[site].site_path parms["site_path"] = self.supported_sites[site].site_path
parms["table_finder"] = self.supported_sites[site].table_finder parms["table_finder"] = self.supported_sites[site].table_finder
parms["HH_path"] = self.supported_sites[site].HH_path parms["HH_path"] = self.supported_sites[site].HH_path
parms["site_name"] = self.supported_sites[site].site_name
parms["enabled"] = self.supported_sites[site].enabled
parms["aux_window"] = self.supported_sites[site].aux_window
return parms return parms
def set_site_parameters(self, site_name, converter = None, decoder = None, def set_site_parameters(self, site_name, converter = None, decoder = None,
hudbgcolor = None, hudfgcolor = None, hudbgcolor = None, hudfgcolor = None,
hudopacity = None, screen_name = None, hudopacity = None, screen_name = None,
site_path = None, table_finder = None, site_path = None, table_finder = None,
HH_path = None): HH_path = None, enabled = None):
"""Sets the specified site parameters for the specified site.""" """Sets the specified site parameters for the specified site."""
site_node = self.get_site_node(site_name) site_node = self.get_site_node(site_name)
if not db_node == None: if not db_node == None:
@ -513,6 +528,7 @@ class Config:
if not site_path == None: site_node.setAttribute("site_path", site_path) if not site_path == None: site_node.setAttribute("site_path", site_path)
if not table_finder == None: site_node.setAttribute("table_finder", table_finder) if not table_finder == None: site_node.setAttribute("table_finder", table_finder)
if not HH_path == None: site_node.setAttribute("HH_path", HH_path) if not HH_path == None: site_node.setAttribute("HH_path", HH_path)
if not enabled == None: site_node.setAttribute("enabled", enabled)
if self.supported_databases.has_key(db_name): if self.supported_databases.has_key(db_name):
if not converter == None: self.supported_sites[site].converter = converter if not converter == None: self.supported_sites[site].converter = converter
@ -524,8 +540,47 @@ class Config:
if not site_path == None: self.supported_sites[site].site_path = site_path if not site_path == None: self.supported_sites[site].site_path = site_path
if not table_finder == None: self.supported_sites[site].table_finder = table_finder if not table_finder == None: self.supported_sites[site].table_finder = table_finder
if not HH_path == None: self.supported_sites[site].HH_path = HH_path if not HH_path == None: self.supported_sites[site].HH_path = HH_path
if not enabled == None: self.supported_sites[site].enabled = enabled
return return
def get_aux_windows(self):
"""Gets the list of mucked window formats in the configuration."""
mw = []
for w in self.aux_windows.keys():
mw.append(w)
return mw
def get_aux_parameters(self, name):
"""Gets a dict of mucked window parameters from the named mw."""
param = {}
if self.aux_windows.has_key(name):
for key in dir(self.aux_windows[name]):
if key.startswith('__'): continue
value = getattr(self.aux_windows[name], key)
if callable(value): continue
param[key] = value
return param
return None
def get_game_parameters(self, name):
"""Get the configuration parameters for the named game."""
param = {}
if self.supported_games.has_key(name):
param['game_name'] = self.supported_games[name].game_name
param['db'] = self.supported_games[name].db
param['rows'] = self.supported_games[name].rows
param['cols'] = self.supported_games[name].cols
param['aux'] = self.supported_games[name].aux
return param
def get_supported_games(self):
"""Get the list of supported games."""
sg = []
for game in c.supported_games.keys():
sg.append(c.supported_games[game].game_name)
return sg
if __name__== "__main__": if __name__== "__main__":
c = Config() c = Config()
@ -546,18 +601,20 @@ if __name__== "__main__":
print c.supported_databases[db] print c.supported_databases[db]
print "----------- END SUPPORTED DATABASES -----------" print "----------- END SUPPORTED DATABASES -----------"
print "\n----------- MUCKED WINDOW FORMATS -----------" print "\n----------- AUX WINDOW FORMATS -----------"
for w in c.mucked_windows.keys(): for w in c.aux_windows.keys():
print c.mucked_windows[w] print c.aux_windows[w]
print "----------- END MUCKED WINDOW FORMATS -----------" print "----------- END AUX WINDOW FORMATS -----------"
print "\n----------- POPUP WINDOW FORMATS -----------" print "\n----------- POPUP WINDOW FORMATS -----------"
for w in c.popup_windows.keys(): for w in c.popup_windows.keys():
print c.popup_windows[w] print c.popup_windows[w]
print "----------- END MUCKED WINDOW FORMATS -----------" print "----------- END POPUP WINDOW FORMATS -----------"
print "\n----------- IMPORT -----------" print "\n----------- IMPORT -----------"
# print c.imp tmp = c.get_import_parameters()
for param in tmp:
print " " + str(param) + ": " + str(tmp[param])
print "----------- END IMPORT -----------" print "----------- END IMPORT -----------"
print "\n----------- TABLE VIEW -----------" print "\n----------- TABLE VIEW -----------"
@ -573,6 +630,12 @@ if __name__== "__main__":
print "paths = ", c.get_default_paths("PokerStars") print "paths = ", c.get_default_paths("PokerStars")
print "colors = ", c.get_default_colors("PokerStars") print "colors = ", c.get_default_colors("PokerStars")
print "locs = ", c.get_locations("PokerStars", 8) print "locs = ", c.get_locations("PokerStars", 8)
for mw in c.get_aux_windows():
print c.get_aux_parameters(mw)
for site in c.supported_sites.keys(): for site in c.supported_sites.keys():
print "site = ", site, print "site = ", site,
print c.get_site_parameters(site) print c.get_site_parameters(site)
for game in c.get_supported_games():
print c.get_game_parameters(game)

View File

@ -601,7 +601,34 @@ class FpdbSQLQueries:
WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL) WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)
ORDER BY handStart""" ORDER BY handStart"""
# Returns the profit for a given ring game handId, Total pot - money invested by playerId # Returns the profit for all hands, Total pot - money invested by playerId
if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
self.query['getRingProfitAllHandsPlayerIdSite'] = """
SELECT hp.handId, hp.winnings, SUM(ha.amount) costs, hp.winnings - SUM(ha.amount) profit
FROM HandsPlayers hp
INNER JOIN Players pl ON hp.playerId = pl.id
INNER JOIN Hands h ON h.id = hp.handId
INNER JOIN HandsActions ha ON ha.handPlayerId = hp.id
WHERE pl.name = %s
AND pl.siteId = %s
AND hp.tourneysPlayersId IS NULL
group by hp.handId, hp.winnings, h.handStart
ORDER BY h.handStart"""
elif(self.dbname == 'SQLite'):
#May not work.
self.query['getRingProfitAllHandsPlayerIdSite'] = """
SELECT hp.handId, hp.winnings, SUM(ha.amount) costs, hp.winnings - SUM(ha.amount) profit
FROM HandsPlayers hp
INNER JOIN Players pl ON hp.playerId = pl.id
INNER JOIN Hands h ON h.id = hp.handId
INNER JOIN HandsActions ha ON ha.handPlayerId = hp.id
WHERE pl.name = %s
AND pl.siteId = %s
AND hp.tourneysPlayersId IS NULL
group by hp.handId, hp.winnings, h.handStart
ORDER BY h.handStart"""
# Returns the profit for a given ring game handId, Total pot - money invested by playerId - WRONG, returns players costs
if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'): if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id

View File

@ -26,175 +26,170 @@ import os
import time import time
import fpdb_import import fpdb_import
class GuiAutoImport (threading.Thread): class GuiAutoImport (threading.Thread):
def starsBrowseClicked(self, widget, data): def __init__(self, settings, config):
"""runs when user clicks browse on auto import tab""" """Constructor for GuiAutoImport"""
#print "start of GuiAutoImport.starsBrowseClicked" self.settings=settings
current_path=self.starsDirPath.get_text() self.config=config
dia_chooser = gtk.FileChooserDialog(title="Please choose the path that you want to auto import", imp = self.config.get_import_parameters()
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
#dia_chooser.set_current_folder(pathname)
dia_chooser.set_filename(current_path)
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
response = dia_chooser.run() print "Import parameters"
if response == gtk.RESPONSE_OK: print imp
#print dia_chooser.get_filename(), 'selected'
self.starsDirPath.set_text(dia_chooser.get_filename())
elif response == gtk.RESPONSE_CANCEL:
print 'Closed, no files selected'
dia_chooser.destroy()
#end def GuiAutoImport.starsBrowseClicked
def tiltBrowseClicked(self, widget, data): self.input_settings = {}
"""runs when user clicks browse on auto import tab"""
#print "start of GuiAutoImport.tiltBrowseClicked"
current_path=self.tiltDirPath.get_text()
dia_chooser = gtk.FileChooserDialog(title="Please choose the path that you want to auto import", self.importer = fpdb_import.Importer(self, self.settings, self.config)
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, self.importer.setCallHud(True)
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) self.importer.setMinPrint(30)
#dia_chooser.set_current_folder(pathname) self.importer.setQuiet(False)
dia_chooser.set_filename(current_path) self.importer.setFailOnError(False)
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import self.importer.setHandCount(0)
# self.importer.setWatchTime()
response = dia_chooser.run() self.server=settings['db-host']
if response == gtk.RESPONSE_OK: self.user=settings['db-user']
#print dia_chooser.get_filename(), 'selected' self.password=settings['db-password']
self.tiltDirPath.set_text(dia_chooser.get_filename()) self.database=settings['db-databaseName']
elif response == gtk.RESPONSE_CANCEL:
print 'Closed, no files selected'
dia_chooser.destroy()
#end def GuiAutoImport.tiltBrowseClicked
def do_import(self): self.mainVBox=gtk.VBox(False,1)
"""Callback for timer to do an import iteration.""" self.mainVBox.show()
self.importer.runUpdated()
print "GuiAutoImport.import_dir done"
return True
def startClicked(self, widget, data): self.settingsHBox = gtk.HBox(False, 0)
"""runs when user clicks start on auto import tab""" self.mainVBox.pack_start(self.settingsHBox, False, True, 0)
self.settingsHBox.show()
# Check to see if we have an open file handle to the HUD and open one if we do not. self.intervalLabel = gtk.Label("Time between imports in seconds:")
# bufsize = 1 means unbuffered self.settingsHBox.pack_start(self.intervalLabel)
# We need to close this file handle sometime. self.intervalLabel.show()
# TODO: Allow for importing from multiple dirs - REB 29AUG2008 self.intervalEntry=gtk.Entry()
# As presently written this function does nothing if there is already a pipe open. self.intervalEntry.set_text(str(self.config.get_import_parameters().get("interval")))
# That is not correct. It should open another dir for importing while piping the self.settingsHBox.pack_start(self.intervalEntry)
# results to the same pipe. This means that self.path should be a a list of dirs self.intervalEntry.show()
# to watch.
try: #uhhh, I don't this this is the best way to check for the existence of an attr
getattr(self, "pipe_to_hud")
except AttributeError:
if os.name == 'nt':
command = "python HUD_main.py" + " %s" % (self.database)
bs = 0 # windows is not happy with line buffing here
self.pipe_to_hud = subprocess.Popen(command, bufsize = bs, stdin = subprocess.PIPE,
universal_newlines=True)
else:
cwd = os.getcwd()
command = os.path.join(cwd, 'HUD_main.py')
bs = 1
self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
universal_newlines=True)
# self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
# universal_newlines=True)
# command = command + " %s" % (self.database)
# print "command = ", command
# self.pipe_to_hud = os.popen(command, 'w')
self.starspath=self.starsDirPath.get_text()
self.tiltpath=self.tiltDirPath.get_text()
# Add directory to importer object. self.addSites(self.mainVBox)
self.importer.addImportDirectory(self.starspath, True, "PokerStars", "passthrough")
self.importer.addImportDirectory(self.tiltpath, True, "FullTilt", "passthrough")
self.do_import()
interval=int(self.intervalEntry.get_text()) self.startButton=gtk.Button("Start Autoimport")
gobject.timeout_add(interval*1000, self.do_import) self.startButton.connect("clicked", self.startClicked, "start clicked")
#end def GuiAutoImport.startClicked self.mainVBox.add(self.startButton)
self.startButton.show()
def get_vbox(self):
"""returns the vbox of this thread"""
return self.mainVBox
#end def get_vbox
def __init__(self, settings, config, debug=True): #end of GuiAutoImport.__init__
"""Constructor for GuiAutoImport""" def browseClicked(self, widget, data):
self.settings=settings """runs when user clicks one of the browse buttons in the auto import tab"""
self.config=config current_path=data[1].get_text()
self.importer = fpdb_import.Importer(self,self.settings)
self.importer.setCallHud(True)
self.importer.setMinPrint(30)
self.importer.setQuiet(False)
self.importer.setFailOnError(False)
self.importer.setHandCount(0)
# self.importer.setWatchTime()
self.server=settings['db-host'] dia_chooser = gtk.FileChooserDialog(title="Please choose the path that you want to auto import",
self.user=settings['db-user'] action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
self.password=settings['db-password'] buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
self.database=settings['db-databaseName'] #dia_chooser.set_current_folder(pathname)
dia_chooser.set_filename(current_path)
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
self.mainVBox=gtk.VBox(False,1) response = dia_chooser.run()
self.mainVBox.show() if response == gtk.RESPONSE_OK:
#print dia_chooser.get_filename(), 'selected'
data[1].set_text(dia_chooser.get_filename())
self.input_settings[data[0]][0] = dia_chooser.get_filename()
elif response == gtk.RESPONSE_CANCEL:
print 'Closed, no files selected'
dia_chooser.destroy()
#end def GuiAutoImport.browseClicked
self.settingsHBox = gtk.HBox(False, 0) def do_import(self):
self.mainVBox.pack_start(self.settingsHBox, False, True, 0) """Callback for timer to do an import iteration."""
self.settingsHBox.show() self.importer.runUpdated()
print "GuiAutoImport.import_dir done"
return True
self.intervalLabel = gtk.Label("Interval (ie. break) between imports in seconds:") def startClicked(self, widget, data):
self.settingsHBox.pack_start(self.intervalLabel) """runs when user clicks start on auto import tab"""
self.intervalLabel.show()
self.intervalEntry=gtk.Entry() # Check to see if we have an open file handle to the HUD and open one if we do not.
self.intervalEntry.set_text(str(self.settings['hud-defaultInterval'])) # bufsize = 1 means unbuffered
self.settingsHBox.pack_start(self.intervalEntry) # We need to close this file handle sometime.
self.intervalEntry.show()
self.pathHBox = gtk.HBox(False, 0) # TODO: Allow for importing from multiple dirs - REB 29AUG2008
self.mainVBox.pack_start(self.pathHBox, False, True, 0) # As presently written this function does nothing if there is already a pipe open.
self.pathHBox.show() # That is not correct. It should open another dir for importing while piping the
# results to the same pipe. This means that self.path should be a a list of dirs
# to watch.
try: #uhhh, I don't this this is the best way to check for the existence of an attr
getattr(self, "pipe_to_hud")
except AttributeError:
if os.name == 'nt':
command = "python HUD_main.py" + " %s" % (self.database)
bs = 0 # windows is not happy with line buffing here
self.pipe_to_hud = subprocess.Popen(command, bufsize = bs, stdin = subprocess.PIPE,
universal_newlines=True)
else:
cwd = os.getcwd()
command = os.path.join(cwd, 'HUD_main.py')
bs = 1
self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
universal_newlines=True)
# self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
# universal_newlines=True)
# command = command + " %s" % (self.database)
# print "command = ", command
# self.pipe_to_hud = os.popen(command, 'w')
self.pathStarsLabel = gtk.Label("Path to PokerStars auto-import:") # Add directories to importer object.
self.pathHBox.pack_start(self.pathStarsLabel, False, False, 0) for site in self.input_settings:
self.pathStarsLabel.show() self.importer.addImportDirectory(self.input_settings[site][0], True, site, self.input_settings[site][1])
print "Adding import directories - Site: " + site + " dir: "+ str(self.input_settings[site][0])
self.do_import()
self.starsDirPath=gtk.Entry() interval=int(self.intervalEntry.get_text())
paths = self.config.get_default_paths("PokerStars") gobject.timeout_add(interval*1000, self.do_import)
self.starsDirPath.set_text(paths['hud-defaultPath']) #end def GuiAutoImport.startClicked
self.pathHBox.pack_start(self.starsDirPath, False, True, 0)
self.starsDirPath.show()
self.browseButton=gtk.Button("Browse...") def get_vbox(self):
self.browseButton.connect("clicked", self.starsBrowseClicked, "Browse clicked") """returns the vbox of this thread"""
self.pathHBox.pack_start(self.browseButton, False, False, 0) return self.mainVBox
self.browseButton.show() #end def get_vbox
self.pathTiltLabel = gtk.Label("Path to Full Tilt auto-import:") #Create the site line given required info and setup callbacks
self.pathHBox.pack_start(self.pathTiltLabel, False, False, 0) #enabling and disabling sites from this interface not possible
self.pathTiltLabel.show() #expects a box to layout the line horizontally
def createSiteLine(self, hbox, site, iconpath, hhpath, filter_name, active = True):
label = gtk.Label(site + " auto-import:")
hbox.pack_start(label, False, False, 0)
label.show()
self.tiltDirPath=gtk.Entry() dirPath=gtk.Entry()
paths = self.config.get_default_paths("Full Tilt") dirPath.set_text(hhpath)
self.tiltDirPath.set_text(paths['hud-defaultPath']) hbox.pack_start(dirPath, False, True, 0)
self.pathHBox.pack_start(self.tiltDirPath, False, True, 0) dirPath.show()
self.tiltDirPath.show()
self.browseButton=gtk.Button("Browse...") browseButton=gtk.Button("Browse...")
self.browseButton.connect("clicked", self.tiltBrowseClicked, "Browse clicked") browseButton.connect("clicked", self.browseClicked, [site] + [dirPath])
self.pathHBox.pack_start(self.browseButton, False, False, 0) hbox.pack_start(browseButton, False, False, 0)
self.browseButton.show() browseButton.show()
label = gtk.Label(site + " filter:")
hbox.pack_start(label, False, False, 0)
label.show()
filter=gtk.Entry()
filter.set_text(filter_name)
hbox.pack_start(filter, False, True, 0)
filter.show()
def addSites(self, vbox):
for site in self.config.supported_sites.keys():
pathHBox = gtk.HBox(False, 0)
vbox.pack_start(pathHBox, False, True, 0)
pathHBox.show()
paths = self.config.get_default_paths(site)
params = self.config.get_site_parameters(site)
self.createSiteLine(pathHBox, site, False, paths['hud-defaultPath'], params['converter'], params['enabled'])
self.input_settings[site] = [paths['hud-defaultPath']] + [params['converter']]
self.startButton=gtk.Button("Start Autoimport")
self.startButton.connect("clicked", self.startClicked, "start clicked")
self.mainVBox.add(self.startButton)
self.startButton.show()
#end of GuiAutoImport.__init__
if __name__== "__main__": if __name__== "__main__":
def destroy(*args): # call back for terminating the main eventloop def destroy(*args): # call back for terminating the main eventloop
gtk.main_quit() gtk.main_quit()
@ -206,7 +201,7 @@ if __name__== "__main__":
settings['db-databaseName'] = "fpdb" settings['db-databaseName'] = "fpdb"
settings['hud-defaultInterval'] = 10 settings['hud-defaultInterval'] = 10
settings['hud-defaultPath'] = 'C:/Program Files/PokerStars/HandHistory/nutOmatic' settings['hud-defaultPath'] = 'C:/Program Files/PokerStars/HandHistory/nutOmatic'
settings['imp-callFpdbHud'] = True settings['callFpdbHud'] = True
i = GuiAutoImport(settings) i = GuiAutoImport(settings)
main_window = gtk.Window() main_window = gtk.Window()

View File

@ -87,16 +87,20 @@ class GuiGraphViewer (threading.Thread):
#end of def showClicked #end of def showClicked
def getRingProfitGraph(self, name, site): def getRingProfitGraph(self, name, site):
self.cursor.execute(self.sql.query['getRingWinningsAllGamesPlayerIdSite'], (name, site)) #self.cursor.execute(self.sql.query['getRingWinningsAllGamesPlayerIdSite'], (name, site))
self.cursor.execute(self.sql.query['getRingProfitAllHandsPlayerIdSite'], (name, site))
# returns (HandId,Winnings,Costs,Profit)
winnings = self.db.cursor.fetchall() winnings = self.db.cursor.fetchall()
profit=range(len(winnings)) #profit=range(len(winnings))
for i in profit: #for i in profit:
self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site)) # self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site))
spent = self.db.cursor.fetchone() # spent = self.db.cursor.fetchone()
profit[i]=(i, winnings[i][1]-spent[0]) # profit[i]=(i, winnings[i][1]-spent[0])
#y=map(lambda x:float(x[1]), profit)
y=map(lambda x:float(x[3]), winnings)
y=map(lambda x:float(x[1]), profit)
line = cumsum(y) line = cumsum(y)
return line/100 return line/100
#end of def getRingProfitGraph #end of def getRingProfitGraph

29
pyfpdb/HUD_main.py Executable file → Normal file
View File

@ -83,6 +83,8 @@ def update_HUD(new_hand_id, table_name, config, stat_dict):
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
try: try:
hud_dict[table_name].update(new_hand_id, config, stat_dict) hud_dict[table_name].update(new_hand_id, config, stat_dict)
for m in hud_dict[table_name].aux_windows:
m.update_gui(new_hand_id)
return False return False
finally: finally:
gtk.gdk.threads_leave() gtk.gdk.threads_leave()
@ -92,7 +94,7 @@ def read_stdin(): # This is the thread function
global hud_dict global hud_dict
db_connection = Database.Database(config, db_name, 'temp') db_connection = Database.Database(config, db_name, 'temp')
# tourny_finder = re.compile('(\d+) (\d+)') tourny_finder = re.compile('(\d+) (\d+)')
while True: # wait for a new hand number on stdin while True: # wait for a new hand number on stdin
new_hand_id = sys.stdin.readline() new_hand_id = sys.stdin.readline()
@ -110,28 +112,32 @@ def read_stdin(): # This is the thread function
# find out if this hand is from a tournament # find out if this hand is from a tournament
is_tournament = False is_tournament = False
# (t_number, s_number) = (0, 0) (tour_number, tab_number) = (0, 0)
# mat_obj = tourny_finder(table_name) mat_obj = tourny_finder.search(table_name)
# if len(mat_obj.groups) == 2: # if len(mat_obj.groups) == 2:
# is_tournament = True if mat_obj:
# (t_number, s_number) = mat_obj.group(1, 2) is_tournament = True
(tour_number, tab_number) = mat_obj.group(1, 2)
stat_dict = db_connection.get_stats_from_hand(new_hand_id) stat_dict = db_connection.get_stats_from_hand(new_hand_id)
# if a hud for this CASH table exists, just update it # if a hud for this CASH table exists, just update it
if hud_dict.has_key(table_name): if hud_dict.has_key(table_name):
# update the data for the aux_windows
for aw in hud_dict[table_name].aux_windows:
aw.update_data(new_hand_id)
update_HUD(new_hand_id, table_name, config, stat_dict) update_HUD(new_hand_id, table_name, config, stat_dict)
# if a hud for this TOURNAMENT table exists, just update it # if a hud for this TOURNAMENT table exists, just update it
# elif hud_dict.has_key(t_number): elif hud_dict.has_key(tour_number):
# update_HUD(new_hand_id, t_number, config, stat_dict) update_HUD(new_hand_id, tour_number, config, stat_dict)
# otherwise create a new hud # otherwise create a new hud
else: else:
if is_tournament: if is_tournament:
tablewindow = Tables.discover_tournament_table(config, t_number, s_number) tablewindow = Tables.discover_tournament_table(config, tour_number, tab_number)
if tablewindow == None: if tablewindow == None:
sys.stderr.write("table name "+table_name+" not found\n") sys.stderr.write("tournament %s, table %s not found\n" % (tour_number, tab_number))
else: else:
create_HUD(new_hand_id, tablewindow, db_name, t_number, max, poker_game, db_connection, config, stat_dict) create_HUD(new_hand_id, tablewindow, db_name, tour_number, max, poker_game, db_connection, config, stat_dict)
else: else:
tablewindow = Tables.discover_table_by_name(config, table_name) tablewindow = Tables.discover_table_by_name(config, table_name)
if tablewindow == None: if tablewindow == None:
@ -163,4 +169,3 @@ if __name__== "__main__":
main_window.show_all() main_window.show_all()
gtk.main() gtk.main()

View File

@ -59,19 +59,22 @@ class Hud:
self.stat_windows = {} self.stat_windows = {}
self.popup_windows = {} self.popup_windows = {}
self.aux_windows = []
self.font = pango.FontDescription("Sans 8") self.font = pango.FontDescription("Sans 8")
# Set up a main window for this this instance of the HUD # Set up a main window for this this instance of the HUD
self.main_window = gtk.Window() self.main_window = gtk.Window()
# self.window.set_decorated(0) # self.window.set_decorated(0)
self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC) self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC)
self.main_window.set_title(table.name + " FPDBHUD") self.main_window.set_title(table.name + " FPDBHUD")
self.main_window.connect("destroy", self.kill_hud) self.main_window.connect("destroy", self.kill_hud)
self.main_window.set_decorated(False) self.main_window.set_decorated(False)
self.main_window.set_opacity(self.colors["hudopacity"])
#self.main_window.set_transient_for(parent.get_toplevel()) #self.main_window.set_transient_for(parent.get_toplevel())
self.ebox = gtk.EventBox() self.ebox = gtk.EventBox()
self.label = gtk.Label("Right click to close HUD for %s\nor Save Stat Positions." % (table.name)) # self.label = gtk.Label("Right click to close HUD for %s\nor Save Stat Positions." % (table.name))
self.label = gtk.Label("FPDB Menu (Right Click)\nLeft-drag to move")
self.label.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudbgcolor'])) self.label.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudbgcolor']))
self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor'])) self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
@ -111,29 +114,31 @@ class Hud:
self.main_window.set_destroy_with_parent(True) self.main_window.set_destroy_with_parent(True)
def on_button_press(self, widget, event): def on_button_press(self, widget, event):
if event.button == 1:
self.main_window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
return True
if event.button == 3: if event.button == 3:
widget.popup(None, None, None, event.button, event.time) widget.popup(None, None, None, event.button, event.time)
return True return True
return False return False
def kill_hud(self, args): def kill_hud(self, *args):
for k in self.stat_windows.keys(): for k in self.stat_windows.keys():
self.stat_windows[k].window.destroy() self.stat_windows[k].window.destroy()
self.main_window.destroy() self.main_window.destroy()
self.deleted = True self.deleted = True
def reposition_windows(self, args): def reposition_windows(self, *args):
for w in self.stat_windows: for w in self.stat_windows:
self.stat_windows[w].window.move(self.stat_windows[w].x, self.stat_windows[w].window.move(self.stat_windows[w].x,
self.stat_windows[w].y) self.stat_windows[w].y)
def save_layout(self, *args): def save_layout(self, *args):
new_layout = [] new_layout = [(0, 0)] * self.max
# todo: have the hud track the poker table's window position regularly, don't forget to update table.x and table.y. # todo: have the hud track the poker table's window position regularly, don't forget to update table.x and table.y.
for sw in self.stat_windows: for sw in self.stat_windows:
loc = self.stat_windows[sw].window.get_position() loc = self.stat_windows[sw].window.get_position()
new_loc = (loc[0] - self.table.x, loc[1] - self.table.y) new_loc = (loc[0] - self.table.x, loc[1] - self.table.y)
new_layout.append(new_loc) new_layout[self.stat_windows[sw].adj - 1] = new_loc
# print new_layout
self.config.edit_layout(self.table.site, self.max, locations = new_layout) self.config.edit_layout(self.table.site, self.max, locations = new_layout)
self.config.save() self.config.save()
@ -177,6 +182,7 @@ class Hud:
x = x, x = x,
y = y, y = y,
seat = i, seat = i,
adj = adj[i],
player_id = 'fake', player_id = 'fake',
font = self.font) font = self.font)
@ -188,9 +194,11 @@ class Hud:
self.stats[config.supported_games[self.poker_game].stats[stat].row] \ self.stats[config.supported_games[self.poker_game].stats[stat].row] \
[config.supported_games[self.poker_game].stats[stat].col] = \ [config.supported_games[self.poker_game].stats[stat].col] = \
config.supported_games[self.poker_game].stats[stat].stat_name config.supported_games[self.poker_game].stats[stat].stat_name
# self.mucked_window = gtk.Window()
# self.m = Mucked.Mucked(self.mucked_window, self.db_connection) game_params = config.get_game_parameters(self.poker_game)
# self.mucked_window.show_all() if not game_params['aux'] == "":
aux_params = config.get_aux_parameters(game_params['aux'])
self.aux_windows.append(eval("%s.%s(gtk.Window(), config, 'fpdb')" % (aux_params['module'], aux_params['class'])))
def update(self, hand, config, stat_dict): def update(self, hand, config, stat_dict):
self.hand = hand # this is the last hand, so it is available later self.hand = hand # this is the last hand, so it is available later
@ -211,7 +219,9 @@ class Hud:
tip = stat_dict[s]['screen_name'] + "\n" + number[5] + "\n" + \ tip = stat_dict[s]['screen_name'] + "\n" + number[5] + "\n" + \
number[3] + ", " + number[4] number[3] + ", " + number[4]
Stats.do_tip(self.stat_windows[stat_dict[s]['seat']].e_box[r][c], tip) Stats.do_tip(self.stat_windows[stat_dict[s]['seat']].e_box[r][c], tip)
# self.m.update(hand) # for m in self.aux_windows:
# m.update_data(hand)
# m.update_gui(hand)
def topify_window(self, window): def topify_window(self, window):
"""Set the specified gtk window to stayontop in MS Windows.""" """Set the specified gtk window to stayontop in MS Windows."""
@ -259,7 +269,8 @@ class Stat_Window:
# This handles all callbacks from button presses on the event boxes in # This handles all callbacks from button presses on the event boxes in
# the stat windows. There is a bit of an ugly kludge to separate single- # the stat windows. There is a bit of an ugly kludge to separate single-
# and double-clicks. # and double-clicks.
if event.button == 1: # left button event
if event.button == 3: # right button event
if event.type == gtk.gdk.BUTTON_PRESS: # left button single click if event.type == gtk.gdk.BUTTON_PRESS: # left button single click
if self.sb_click > 0: return if self.sb_click > 0: return
self.sb_click = gobject.timeout_add(250, self.single_click, widget) self.sb_click = gobject.timeout_add(250, self.single_click, widget)
@ -270,12 +281,14 @@ class Stat_Window:
self.double_click(widget, event, *args) self.double_click(widget, event, *args)
if event.button == 2: # middle button event if event.button == 2: # middle button event
pass
# print "middle button clicked" # print "middle button clicked"
if event.button == 3: # right button event
pass pass
# print "right button clicked"
if event.button == 1: # left button event
if event.state & gtk.gdk.SHIFT_MASK:
self.window.begin_resize_drag(gtk.gdk.WINDOW_EDGE_SOUTH_EAST, event.button, int(event.x_root), int(event.y_root), event.time)
else:
self.window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
def single_click(self, widget): def single_click(self, widget):
# Callback from the timeout in the single-click finding part of the # Callback from the timeout in the single-click finding part of the
@ -305,10 +318,12 @@ class Stat_Window:
self.y = y + self.table.y self.y = y + self.table.y
self.window.move(self.x, self.y) self.window.move(self.x, self.y)
def __init__(self, parent, game, table, seat, x, y, player_id, font): def __init__(self, parent, game, table, seat, adj, x, y, player_id, font):
self.parent = parent # Hud object that this stat window belongs to self.parent = parent # Hud object that this stat window belongs to
self.game = game # Configuration object for the curren self.game = game # Configuration object for the curren
self.table = table # Table object where this is going self.table = table # Table object where this is going
self.seat = seat # seat number of his player
self.adj = adj # the adjusted seat number for this player
self.x = x + table.x # table.x and y are the location of the table self.x = x + table.x # table.x and y are the location of the table
self.y = y + table.y # x and y are the location relative to table.x & y self.y = y + table.y # x and y are the location relative to table.x & y
self.player_id = player_id # looks like this isn't used ;) self.player_id = player_id # looks like this isn't used ;)
@ -349,8 +364,9 @@ class Stat_Window:
# font = pango.FontDescription("Sans 8") # font = pango.FontDescription("Sans 8")
self.label[r][c].modify_font(font) self.label[r][c].modify_font(font)
if not os.name == 'nt': # seems to be a bug in opacity on windows # if not os.name == 'nt': # seems to be a bug in opacity on windows
self.window.set_opacity(parent.colors['hudopacity']) self.window.set_opacity(parent.colors['hudopacity'])
self.window.realize self.window.realize
self.window.move(self.x, self.y) self.window.move(self.x, self.y)
self.window.show_all() self.window.show_all()
@ -457,7 +473,7 @@ class Popup_window:
self.lab.set_text(pu_text) self.lab.set_text(pu_text)
self.window.show_all() self.window.show_all()
self.window.set_transient_for(stat_window.main_window) self.window.set_transient_for(stat_window.window)
# set_keep_above(1) for windows # set_keep_above(1) for windows
if os.name == 'nt': self.topify_window(self.window) if os.name == 'nt': self.topify_window(self.window)

View File

@ -229,14 +229,21 @@ class Sql:
sum(street3CheckCallRaiseDone) AS ccr_3, sum(street3CheckCallRaiseDone) AS ccr_3,
sum(street4CheckCallRaiseChance) AS ccr_opp_4, sum(street4CheckCallRaiseChance) AS ccr_opp_4,
sum(street4CheckCallRaiseDone) AS ccr_4 sum(street4CheckCallRaiseDone) AS ccr_4
FROM HudCache, Hands FROM Hands
WHERE HudCache.PlayerId in INNER JOIN HandsPlayers ON (HandsPlayers.handId = %s)
(SELECT PlayerId FROM HandsPlayers INNER JOIN HudCache ON ( HudCache.PlayerId = HandsPlayers.PlayerId+0
WHERE handId = %s) AND HudCache.gametypeId+0 = Hands.gametypeId+0)
AND Hands.id = %s WHERE Hands.id = %s
AND Hands.gametypeId = HudCache.gametypeId
GROUP BY HudCache.PlayerId GROUP BY HudCache.PlayerId
""" """
# FROM HudCache, Hands
# WHERE HudCache.PlayerId in
# (SELECT PlayerId FROM HandsPlayers
# WHERE handId = %s)
# AND Hands.id = %s
# AND Hands.gametypeId = HudCache.gametypeId
# AND PlayerId LIKE %s # AND PlayerId LIKE %s
# HudCache.gametypeId AS gametypeId, # HudCache.gametypeId AS gametypeId,
# activeSeats AS n_active, # activeSeats AS n_active,

View File

@ -71,6 +71,7 @@ def do_stat(stat_dict, player = 24, stat = 'vpip'):
# functions that return individual stats # functions that return individual stats
def playername(stat_dict, player): def playername(stat_dict, player):
""" Player Name."""
return (stat_dict[player]['screen_name'], return (stat_dict[player]['screen_name'],
stat_dict[player]['screen_name'], stat_dict[player]['screen_name'],
stat_dict[player]['screen_name'], stat_dict[player]['screen_name'],
@ -98,6 +99,26 @@ def vpip(stat_dict, player):
'wtsd' 'wtsd'
) )
def vpip_0(stat_dict, player):
""" Voluntarily put $ in the pot (no decimals)."""
stat = 0.0
try:
stat = float(stat_dict[player]['vpip'])/float(stat_dict[player]['n'])
return (stat,
'%2.0f' % (100*stat) + '%',
'v=%2.0f' % (100*stat) + '%',
'vpip=%2.0f' % (100*stat) + '%',
'(%d/%d)' % (stat_dict[player]['vpip'], stat_dict[player]['n']),
'vpip'
)
except: return (stat,
'%2.0f' % (0) + '%',
'w=%2.0f' % (0) + '%',
'wtsd=%2.0f' % (0) + '%',
'(%d/%d)' % (0, 0),
'wtsd'
)
def pfr(stat_dict, player): def pfr(stat_dict, player):
""" Preflop (3rd street) raise.""" """ Preflop (3rd street) raise."""
stat = 0.0 stat = 0.0
@ -119,6 +140,27 @@ def pfr(stat_dict, player):
'pfr' 'pfr'
) )
def pfr_0(stat_dict, player):
""" Preflop (3rd street) raise (no decimals)."""
stat = 0.0
try:
stat = float(stat_dict[player]['pfr'])/float(stat_dict[player]['n'])
return (stat,
'%2.0f' % (100*stat) + '%',
'p=%2.0f' % (100*stat) + '%',
'pfr=%2.0f' % (100*stat) + '%',
'(%d/%d)' % (stat_dict[player]['pfr'], stat_dict[player]['n']),
'pfr'
)
except:
return (stat,
'%2.0f' % (0) + '%',
'p=%2.0f' % (0) + '%',
'pfr=%2.0f' % (0) + '%',
'(%d/%d)' % (0, 0),
'pfr'
)
def wtsd(stat_dict, player): def wtsd(stat_dict, player):
""" Went to SD when saw flop/4th.""" """ Went to SD when saw flop/4th."""
stat = 0.0 stat = 0.0
@ -149,7 +191,7 @@ def wmsd(stat_dict, player):
'%3.1f' % (100*stat) + '%', '%3.1f' % (100*stat) + '%',
'w=%3.1f' % (100*stat) + '%', 'w=%3.1f' % (100*stat) + '%',
'wmsd=%3.1f' % (100*stat) + '%', 'wmsd=%3.1f' % (100*stat) + '%',
'(%f5.0/%d)' % (stat_dict[player]['wmsd'], stat_dict[player]['sd']), '(%5.1f/%d)' % (float(stat_dict[player]['wmsd']), stat_dict[player]['sd']),
'% won money at showdown' '% won money at showdown'
) )
except: except:
@ -415,6 +457,61 @@ def a_freq_4(stat_dict, player):
'Aggression Freq flop/4th' 'Aggression Freq flop/4th'
) )
def a_freq_123(stat_dict, player):
""" Post-Flop aggression frequency."""
stat = 0.0
try:
stat = float( stat_dict[player]['aggr_1'] + stat_dict[player]['aggr_2'] + stat_dict[player]['aggr_3']
) / float( stat_dict[player]['saw_1'] + stat_dict[player]['saw_2'] + stat_dict[player]['saw_3']);
return (stat,
'%3.1f' % (100*stat) + '%',
'afq=%3.1f' % (100*stat) + '%',
'postf_aggfq=%3.1f' % (100*stat) + '%',
'(%d/%d)' % ( stat_dict[player]['aggr_1']
+ stat_dict[player]['aggr_2']
+ stat_dict[player]['aggr_3']
, stat_dict[player]['saw_1']
+ stat_dict[player]['saw_2']
+ stat_dict[player]['saw_3']
),
'Post-Flop Aggression Freq'
)
except:
return (stat,
'%2.0f' % (0) + '%',
'a3=%2.0f' % (0) + '%',
'a_fq_3=%2.0f' % (0) + '%',
'(%d/%d)' % (0, 0),
'Post-Flop Aggression Freq'
)
def a_freq_123_0(stat_dict, player):
""" Post-Flop aggression frequency (no decimals)."""
stat = 0.0
try:
stat = float( stat_dict[player]['aggr_1'] + stat_dict[player]['aggr_2'] + stat_dict[player]['aggr_3']) / float( stat_dict[player]['saw_1'] + stat_dict[player]['saw_2'] + stat_dict[player]['saw_3']);
return (stat,
'%2.0f' % (100*stat) + '%',
'afq=%2.0f' % (100*stat) + '%',
'postf_aggfq=%2.0f' % (100*stat) + '%',
'(%d/%d)' % ( stat_dict[player]['aggr_1']
+ stat_dict[player]['aggr_2']
+ stat_dict[player]['aggr_3']
, stat_dict[player]['saw_1']
+ stat_dict[player]['saw_2']
+ stat_dict[player]['saw_3']
),
'Post-Flop Aggression Freq'
)
except:
return (stat,
'%2.0f' % (0) + '%',
'a3=%2.0f' % (0) + '%',
'a_fq_3=%2.0f' % (0) + '%',
'(%d/%d)' % (0, 0),
'Post-Flop Aggression Freq'
)
def cb_1(stat_dict, player): def cb_1(stat_dict, player):
""" Flop continuation bet.""" """ Flop continuation bet."""
stat = 0.0 stat = 0.0
@ -591,7 +688,9 @@ if __name__== "__main__":
for player in stat_dict.keys(): for player in stat_dict.keys():
print "player = ", player, do_stat(stat_dict, player = player, stat = 'vpip') print "player = ", player, do_stat(stat_dict, player = player, stat = 'vpip')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'vpip_0')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'pfr') print "player = ", player, do_stat(stat_dict, player = player, stat = 'pfr')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'pfr_0')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'wtsd') print "player = ", player, do_stat(stat_dict, player = player, stat = 'wtsd')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'saw_f') print "player = ", player, do_stat(stat_dict, player = player, stat = 'saw_f')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'n') print "player = ", player, do_stat(stat_dict, player = player, stat = 'n')
@ -606,6 +705,8 @@ if __name__== "__main__":
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_2') print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_2')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_3') print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_3')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_4') print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_4')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_123')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_123_0')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_1') print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_1')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_2') print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_2')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_3') print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_3')
@ -614,6 +715,7 @@ if __name__== "__main__":
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_2') print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_2')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_3') print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_3')
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_4') print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_4')
print "\n"
print "\n\nLegal stats:" print "\n\nLegal stats:"
for attr in dir(): for attr in dir():
@ -621,8 +723,8 @@ if __name__== "__main__":
if attr in ("Configuration", "Database", "GInitiallyUnowned", "gtk", "pygtk", if attr in ("Configuration", "Database", "GInitiallyUnowned", "gtk", "pygtk",
"player", "c", "db_connection", "do_stat", "do_tip", "stat_dict", "player", "c", "db_connection", "do_stat", "do_tip", "stat_dict",
"h"): continue "h"): continue
print attr, eval("%s.__doc__" % (attr)) print "%-14s %s" % (attr, eval("%s.__doc__" % (attr)))
# print " <pu_stat pu_stat_name = \"%s\"> </pu_stat>" % (attr) # print " <pu_stat pu_stat_name = \"%s\"> </pu_stat>" % (attr)
db_connection.close db_connection.close_connection

670
pyfpdb/fpdb.py Executable file → Normal file
View File

@ -22,13 +22,13 @@ from optparse import OptionParser
parser = OptionParser() 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 .") help="If passed error output will go to the console rather than .")
(options, sys.argv) = parser.parse_args() (options, sys.argv) = parser.parse_args()
if not options.errorsToConsole: if not options.errorsToConsole:
print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_." print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_."
errorFile = open('fpdb-error-log.txt', 'w', 0) errorFile = open('fpdb-error-log.txt', 'w', 0)
sys.stderr = errorFile sys.stderr = errorFile
import pygtk import pygtk
pygtk.require('2.0') pygtk.require('2.0')
@ -44,406 +44,406 @@ import FpdbSQLQueries
import Configuration import Configuration
class fpdb: class fpdb:
def tab_clicked(self, widget, tab_name): def tab_clicked(self, widget, tab_name):
"""called when a tab button is clicked to activate that tab""" """called when a tab button is clicked to activate that tab"""
#print "start of tab_clicked" #print "start of tab_clicked"
self.display_tab(tab_name) self.display_tab(tab_name)
#end def tab_clicked #end def tab_clicked
def add_and_display_tab(self, new_tab, new_tab_name): def add_and_display_tab(self, new_tab, new_tab_name):
"""just calls the component methods""" """just calls the component methods"""
self.add_tab(new_tab, new_tab_name) self.add_tab(new_tab, new_tab_name)
self.display_tab(new_tab_name) self.display_tab(new_tab_name)
#end def add_and_display_tab #end def add_and_display_tab
def add_tab(self, new_tab, new_tab_name): def add_tab(self, new_tab, new_tab_name):
"""adds a tab, namely creates the button and displays it and appends all the relevant arrays""" """adds a tab, namely creates the button and displays it and appends all the relevant arrays"""
#print "start of add_tab" #print "start of add_tab"
for i in self.tab_names: #todo: check this is valid for i in self.tab_names: #todo: check this is valid
if i==new_tab_name: if i==new_tab_name:
raise fpdb_simple.FpdbError("duplicate tab_name not permitted") raise fpdb_simple.FpdbError("duplicate tab_name not permitted")
self.tabs.append(new_tab) self.tabs.append(new_tab)
self.tab_names.append(new_tab_name) self.tab_names.append(new_tab_name)
new_tab_sel_button=gtk.ToggleButton(new_tab_name) new_tab_sel_button=gtk.ToggleButton(new_tab_name)
new_tab_sel_button.connect("clicked", self.tab_clicked, new_tab_name) new_tab_sel_button.connect("clicked", self.tab_clicked, new_tab_name)
self.tab_box.add(new_tab_sel_button) self.tab_box.add(new_tab_sel_button)
new_tab_sel_button.show() new_tab_sel_button.show()
self.tab_buttons.append(new_tab_sel_button) self.tab_buttons.append(new_tab_sel_button)
#end def add_tab #end def add_tab
def display_tab(self, new_tab_name): def display_tab(self, new_tab_name):
"""displays the indicated tab""" """displays the indicated tab"""
#print "start of display_tab, len(self.tab_names):",len(self.tab_names) #print "start of display_tab, len(self.tab_names):",len(self.tab_names)
tab_no=-1 tab_no=-1
#if len(self.tab_names)>1: #if len(self.tab_names)>1:
for i in range(len(self.tab_names)): for i in range(len(self.tab_names)):
#print "display_tab, new_tab_name:",new_tab_name," self.tab_names[i]:", self.tab_names[i] #print "display_tab, new_tab_name:",new_tab_name," self.tab_names[i]:", self.tab_names[i]
if (new_tab_name==self.tab_names[i]): if (new_tab_name==self.tab_names[i]):
tab_no=i tab_no=i
#self.tab_buttons[i].set_active(False) #self.tab_buttons[i].set_active(False)
#else: #else:
# tab_no=0 # tab_no=0
#current_tab_no=-1 #current_tab_no=-1
for i in range(len(self.tab_names)): for i in range(len(self.tab_names)):
if self.current_tab==self.tabs[i]: if self.current_tab==self.tabs[i]:
#self.tab_buttons[i].set_active(False) #self.tab_buttons[i].set_active(False)
pass pass
if tab_no==-1: if tab_no==-1:
raise fpdb_simple.FpdbError("invalid tab_no") raise fpdb_simple.FpdbError("invalid tab_no")
else: else:
self.main_vbox.remove(self.current_tab) self.main_vbox.remove(self.current_tab)
#self.current_tab.destroy() #self.current_tab.destroy()
self.current_tab=self.tabs[tab_no] self.current_tab=self.tabs[tab_no]
self.main_vbox.add(self.current_tab) self.main_vbox.add(self.current_tab)
self.tab_buttons[tab_no].set_active(True) self.tab_buttons[tab_no].set_active(True)
self.current_tab.show() self.current_tab.show()
#end def display_tab #end def display_tab
def delete_event(self, widget, event, data=None): def delete_event(self, widget, event, data=None):
return False return False
#end def delete_event #end def delete_event
def destroy(self, widget, data=None): def destroy(self, widget, data=None):
self.quit(widget, data) self.quit(widget, data)
#end def destroy #end def destroy
def dia_about(self, widget, data): def dia_about(self, widget, data):
print "todo: implement dia_about" print "todo: implement dia_about"
#end def dia_about #end def dia_about
def dia_create_del_database(self, widget, data): def dia_create_del_database(self, widget, data):
print "todo: implement dia_create_del_database" print "todo: implement dia_create_del_database"
obtain_global_lock() obtain_global_lock()
#end def dia_create_del_database #end def dia_create_del_database
def dia_create_del_user(self, widget, data): def dia_create_del_user(self, widget, data):
print "todo: implement dia_create_del_user" print "todo: implement dia_create_del_user"
obtain_global_lock() obtain_global_lock()
#end def dia_create_del_user #end def dia_create_del_user
def dia_database_stats(self, widget, data): def dia_database_stats(self, widget, data):
print "todo: implement dia_database_stats" print "todo: implement dia_database_stats"
#string=fpdb_db.getDbStats(db, cursor) #string=fpdb_db.getDbStats(db, cursor)
#end def dia_database_stats #end def dia_database_stats
def dia_delete_db_parts(self, widget, data): def dia_delete_db_parts(self, widget, data):
print "todo: implement dia_delete_db_parts" print "todo: implement dia_delete_db_parts"
obtain_global_lock() obtain_global_lock()
#end def dia_delete_db_parts #end def dia_delete_db_parts
def dia_edit_profile(self, widget=None, data=None, create_default=False, path=None): def dia_edit_profile(self, widget=None, data=None, create_default=False, path=None):
print "todo: implement dia_edit_profile" print "todo: implement dia_edit_profile"
obtain_global_lock() obtain_global_lock()
#end def dia_edit_profile #end def dia_edit_profile
def dia_export_db(self, widget, data): def dia_export_db(self, widget, data):
print "todo: implement dia_export_db" print "todo: implement dia_export_db"
obtain_global_lock() obtain_global_lock()
#end def dia_export_db #end def dia_export_db
def dia_get_db_root_credentials(self): def dia_get_db_root_credentials(self):
"""obtains db root credentials from user""" """obtains db root credentials from user"""
print "todo: implement dia_get_db_root_credentials" print "todo: implement dia_get_db_root_credentials"
# user, pw=None, None # user, pw=None, None
# #
# dialog=gtk.Dialog(title="DB Credentials needed", parent=None, flags=0, # dialog=gtk.Dialog(title="DB Credentials needed", parent=None, flags=0,
# buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,"Connect and recreate",gtk.RESPONSE_OK)) # buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,"Connect and recreate",gtk.RESPONSE_OK))
# #
# label_warning1=gtk.Label("Please enter credentials for a database user for "+self.host+" that has permissions to create a database.") # label_warning1=gtk.Label("Please enter credentials for a database user for "+self.host+" that has permissions to create a database.")
# #
# #
# label_user=gtk.Label("Username") # label_user=gtk.Label("Username")
# dialog.vbox.add(label_user) # dialog.vbox.add(label_user)
# label_user.show() # label_user.show()
# #
# response=dialog.run() # response=dialog.run()
# dialog.destroy() # dialog.destroy()
# return (user, pw, response) # return (user, pw, response)
#end def dia_get_db_root_credentials #end def dia_get_db_root_credentials
def dia_import_db(self, widget, data): def dia_import_db(self, widget, data):
print "todo: implement dia_import_db" print "todo: implement dia_import_db"
obtain_global_lock() obtain_global_lock()
#end def dia_import_db #end def dia_import_db
def dia_licensing(self, widget, data): def dia_licensing(self, widget, data):
print "todo: implement dia_licensing" print "todo: implement dia_licensing"
#end def dia_licensing #end def dia_licensing
def dia_load_profile(self, widget, data): def dia_load_profile(self, widget, data):
"""Dialogue to select a file to load a profile from""" """Dialogue to select a file to load a profile from"""
self.obtain_global_lock() self.obtain_global_lock()
chooser = gtk.FileChooserDialog(title="Please select a profile file to load", chooser = gtk.FileChooserDialog(title="Please select a profile file to load",
action=gtk.FILE_CHOOSER_ACTION_OPEN, action=gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
chooser.set_filename(self.profile) chooser.set_filename(self.profile)
response = chooser.run() response = chooser.run()
chooser.destroy() chooser.destroy()
if response == gtk.RESPONSE_OK: if response == gtk.RESPONSE_OK:
self.load_profile(chooser.get_filename()) self.load_profile(chooser.get_filename())
elif response == gtk.RESPONSE_CANCEL: elif response == gtk.RESPONSE_CANCEL:
print 'User cancelled loading profile' print 'User cancelled loading profile'
#end def dia_load_profile #end def dia_load_profile
def dia_recreate_tables(self, widget, data): def dia_recreate_tables(self, widget, data):
"""Dialogue that asks user to confirm that he wants to delete and recreate the tables""" """Dialogue that asks user to confirm that he wants to delete and recreate the tables"""
self.obtain_global_lock() self.obtain_global_lock()
dia_confirm=gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, dia_confirm=gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables") buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables")
diastring=("Please confirm that you want to (re-)create the tables. If there already are tables in the database "+self.db.database+" on "+self.db.host+" they will be deleted.") diastring=("Please confirm that you want to (re-)create the tables. If there already are tables in the database "+self.db.database+" on "+self.db.host+" they will be deleted.")
dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted
response=dia_confirm.run() response=dia_confirm.run()
dia_confirm.destroy() dia_confirm.destroy()
if response == gtk.RESPONSE_YES: if response == gtk.RESPONSE_YES:
self.db.recreate_tables() self.db.recreate_tables()
elif response == gtk.RESPONSE_NO: elif response == gtk.RESPONSE_NO:
print 'User cancelled recreating tables' print 'User cancelled recreating tables'
#end def dia_recreate_tables #end def dia_recreate_tables
def dia_regression_test(self, widget, data): def dia_regression_test(self, widget, data):
print "todo: implement dia_regression_test" print "todo: implement dia_regression_test"
self.obtain_global_lock() self.obtain_global_lock()
#end def dia_regression_test #end def dia_regression_test
def dia_save_profile(self, widget, data): def dia_save_profile(self, widget, data):
print "todo: implement dia_save_profile" print "todo: implement dia_save_profile"
#end def dia_save_profile #end def dia_save_profile
def diaSetupWizard(self, path): def diaSetupWizard(self, path):
print "todo: implement setup wizard" print "todo: implement setup wizard"
print "setup wizard not implemented - please create the default configuration file:", path print "setup wizard not implemented - please create the default configuration file:", path
diaSetupWizard = gtk.Dialog(title="Fatal Error - Config File Missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK)) diaSetupWizard = gtk.Dialog(title="Fatal Error - Config File Missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
label = gtk.Label("Please copy the config file from the docs folder to:") label = gtk.Label("Please copy the config file from the docs folder to:")
diaSetupWizard.vbox.add(label) diaSetupWizard.vbox.add(label)
label.show() label.show()
label = gtk.Label(path) label = gtk.Label(path)
diaSetupWizard.vbox.add(label) diaSetupWizard.vbox.add(label)
label.show() label.show()
label = gtk.Label("and edit it according to the install documentation at http://fpdb.sourceforge.net") label = gtk.Label("and edit it according to the install documentation at http://fpdb.sourceforge.net")
diaSetupWizard.vbox.add(label) diaSetupWizard.vbox.add(label)
label.show() label.show()
response = diaSetupWizard.run() response = diaSetupWizard.run()
sys.exit(1) sys.exit(1)
#end def diaSetupWizard #end def diaSetupWizard
def get_menu(self, window): def get_menu(self, window):
"""returns the menu for this program""" """returns the menu for this program"""
accel_group = gtk.AccelGroup() accel_group = gtk.AccelGroup()
self.item_factory = gtk.ItemFactory(gtk.MenuBar, "<main>", accel_group) self.item_factory = gtk.ItemFactory(gtk.MenuBar, "<main>", accel_group)
self.item_factory.create_items(self.menu_items) self.item_factory.create_items(self.menu_items)
window.add_accel_group(accel_group) window.add_accel_group(accel_group)
return self.item_factory.get_widget("<main>") return self.item_factory.get_widget("<main>")
#end def get_menu #end def get_menu
def load_profile(self): def load_profile(self):
"""Loads profile from the provided path name.""" """Loads profile from the provided path name."""
self.settings = {} self.settings = {}
if (os.sep=="/"): if (os.sep=="/"):
self.settings['os']="linuxmac" self.settings['os']="linuxmac"
else: else:
self.settings['os']="windows" self.settings['os']="windows"
self.settings.update(self.config.get_db_parameters()) self.settings.update(self.config.get_db_parameters())
self.settings.update(self.config.get_tv_parameters()) self.settings.update(self.config.get_tv_parameters())
self.settings.update(self.config.get_import_parameters()) self.settings.update(self.config.get_import_parameters())
self.settings.update(self.config.get_default_paths()) self.settings.update(self.config.get_default_paths())
if self.db!=None: if self.db!=None:
self.db.disconnect() self.db.disconnect()
self.db = fpdb_db.fpdb_db() self.db = fpdb_db.fpdb_db()
#print "end of fpdb.load_profile, databaseName:",self.settings['db-databaseName'] #print "end of fpdb.load_profile, databaseName:",self.settings['db-databaseName']
self.db.connect(self.settings['db-backend'], self.settings['db-host'], self.settings['db-databaseName'], self.settings['db-user'], self.settings['db-password']) self.db.connect(self.settings['db-backend'], self.settings['db-host'], self.settings['db-databaseName'], self.settings['db-user'], self.settings['db-password'])
if self.db.wrongDbVersion: if self.db.wrongDbVersion:
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK)) diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
label = gtk.Label("An invalid DB version or missing tables have been detected.") label = gtk.Label("An invalid DB version or missing tables have been detected.")
diaDbVersionWarning.vbox.add(label) diaDbVersionWarning.vbox.add(label)
label.show() label.show()
label = gtk.Label("This error is not necessarily fatal but it is strongly recommended that you recreate the tables by using the Database menu.") label = gtk.Label("This error is not necessarily fatal but it is strongly recommended that you recreate the tables by using the Database menu.")
diaDbVersionWarning.vbox.add(label) diaDbVersionWarning.vbox.add(label)
label.show() label.show()
label = gtk.Label("Not doing this will likely lead to misbehaviour including fpdb crashes, corrupt data etc.") label = gtk.Label("Not doing this will likely lead to misbehaviour including fpdb crashes, corrupt data etc.")
diaDbVersionWarning.vbox.add(label) diaDbVersionWarning.vbox.add(label)
label.show() label.show()
response = diaDbVersionWarning.run() response = diaDbVersionWarning.run()
diaDbVersionWarning.destroy() diaDbVersionWarning.destroy()
# Database connected to successfully, load queries to pass on to other classes # Database connected to successfully, load queries to pass on to other classes
self.querydict = FpdbSQLQueries.FpdbSQLQueries(self.db.get_backend_name()) self.querydict = FpdbSQLQueries.FpdbSQLQueries(self.db.get_backend_name())
#end def load_profile #end def load_profile
def not_implemented(self): def not_implemented(self):
print "todo: called unimplemented menu entry (users: pls ignore this)"#remove this once more entries are implemented print "todo: called unimplemented menu entry (users: pls ignore this)"#remove this once more entries are implemented
#end def not_implemented #end def not_implemented
def obtain_global_lock(self): def obtain_global_lock(self):
print "todo: implement obtain_global_lock (users: pls ignore this)" print "todo: implement obtain_global_lock (users: pls ignore this)"
#end def obtain_global_lock #end def obtain_global_lock
def quit(self, widget, data): def quit(self, widget, data):
print "Quitting normally" print "Quitting normally"
#check if current settings differ from profile, if so offer to save or abort #check if current settings differ from profile, if so offer to save or abort
self.db.disconnect() self.db.disconnect()
gtk.main_quit() gtk.main_quit()
#end def quit_cliecked #end def quit_cliecked
def release_global_lock(self): def release_global_lock(self):
print "todo: implement release_global_lock" print "todo: implement release_global_lock"
#end def release_global_lock #end def release_global_lock
def tab_abbreviations(self, widget, data): def tab_abbreviations(self, widget, data):
print "todo: implement tab_abbreviations" print "todo: implement tab_abbreviations"
#end def tab_abbreviations #end def tab_abbreviations
def tab_auto_import(self, widget, data): def tab_auto_import(self, widget, data):
"""opens the auto import tab""" """opens the auto import tab"""
new_aimp_thread=GuiAutoImport.GuiAutoImport(self.settings, self.config) new_aimp_thread=GuiAutoImport.GuiAutoImport(self.settings, self.config)
self.threads.append(new_aimp_thread) self.threads.append(new_aimp_thread)
aimp_tab=new_aimp_thread.get_vbox() aimp_tab=new_aimp_thread.get_vbox()
self.add_and_display_tab(aimp_tab, "Auto Import") self.add_and_display_tab(aimp_tab, "Auto Import")
#end def tab_auto_import #end def tab_auto_import
def tab_bulk_import(self, widget, data): def tab_bulk_import(self, widget, data):
"""opens a tab for bulk importing""" """opens a tab for bulk importing"""
#print "start of tab_bulk_import" #print "start of tab_bulk_import"
new_import_thread=GuiBulkImport.GuiBulkImport(self.db, self.settings, self.config) new_import_thread=GuiBulkImport.GuiBulkImport(self.db, self.settings, self.config)
self.threads.append(new_import_thread) self.threads.append(new_import_thread)
bulk_tab=new_import_thread.get_vbox() bulk_tab=new_import_thread.get_vbox()
self.add_and_display_tab(bulk_tab, "Bulk Import") self.add_and_display_tab(bulk_tab, "Bulk Import")
#end def tab_bulk_import #end def tab_bulk_import
def tab_main_help(self, widget, data): def tab_main_help(self, widget, data):
"""Displays a tab with the main fpdb help screen""" """Displays a tab with the main fpdb help screen"""
#print "start of tab_main_help" #print "start of tab_main_help"
mh_tab=gtk.Label("""Welcome to Fpdb! mh_tab=gtk.Label("""Welcome to Fpdb!
For documentation please visit our website at http://fpdb.sourceforge.net/ or check the docs directory in the fpdb folder. For documentation please visit our website at http://fpdb.sourceforge.net/ or check the docs directory in the fpdb folder.
Please note that default.conf is no longer needed nor used, all configuration now happens in HUD_config.xml Please note that default.conf is no longer needed nor used, all configuration now happens in HUD_config.xml
This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
self.add_and_display_tab(mh_tab, "Help") self.add_and_display_tab(mh_tab, "Help")
#end def tab_main_help #end def tab_main_help
def tab_table_viewer(self, widget, data): def tab_table_viewer(self, widget, data):
"""opens a table viewer tab""" """opens a table viewer tab"""
#print "start of tab_table_viewer" #print "start of tab_table_viewer"
new_tv_thread=GuiTableViewer.GuiTableViewer(self.db, self.settings) new_tv_thread=GuiTableViewer.GuiTableViewer(self.db, self.settings)
self.threads.append(new_tv_thread) self.threads.append(new_tv_thread)
tv_tab=new_tv_thread.get_vbox() tv_tab=new_tv_thread.get_vbox()
self.add_and_display_tab(tv_tab, "Table Viewer") self.add_and_display_tab(tv_tab, "Table Viewer")
#end def tab_table_viewer #end def tab_table_viewer
def tabGraphViewer(self, widget, data): def tabGraphViewer(self, widget, data):
"""opens a graph viewer tab""" """opens a graph viewer tab"""
#print "start of tabGraphViewer" #print "start of tabGraphViewer"
new_gv_thread=GuiGraphViewer.GuiGraphViewer(self.db, self.settings, self.querydict, self.config) new_gv_thread=GuiGraphViewer.GuiGraphViewer(self.db, self.settings, self.querydict, self.config)
self.threads.append(new_gv_thread) self.threads.append(new_gv_thread)
gv_tab=new_gv_thread.get_vbox() gv_tab=new_gv_thread.get_vbox()
self.add_and_display_tab(gv_tab, "Graphs") self.add_and_display_tab(gv_tab, "Graphs")
#end def tabGraphViewer #end def tabGraphViewer
def __init__(self): def __init__(self):
self.threads=[] self.threads=[]
self.db=None self.db=None
self.config = Configuration.Config() self.config = Configuration.Config()
self.load_profile() self.load_profile()
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.connect("delete_event", self.delete_event) self.window.connect("delete_event", self.delete_event)
self.window.connect("destroy", self.destroy) self.window.connect("destroy", self.destroy)
self.window.set_title("Free Poker DB - version: alpha9+, p143 or higher") self.window.set_title("Free Poker DB - version: alpha9+, p143 or higher")
self.window.set_border_width(1) self.window.set_border_width(1)
self.window.set_size_request(1020,400) self.window.set_size_request(1020,400)
self.window.set_resizable(True) self.window.set_resizable(True)
self.menu_items = ( self.menu_items = (
( "/_Main", None, None, 0, "<Branch>" ), ( "/_Main", None, None, 0, "<Branch>" ),
( "/Main/_Load Profile (broken)", "<control>L", self.dia_load_profile, 0, None ), ( "/Main/_Load Profile (broken)", "<control>L", self.dia_load_profile, 0, None ),
( "/Main/_Edit Profile (todo)", "<control>E", self.dia_edit_profile, 0, None ), ( "/Main/_Edit Profile (todo)", "<control>E", self.dia_edit_profile, 0, None ),
( "/Main/_Save Profile (todo)", None, self.dia_save_profile, 0, None ), ( "/Main/_Save Profile (todo)", None, self.dia_save_profile, 0, None ),
("/Main/sep1", None, None, 0, "<Separator>" ), ("/Main/sep1", None, None, 0, "<Separator>" ),
("/Main/_Quit", "<control>Q", self.quit, 0, None ), ("/Main/_Quit", "<control>Q", self.quit, 0, None ),
("/_Import", None, None, 0, "<Branch>" ), ("/_Import", None, None, 0, "<Branch>" ),
("/Import/_Bulk Import", "<control>B", self.tab_bulk_import, 0, None ), ("/Import/_Bulk Import", "<control>B", self.tab_bulk_import, 0, None ),
("/Import/_Auto Import and HUD", "<control>A", self.tab_auto_import, 0, None ), ("/Import/_Auto Import and HUD", "<control>A", self.tab_auto_import, 0, None ),
("/Import/Auto _Rating (todo)", "<control>R", self.not_implemented, 0, None ), ("/Import/Auto _Rating (todo)", "<control>R", self.not_implemented, 0, None ),
("/_Viewers", None, None, 0, "<Branch>" ), ("/_Viewers", None, None, 0, "<Branch>" ),
("/_Viewers/_Auto Import and HUD", "<control>A", self.tab_auto_import, 0, None ), ("/_Viewers/_Auto Import and HUD", "<control>A", self.tab_auto_import, 0, None ),
("/Viewers/_Graphs", "<control>G", self.tabGraphViewer, 0, None ), ("/Viewers/_Graphs", "<control>G", self.tabGraphViewer, 0, None ),
("/Viewers/Hand _Replayer (todo)", None, self.not_implemented, 0, None ), ("/Viewers/Hand _Replayer (todo)", None, self.not_implemented, 0, None ),
("/Viewers/Player _Details (todo)", None, self.not_implemented, 0, None ), ("/Viewers/Player _Details (todo)", None, self.not_implemented, 0, None ),
("/Viewers/_Player Stats (tabulated view) (todo)", None, self.not_implemented, 0, None ), ("/Viewers/_Player Stats (tabulated view) (todo)", None, self.not_implemented, 0, None ),
("/Viewers/Starting _Hands (todo)", None, self.not_implemented, 0, None ), ("/Viewers/Starting _Hands (todo)", None, self.not_implemented, 0, None ),
("/Viewers/_Session Replayer (todo)", None, self.not_implemented, 0, None ), ("/Viewers/_Session Replayer (todo)", None, self.not_implemented, 0, None ),
("/Viewers/Poker_table Viewer (mostly obselete)", "<control>T", self.tab_table_viewer, 0, None ), ("/Viewers/Poker_table Viewer (mostly obselete)", "<control>T", self.tab_table_viewer, 0, None ),
#( "/Viewers/Tourney Replayer #( "/Viewers/Tourney Replayer
( "/_Database", None, None, 0, "<Branch>" ), ( "/_Database", None, None, 0, "<Branch>" ),
( "/Database/Create or Delete _Database (todo)", None, self.dia_create_del_database, 0, None ), ( "/Database/Create or Delete _Database (todo)", None, self.dia_create_del_database, 0, None ),
( "/Database/Create or Delete _User (todo)", None, self.dia_create_del_user, 0, None ), ( "/Database/Create or Delete _User (todo)", None, self.dia_create_del_user, 0, None ),
( "/Database/Create or Recreate _Tables", None, self.dia_recreate_tables, 0, None ), ( "/Database/Create or Recreate _Tables", None, self.dia_recreate_tables, 0, None ),
( "/Database/_Statistics (todo)", None, self.dia_database_stats, 0, None ), ( "/Database/_Statistics (todo)", None, self.dia_database_stats, 0, None ),
( "/D_ebugging", None, None, 0, "<Branch>" ), ( "/D_ebugging", None, None, 0, "<Branch>" ),
( "/Debugging/_Delete Parts of Database (todo)", None, self.dia_delete_db_parts, 0, None ), ( "/Debugging/_Delete Parts of Database (todo)", None, self.dia_delete_db_parts, 0, None ),
( "/Debugging/_Export DB (todo)", None, self.dia_export_db, 0, None ), ( "/Debugging/_Export DB (todo)", None, self.dia_export_db, 0, None ),
( "/Debugging/_Import DB (todo)", None, self.dia_import_db, 0, None ), ( "/Debugging/_Import DB (todo)", None, self.dia_import_db, 0, None ),
( "/Debugging/_Regression test (todo)", None, self.dia_regression_test, 0, None ), ( "/Debugging/_Regression test (todo)", None, self.dia_regression_test, 0, None ),
( "/_Help", None, None, 0, "<LastBranch>" ), ( "/_Help", None, None, 0, "<LastBranch>" ),
( "/Help/_Main Help", "<control>H", self.tab_main_help, 0, None ), ( "/Help/_Main Help", "<control>H", self.tab_main_help, 0, None ),
( "/Help/_Abbrevations (todo)", None, self.tab_abbreviations, 0, None ), ( "/Help/_Abbrevations (todo)", None, self.tab_abbreviations, 0, None ),
( "/Help/sep1", None, None, 0, "<Separator>" ), ( "/Help/sep1", None, None, 0, "<Separator>" ),
( "/Help/A_bout (todo)", None, self.dia_about, 0, None ), ( "/Help/A_bout (todo)", None, self.dia_about, 0, None ),
( "/Help/_License and Copying (todo)", None, self.dia_licensing, 0, None ) ( "/Help/_License and Copying (todo)", None, self.dia_licensing, 0, None )
) )
self.main_vbox = gtk.VBox(False, 1) self.main_vbox = gtk.VBox(False, 1)
self.main_vbox.set_border_width(1) self.main_vbox.set_border_width(1)
self.window.add(self.main_vbox) self.window.add(self.main_vbox)
self.main_vbox.show() self.main_vbox.show()
menubar = self.get_menu(self.window) menubar = self.get_menu(self.window)
self.main_vbox.pack_start(menubar, False, True, 0) self.main_vbox.pack_start(menubar, False, True, 0)
menubar.show() menubar.show()
#done menubar #done menubar
self.tabs=[] self.tabs=[]
self.tab_names=[] self.tab_names=[]
self.tab_buttons=[] self.tab_buttons=[]
self.tab_box = gtk.HBox(False,1) self.tab_box = gtk.HBox(False,1)
self.main_vbox.pack_start(self.tab_box, False, True, 0) self.main_vbox.pack_start(self.tab_box, False, True, 0)
self.tab_box.show() self.tab_box.show()
#done tab bar #done tab bar
self.current_tab = gtk.VBox(False,1) self.current_tab = gtk.VBox(False,1)
self.current_tab.set_border_width(1) self.current_tab.set_border_width(1)
self.main_vbox.add(self.current_tab) self.main_vbox.add(self.current_tab)
self.current_tab.show() self.current_tab.show()
self.tab_main_help(None, None) self.tab_main_help(None, None)
self.status_bar = gtk.Label("Status: Connected to "+self.db.get_backend_name()+" database named "+self.db.database+" on host "+self.db.host) self.status_bar = gtk.Label("Status: Connected to "+self.db.get_backend_name()+" database named "+self.db.database+" on host "+self.db.host)
self.main_vbox.pack_end(self.status_bar, False, True, 0) self.main_vbox.pack_end(self.status_bar, False, True, 0)
self.status_bar.show() self.status_bar.show()
self.window.show() self.window.show()
#end def __init__ #end def __init__
def main(self): def main(self):
gtk.main() gtk.main()
return 0 return 0
#end def main #end def main
if __name__ == "__main__": if __name__ == "__main__":
me = fpdb() me = fpdb()
me.main() me.main()

0
pyfpdb/fpdb_db.py Executable file → Normal file
View File

456
pyfpdb/fpdb_import.py Executable file → Normal file
View File

@ -20,16 +20,16 @@
import sys import sys
try: try:
import MySQLdb import MySQLdb
mysqlLibFound=True mysqlLibFound=True
except: except:
pass pass
try: try:
import psycopg2 import psycopg2
pgsqlLibFound=True pgsqlLibFound=True
except: except:
pass pass
import math import math
import os import os
@ -41,258 +41,270 @@ from time import time
class Importer: class Importer:
def __init__(self, caller, settings): def __init__(self, caller, settings, config):
"""Constructor""" """Constructor"""
self.settings=settings self.settings=settings
self.caller=caller self.caller=caller
self.db = None self.config = config
self.cursor = None self.db = None
self.filelist = {} self.cursor = None
self.dirlist = {} self.filelist = {}
self.monitor = False self.dirlist = {}
self.updated = {} #Time last import was run {file:mtime} self.monitor = False
self.callHud = False self.updated = {} #Time last import was run {file:mtime}
self.lines = None self.lines = None
self.faobs = None #File as one big string self.faobs = None #File as one big string
self.pos_in_file = {} # dict to remember how far we have read in the file self.pos_in_file = {} # dict to remember how far we have read in the file
#Set defaults #Set defaults
if not self.settings.has_key('imp-callFpdbHud'): self.callHud = self.config.get_import_parameters().get("callFpdbHud")
self.settings['imp-callFpdbHud'] = False if not self.settings.has_key('minPrint'):
if not self.settings.has_key('minPrint'): self.settings['minPrint'] = 30
self.settings['minPrint'] = 30 self.dbConnect()
self.dbConnect()
def dbConnect(self): def dbConnect(self):
#connect to DB #connect to DB
if self.settings['db-backend'] == 2: if self.settings['db-backend'] == 2:
if not mysqlLibFound: if not mysqlLibFound:
raise fpdb_simple.FpdbError("interface library MySQLdb not found but MySQL selected as backend - please install the library or change the config file") raise fpdb_simple.FpdbError("interface library MySQLdb not found but MySQL selected as backend - please install the library or change the config file")
self.db = MySQLdb.connect(self.settings['db-host'], self.settings['db-user'], self.db = MySQLdb.connect(self.settings['db-host'], self.settings['db-user'],
self.settings['db-password'], self.settings['db-databaseName']) self.settings['db-password'], self.settings['db-databaseName'])
elif self.settings['db-backend'] == 3: elif self.settings['db-backend'] == 3:
if not pgsqlLibFound: if not pgsqlLibFound:
raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file") raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
print self.settings print self.settings
self.db = psycopg2.connect(host = self.settings['db-host'], self.db = psycopg2.connect(host = self.settings['db-host'],
user = self.settings['db-user'], user = self.settings['db-user'],
password = self.settings['db-password'], password = self.settings['db-password'],
database = self.settings['db-databaseName']) database = self.settings['db-databaseName'])
elif self.settings['db-backend'] == 4: elif self.settings['db-backend'] == 4:
pass pass
else: else:
pass pass
self.cursor = self.db.cursor() self.cursor = self.db.cursor()
#Set functions #Set functions
def setCallHud(self, value): def setCallHud(self, value):
self.callHud = value self.callHud = value
def setMinPrint(self, value): def setMinPrint(self, value):
self.settings['minPrint'] = int(value) self.settings['minPrint'] = int(value)
def setHandCount(self, value): def setHandCount(self, value):
self.settings['handCount'] = int(value) self.settings['handCount'] = int(value)
def setQuiet(self, value): def setQuiet(self, value):
self.settings['quiet'] = value self.settings['quiet'] = value
def setFailOnError(self, value): def setFailOnError(self, value):
self.settings['failOnError'] = value self.settings['failOnError'] = value
# def setWatchTime(self): # def setWatchTime(self):
# self.updated = time() # self.updated = time()
def clearFileList(self): def clearFileList(self):
self.filelist = {} self.filelist = {}
#Add an individual file to filelist #Add an individual file to filelist
def addImportFile(self, filename, site = "default", filter = "passthrough"): def addImportFile(self, filename, site = "default", filter = "passthrough"):
#TODO: test it is a valid file #TODO: test it is a valid file
self.filelist[filename] = [site] + [filter] self.filelist[filename] = [site] + [filter]
#Add a directory of files to filelist #Add a directory of files to filelist
#Only one import directory per site supported. #Only one import directory per site supported.
#dirlist is a hash of lists: #dirlist is a hash of lists:
#dirlist{ 'PokerStars' => ["/path/to/import/", "filtername"] } #dirlist{ 'PokerStars' => ["/path/to/import/", "filtername"] }
def addImportDirectory(self,dir,monitor = False, site = "default", filter = "passthrough"): def addImportDirectory(self, dir, monitor = False, site = "default", filter = "passthrough"):
if os.path.isdir(dir): if dir != "/dev/null" and dir.lower() != "none":
if monitor == True: if os.path.isdir(dir):
self.monitor = True if monitor == True:
self.dirlist[site] = [dir] + [filter] self.monitor = True
self.dirlist[site] = [dir] + [filter]
for file in os.listdir(dir): for file in os.listdir(dir):
self.addImportFile(os.path.join(dir, file), site, filter) self.addImportFile(os.path.join(dir, file), site, filter)
else: else:
print "Warning: Attempted to add: '" + str(dir) + "' as an import directory" print "Warning: Attempted to add: '" + str(dir) + "' as an import directory\n"
#Run full import on filelist #Run full import on filelist
def runImport(self): def runImport(self):
for file in self.filelist: for file in self.filelist:
self.import_file_dict(file) self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
#Run import on updated files, then store latest update time. #Run import on updated files, then store latest update time.
def runUpdated(self): def runUpdated(self):
#Check for new files in directory #Check for new files in directory
#todo: make efficient - always checks for new file, should be able to use mtime of directory #todo: make efficient - always checks for new file, should be able to use mtime of directory
# ^^ May not work on windows # ^^ May not work on windows
for site in self.dirlist: for site in self.dirlist:
self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1]) self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1])
for file in self.filelist: for file in self.filelist:
stat_info = os.stat(file) stat_info = os.stat(file)
try: try:
lastupdate = self.updated[file] lastupdate = self.updated[file]
if stat_info.st_mtime > lastupdate: if stat_info.st_mtime > lastupdate:
self.import_file_dict(file) self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
self.updated[file] = time() self.updated[file] = time()
except: except:
self.updated[file] = time() self.updated[file] = time()
# This codepath only runs first time the file is found, if modified in the last # This codepath only runs first time the file is found, if modified in the last
# minute run an immediate import. # minute run an immediate import.
if (time() - stat_info.st_mtime) < 60: if (time() - stat_info.st_mtime) < 60:
self.import_file_dict(file) self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
# This is now an internal function that should not be called directly. # This is now an internal function that should not be called directly.
def import_file_dict(self, file): def import_file_dict(self, file, site, filter):
starttime = time() if(filter == "passthrough"):
last_read_hand=0 self.import_fpdb_file(file, site)
loc = 0 else:
if (file=="stdin"): #Load filter, and run filtered file though main importer
inputFile=sys.stdin self.import_fpdb_file(file, site)
else:
inputFile=open(file, "rU")
try: loc = self.pos_in_file[file]
except: pass
# Read input file into class and close file
inputFile.seek(loc)
self.lines=fpdb_simple.removeTrailingEOL(inputFile.readlines())
self.pos_in_file[file] = inputFile.tell()
inputFile.close()
firstline = self.lines[0] def import_fpdb_file(self, file, site):
starttime = time()
last_read_hand=0
loc = 0
if (file=="stdin"):
inputFile=sys.stdin
else:
inputFile=open(file, "rU")
try: loc = self.pos_in_file[file]
except: pass
if firstline.find("Tournament Summary")!=-1: # Read input file into class and close file
print "TODO: implement importing tournament summaries" inputFile.seek(loc)
#self.faobs = readfile(inputFile) self.lines=fpdb_simple.removeTrailingEOL(inputFile.readlines())
#self.parseTourneyHistory() self.pos_in_file[file] = inputFile.tell()
return 0 inputFile.close()
site=fpdb_simple.recogniseSite(firstline) try: # sometimes we seem to be getting an empty self.lines, in which case, we just want to return.
category=fpdb_simple.recogniseCategory(firstline) firstline = self.lines[0]
except:
# print "import_fpdb_file", file, site, self.lines, "\n"
return
startpos=0 if firstline.find("Tournament Summary")!=-1:
stored=0 #counter print "TODO: implement importing tournament summaries"
duplicates=0 #counter #self.faobs = readfile(inputFile)
partial=0 #counter #self.parseTourneyHistory()
errors=0 #counter return 0
for i in range (len(self.lines)): #main loop, iterates through the lines of a file and calls the appropriate parser method site=fpdb_simple.recogniseSite(firstline)
if (len(self.lines[i])<2): category=fpdb_simple.recogniseCategory(firstline)
endpos=i
hand=self.lines[startpos:endpos]
if (len(hand[0])<2): startpos=0
hand=hand[1:] stored=0 #counter
duplicates=0 #counter
partial=0 #counter
errors=0 #counter
cancelled=False for i in range (len(self.lines)): #main loop, iterates through the lines of a file and calls the appropriate parser method
damaged=False if (len(self.lines[i])<2):
if (site=="ftp"): endpos=i
for i in range (len(hand)): hand=self.lines[startpos:endpos]
if (hand[i].endswith(" has been canceled")): #this is their typo. this is a typo, right?
cancelled=True
seat1=hand[i].find("Seat ") #todo: make this recover by skipping this line if (len(hand[0])<2):
if (seat1!=-1): hand=hand[1:]
if (hand[i].find("Seat ", seat1+3)!=-1):
damaged=True
if (len(hand)<3): cancelled=False
pass damaged=False
#todo: the above 2 lines are kind of a dirty hack, the mentioned circumstances should be handled elsewhere but that doesnt work with DOS/Win EOL. actually this doesnt work. if (site=="ftp"):
elif (hand[0].endswith(" (partial)")): #partial hand - do nothing for i in range (len(hand)):
partial+=1 if (hand[i].endswith(" has been canceled")): #this is their typo. this is a typo, right?
elif (hand[1].find("Seat")==-1 and hand[2].find("Seat")==-1 and hand[3].find("Seat")==-1):#todo: should this be or instead of and? cancelled=True
partial+=1
elif (cancelled or damaged):
partial+=1
else: #normal processing
isTourney=fpdb_simple.isTourney(hand[0])
if not isTourney:
fpdb_simple.filterAnteBlindFold(site,hand)
hand=fpdb_simple.filterCrap(site, hand, isTourney)
self.hand=hand
try: seat1=hand[i].find("Seat ") #todo: make this recover by skipping this line
handsId=fpdb_parse_logic.mainParser(self.db, self.cursor, site, category, hand) if (seat1!=-1):
self.db.commit() if (hand[i].find("Seat ", seat1+3)!=-1):
damaged=True
stored+=1 if (len(hand)<3):
self.db.commit() pass
# if settings['imp-callFpdbHud'] and self.callHud and os.sep=='/': #todo: the above 2 lines are kind of a dirty hack, the mentioned circumstances should be handled elsewhere but that doesnt work with DOS/Win EOL. actually this doesnt work.
if self.settings['imp-callFpdbHud'] and self.callHud: elif (hand[0].endswith(" (partial)")): #partial hand - do nothing
#print "call to HUD here. handsId:",handsId partial+=1
#pipe the Hands.id out to the HUD elif (hand[1].find("Seat")==-1 and hand[2].find("Seat")==-1 and hand[3].find("Seat")==-1):#todo: should this be or instead of and?
self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep) partial+=1
except fpdb_simple.DuplicateError: elif (cancelled or damaged):
duplicates+=1 partial+=1
except (ValueError), fe: else: #normal processing
errors+=1 isTourney=fpdb_simple.isTourney(hand[0])
self.printEmailErrorMessage(errors, file, hand[0]) if not isTourney:
fpdb_simple.filterAnteBlindFold(site,hand)
hand=fpdb_simple.filterCrap(site, hand, isTourney)
self.hand=hand
if (self.settings['failOnError']): try:
self.db.commit() #dont remove this, in case hand processing was cancelled. handsId=fpdb_parse_logic.mainParser(self.db, self.cursor, site, category, hand)
raise self.db.commit()
except (fpdb_simple.FpdbError), fe:
errors+=1
self.printEmailErrorMessage(errors, file, hand[0])
#fe.printStackTrace() #todo: get stacktrace stored+=1
self.db.rollback() self.db.commit()
if self.callHud:
#print "call to HUD here. handsId:",handsId
#pipe the Hands.id out to the HUD
self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
except fpdb_simple.DuplicateError:
duplicates+=1
except (ValueError), fe:
errors+=1
self.printEmailErrorMessage(errors, file, hand[0])
if (self.settings['failOnError']): if (self.settings['failOnError']):
self.db.commit() #dont remove this, in case hand processing was cancelled. self.db.commit() #dont remove this, in case hand processing was cancelled.
raise raise
if (self.settings['minPrint']!=0): except (fpdb_simple.FpdbError), fe:
if ((stored+duplicates+partial+errors)%self.settings['minPrint']==0): errors+=1
print "stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors self.printEmailErrorMessage(errors, file, hand[0])
if (self.settings['handCount']!=0): #fe.printStackTrace() #todo: get stacktrace
if ((stored+duplicates+partial+errors)>=self.settings['handCount']): self.db.rollback()
if (not self.settings['quiet']):
print "quitting due to reaching the amount of hands to be imported"
print "Total stored:", stored, "duplicates:", duplicates, "partial/damaged:", partial, "errors:", errors, " time:", (time() - starttime)
sys.exit(0)
startpos=endpos
print "Total stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors, " time:", (time() - starttime)
if stored==0: if (self.settings['failOnError']):
if duplicates>0: self.db.commit() #dont remove this, in case hand processing was cancelled.
for line_no in range(len(self.lines)): raise
if self.lines[line_no].find("Game #")!=-1: if (self.settings['minPrint']!=0):
final_game_line=self.lines[line_no] if ((stored+duplicates+partial+errors)%self.settings['minPrint']==0):
handsId=fpdb_simple.parseSiteHandNo(final_game_line) print "stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors
else:
print "failed to read a single hand from file:", inputFile if (self.settings['handCount']!=0):
handsId=0 if ((stored+duplicates+partial+errors)>=self.settings['handCount']):
#todo: this will cause return of an unstored hand number if the last hand was error or partial if (not self.settings['quiet']):
self.db.commit() print "quitting due to reaching the amount of hands to be imported"
self.handsId=handsId print "Total stored:", stored, "duplicates:", duplicates, "partial/damaged:",
return handsId partial, "errors:", errors, " time: %5.3f" % (time() - starttime)
sys.exit(0)
startpos=endpos
print "Total stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors, " time: %5.3f" % (time() - starttime)
if stored==0:
if duplicates>0:
for line_no in range(len(self.lines)):
if self.lines[line_no].find("Game #")!=-1:
final_game_line=self.lines[line_no]
handsId=fpdb_simple.parseSiteHandNo(final_game_line)
else:
print "failed to read a single hand from file:", inputFile
handsId=0
#todo: this will cause return of an unstored hand number if the last hand was error or partial
self.db.commit()
self.handsId=handsId
return handsId
#end def import_file_dict #end def import_file_dict
def parseTourneyHistory(self): def parseTourneyHistory(self):
print "Tourney history parser stub" print "Tourney history parser stub"
#Find tournament boundaries. #Find tournament boundaries.
#print self.foabs #print self.foabs
def printEmailErrorMessage(self, errors, filename, line): def printEmailErrorMessage(self, errors, filename, line):
print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it." print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it."
print "Filename:", filename print "Filename:", filename
print "Here is the first line so you can identify it. Please mention that the error was a ValueError:" print "Here is the first line so you can identify it. Please mention that the error was a ValueError:"
print self.hand[0] print self.hand[0]
if __name__ == "__main__": if __name__ == "__main__":
print "CLI for fpdb_import is now available as CliFpdb.py" print "CLI for fpdb_import is now available as CliFpdb.py"

View File

@ -46,7 +46,7 @@ def mainParser(db, cursor, site, category, hand):
#print "found small blind line:",smallBlindLine #print "found small blind line:",smallBlindLine
break break
#print "small blind line:",smallBlindLine #print "small blind line:",smallBlindLine
gametypeID=fpdb_simple.recogniseGametypeID(cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney) gametypeID=fpdb_simple.recogniseGametypeID(db, cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
if isTourney: if isTourney:
if site!="ps": if site!="ps":
raise fpdb_simple.FpdbError("tourneys are only supported on PS right now") raise fpdb_simple.FpdbError("tourneys are only supported on PS right now")
@ -142,18 +142,18 @@ def mainParser(db, cursor, site, category, hand):
payin_amounts=fpdb_simple.calcPayin(len(names), buyin, fee) payin_amounts=fpdb_simple.calcPayin(len(names), buyin, fee)
if base=="hold": if base=="hold":
result = fpdb_save_to_db.tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID, result = fpdb_save_to_db.tourney_holdem_omaha(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos) siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
elif base=="stud": elif base=="stud":
result = fpdb_save_to_db.tourney_stud(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID, result = fpdb_save_to_db.tourney_stud(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos) siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
else: else:
raise fpdb_simple.FpdbError ("unrecognised category") raise fpdb_simple.FpdbError ("unrecognised category")
else: else:
if base=="hold": if base=="hold":
result = fpdb_save_to_db.ring_holdem_omaha(cursor, base, category, siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos) result = fpdb_save_to_db.ring_holdem_omaha(db, cursor, base, category, siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
elif base=="stud": elif base=="stud":
result = fpdb_save_to_db.ring_stud(cursor, base, category, siteHandNo, gametypeID, result = fpdb_save_to_db.ring_stud(db, cursor, base, category, siteHandNo, gametypeID,
handStartTime, names, playerIDs, startCashes, antes, cardValues, handStartTime, names, playerIDs, startCashes, antes, cardValues,
cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos) cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
else: else:

View File

@ -21,13 +21,13 @@
import fpdb_simple import fpdb_simple
#stores a stud/razz hand into the database #stores a stud/razz hand into the database
def ring_stud(cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos): def ring_stud(db, cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits) fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
hands_id=fpdb_simple.storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats) hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
#print "before calling store_hands_players_stud, antes:", antes #print "before calling store_hands_players_stud, antes:", antes
hands_players_ids=fpdb_simple.store_hands_players_stud(cursor, hands_id, player_ids, hands_players_ids=fpdb_simple.store_hands_players_stud(db, cursor, hands_id, player_ids,
start_cashes, antes, card_values, card_suits, winnings, rakes, seatNos) start_cashes, antes, card_values, card_suits, winnings, rakes, seatNos)
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData) fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
@ -36,14 +36,14 @@ def ring_stud(cursor, base, category, site_hand_no, gametype_id, hand_start_time
return hands_id return hands_id
#end def ring_stud #end def ring_stud
def ring_holdem_omaha(cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos): def ring_holdem_omaha(db, cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
"""stores a holdem/omaha hand into the database""" """stores a holdem/omaha hand into the database"""
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits) fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
fpdb_simple.fill_board_cards(board_values, board_suits) fpdb_simple.fill_board_cards(board_values, board_suits)
hands_id=fpdb_simple.storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats) hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos) hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos)
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData) fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
@ -53,7 +53,7 @@ def ring_holdem_omaha(cursor, base, category, site_hand_no, gametype_id, hand_st
return hands_id return hands_id
#end def ring_holdem_omaha #end def ring_holdem_omaha
def tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId, siteId, #end of tourney specific params def tourney_holdem_omaha(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId, siteId, #end of tourney specific params
site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos): site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
"""stores a tourney holdem/omaha hand into the database""" """stores a tourney holdem/omaha hand into the database"""
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits) fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
@ -62,9 +62,9 @@ def tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knoc
tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourney_start) tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourney_start)
tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings) tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings)
hands_id=fpdb_simple.storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats) hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha_tourney(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids) hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha_tourney(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids)
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData) fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
@ -74,7 +74,7 @@ def tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knoc
return hands_id return hands_id
#end def tourney_holdem_omaha #end def tourney_holdem_omaha
def tourney_stud(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId, def tourney_stud(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId,
siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos): siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
#stores a tourney stud/razz hand into the database #stores a tourney stud/razz hand into the database
fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits) fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits)
@ -83,9 +83,9 @@ def tourney_stud(cursor, base, category, siteTourneyNo, buyin, fee, knockout, en
tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, playerIds, payin_amounts, ranks, winnings) tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, playerIds, payin_amounts, ranks, winnings)
hands_id=fpdb_simple.storeHands(cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats) hands_id=fpdb_simple.storeHands(db, cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats)
hands_players_ids=fpdb_simple.store_hands_players_stud_tourney(cursor, hands_id, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, seatNos, tourneys_players_ids) hands_players_ids=fpdb_simple.store_hands_players_stud_tourney(db, cursor, hands_id, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, seatNos, tourneys_players_ids)
fpdb_simple.storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData) fpdb_simple.storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData)

View File

@ -484,7 +484,8 @@ def isActionLine(line):
#returns whether this is a duplicate #returns whether this is a duplicate
def isAlreadyInDB(cursor, gametypeID, siteHandNo): def isAlreadyInDB(cursor, gametypeID, siteHandNo):
cursor.execute ("SELECT id FROM Hands WHERE gametypeId=%s AND siteHandNo=%s", (gametypeID, siteHandNo)) #print "isAlreadyInDB gtid,shand:",gametypeID, siteHandNo
cursor.execute ("SELECT id FROM Hands WHERE gametypeId=%s AND siteHandNo=%s", (gametypeID, siteHandNo))
result=cursor.fetchall() result=cursor.fetchall()
if (len(result)>=1): if (len(result)>=1):
raise DuplicateError ("dupl") raise DuplicateError ("dupl")
@ -1021,7 +1022,7 @@ def recogniseCategory(line):
#end def recogniseCategory #end def recogniseCategory
#returns the int for the gametype_id for the given line #returns the int for the gametype_id for the given line
def recogniseGametypeID(cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy def recogniseGametypeID(db, cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy
#if (topline.find("HORSE")!=-1): #if (topline.find("HORSE")!=-1):
# raise FpdbError("recogniseGametypeID: HORSE is not yet supported.") # raise FpdbError("recogniseGametypeID: HORSE is not yet supported.")
@ -1072,7 +1073,10 @@ def recogniseGametypeID(cursor, topline, smallBlindLine, site_id, category, isTo
else: else:
cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet)) cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
result=cursor.fetchone() result=cursor.fetchone()
#print "tried SELECTing gametypes.id, result:",result #print "recgt1 result=",result
#ret=result[0]
#print "recgt1 ret=",ret
#print "tried SELECTing gametypes.id, result:",result
try: try:
len(result) len(result)
@ -1105,17 +1109,19 @@ def recogniseGametypeID(cursor, topline, smallBlindLine, site_id, category, isTo
cursor.execute("""INSERT INTO Gametypes cursor.execute("""INSERT INTO Gametypes
(siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet) (siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_blind, big_blind, small_bet, big_bet)) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_blind, big_blind, small_bet, big_bet))
cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet)) #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
else: else:
cursor.execute("""INSERT INTO Gametypes cursor.execute("""INSERT INTO Gametypes
(siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet) (siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind
cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet)) #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
result=cursor.fetchone() result=(db.insert_id(),)
#print "recgt2 result=",result
#print "created new gametypes.id:",result #print "created new gametypes.id:",result
return result[0] #print "recgt3: result=", result
return result[0]
#end def recogniseGametypeID #end def recogniseGametypeID
def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon): def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon):
@ -1248,15 +1254,16 @@ def store_board_cards(cursor, hands_id, board_values, board_suits):
board_values[4], board_suits[4])) board_values[4], board_suits[4]))
#end def store_board_cards #end def store_board_cards
def storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats): def storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats):
#stores into table hands #stores into table hands
cursor.execute ("INSERT INTO Hands (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats) VALUES (%s, %s, %s, %s, %s, %s, %s)", (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.datetime.today(), maxSeats)) cursor.execute ("INSERT INTO Hands (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats) VALUES (%s, %s, %s, %s, %s, %s, %s)", (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.datetime.today(), maxSeats))
#todo: find a better way of doing this... #todo: find a better way of doing this...
cursor.execute("SELECT id FROM Hands WHERE siteHandNo=%s AND gametypeId=%s", (site_hand_no, gametype_id)) #cursor.execute("SELECT id FROM Hands WHERE siteHandNo=%s AND gametypeId=%s", (site_hand_no, gametype_id))
return cursor.fetchall()[0][0] #return cursor.fetchall()[0][0]
return db.insert_id() # mysql only
#end def storeHands #end def storeHands
def store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos): def store_hands_players_holdem_omaha(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos):
result=[] result=[]
if (category=="holdem"): if (category=="holdem"):
for i in range (len(player_ids)): for i in range (len(player_ids)):
@ -1268,8 +1275,9 @@ def store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, sta
(hands_id, player_ids[i], start_cashes[i], positions[i], (hands_id, player_ids[i], start_cashes[i], positions[i],
card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1], card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
winnings[i], rakes[i], seatNos[i])) winnings[i], rakes[i], seatNos[i]))
cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i])) #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
result.append(cursor.fetchall()[0][0]) #result.append(cursor.fetchall()[0][0])
result.append( db.insert_id() ) # mysql only
elif (category=="omahahi" or category=="omahahilo"): elif (category=="omahahi" or category=="omahahilo"):
for i in range (len(player_ids)): for i in range (len(player_ids)):
cursor.execute ("""INSERT INTO HandsPlayers cursor.execute ("""INSERT INTO HandsPlayers
@ -1281,14 +1289,15 @@ def store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, sta
card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1], card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3], card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
winnings[i], rakes[i], seatNos[i])) winnings[i], rakes[i], seatNos[i]))
cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i])) #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
result.append(cursor.fetchall()[0][0]) #result.append(cursor.fetchall()[0][0])
result.append( db.insert_id() ) # mysql only
else: else:
raise FpdbError("invalid category") raise FpdbError("invalid category")
return result return result
#end def store_hands_players_holdem_omaha #end def store_hands_players_holdem_omaha
def store_hands_players_stud(cursor, hands_id, player_ids, start_cashes, antes, def store_hands_players_stud(db, cursor, hands_id, player_ids, start_cashes, antes,
card_values, card_suits, winnings, rakes, seatNos): card_values, card_suits, winnings, rakes, seatNos):
#stores hands_players rows for stud/razz games. returns an array of the resulting IDs #stores hands_players rows for stud/razz games. returns an array of the resulting IDs
result=[] result=[]
@ -1307,12 +1316,14 @@ def store_hands_players_stud(cursor, hands_id, player_ids, start_cashes, antes,
card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3], card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5], card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
card_values[i][6], card_suits[i][6], winnings[i], rakes[i], seatNos[i])) card_values[i][6], card_suits[i][6], winnings[i], rakes[i], seatNos[i]))
cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i])) #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
result.append(cursor.fetchall()[0][0]) #result.append(cursor.fetchall()[0][0])
result.append( db.insert_id() ) # mysql only
return result return result
#end def store_hands_players_stud #end def store_hands_players_stud
def store_hands_players_holdem_omaha_tourney(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids): def store_hands_players_holdem_omaha_tourney(db, cursor, category, hands_id, player_ids,
start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
#stores hands_players for tourney holdem/omaha hands #stores hands_players for tourney holdem/omaha hands
result=[] result=[]
for i in range (len(player_ids)): for i in range (len(player_ids)):
@ -1338,13 +1349,14 @@ def store_hands_players_holdem_omaha_tourney(cursor, category, hands_id, player_
winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i])) winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
else: else:
raise FpdbError ("invalid card_values length:"+str(len(card_values[0]))) raise FpdbError ("invalid card_values length:"+str(len(card_values[0])))
cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i])) #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
result.append(cursor.fetchall()[0][0]) #result.append(cursor.fetchall()[0][0])
result.append( db.insert_id() ) # mysql only
return result return result
#end def store_hands_players_holdem_omaha_tourney #end def store_hands_players_holdem_omaha_tourney
def store_hands_players_stud_tourney(cursor, hands_id, player_ids, start_cashes, def store_hands_players_stud_tourney(db, cursor, hands_id, player_ids, start_cashes,
antes, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids): antes, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
#stores hands_players for tourney stud/razz hands #stores hands_players for tourney stud/razz hands
result=[] result=[]
@ -1362,8 +1374,9 @@ def store_hands_players_stud_tourney(cursor, hands_id, player_ids, start_cashes,
card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3], card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5], card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i])) card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i])) #cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
result.append(cursor.fetchall()[0][0]) #result.append(cursor.fetchall()[0][0])
result.append( db.insert_id() ) # mysql only
return result return result
#end def store_hands_players_stud_tourney #end def store_hands_players_stud_tourney
@ -1949,9 +1962,9 @@ def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
for player in range (len(playerIds)): for player in range (len(playerIds)):
if base=="hold": if base=="hold":
cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player])) cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player]))
else: else:
cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats=%s", (gametypeId, playerIds[player], len(playerIds))) cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s", (gametypeId, playerIds[player], len(playerIds)))
row=cursor.fetchone() row=cursor.fetchone()
#print "gametypeId:", gametypeId, "playerIds[player]",playerIds[player], "len(playerIds):",len(playerIds), "row:",row #print "gametypeId:", gametypeId, "playerIds[player]",playerIds[player], "len(playerIds):",len(playerIds), "row:",row
@ -2097,7 +2110,7 @@ def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
#end def storeHudCache #end def storeHudCache
def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime): def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime):
cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId=%s", (siteTourneyNo, tourneyTypeId)) cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
tmp=cursor.fetchone() tmp=cursor.fetchone()
#print "tried SELECTing tourneys.id, result:",tmp #print "tried SELECTing tourneys.id, result:",tmp
@ -2107,7 +2120,7 @@ def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, sta
cursor.execute("""INSERT INTO Tourneys cursor.execute("""INSERT INTO Tourneys
(tourneyTypeId, siteTourneyNo, entries, prizepool, startTime) (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)
VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)) VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime))
cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId=%s", (siteTourneyNo, tourneyTypeId)) cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
tmp=cursor.fetchone() tmp=cursor.fetchone()
#print "created new tourneys.id:",tmp #print "created new tourneys.id:",tmp
return tmp[0] return tmp[0]
@ -2121,7 +2134,7 @@ def store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks,
#print "ranks:",ranks #print "ranks:",ranks
#print "winnings:",winnings #print "winnings:",winnings
for i in range (len(player_ids)): for i in range (len(player_ids)):
cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId=%s", (tourney_id, player_ids[i])) cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", (tourney_id, player_ids[i]))
tmp=cursor.fetchone() tmp=cursor.fetchone()
#print "tried SELECTing tourneys_players.id:",tmp #print "tried SELECTing tourneys_players.id:",tmp
@ -2132,7 +2145,7 @@ def store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks,
(tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""", (tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""",
(tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i])) (tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i]))
cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId=%s", cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s",
(tourney_id, player_ids[i])) (tourney_id, player_ids[i]))
tmp=cursor.fetchone() tmp=cursor.fetchone()
#print "created new tourneys_players.id:",tmp #print "created new tourneys_players.id:",tmp