sqlcoder initial updates
This commit is contained in:
parent
5884f2f66b
commit
a824814c0a
0
pyfpdb/CliFpdb.py
Executable file → Normal file
0
pyfpdb/CliFpdb.py
Executable file → Normal file
1219
pyfpdb/Configuration.py
Executable file → Normal file
1219
pyfpdb/Configuration.py
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
|
@ -601,7 +601,34 @@ class FpdbSQLQueries:
|
|||
WHERE Players.name = %s AND Players.siteId = %s AND (tourneysPlayersId IS NULL)
|
||||
ORDER BY handStart"""
|
||||
|
||||
# Returns the profit for a given ring game handId, Total pot - money invested by playerId
|
||||
# Returns the profit for all hands, Total pot - money invested by playerId
|
||||
if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
|
||||
self.query['getRingProfitAllHandsPlayerIdSite'] = """
|
||||
SELECT hp.handId, hp.winnings, SUM(ha.amount) costs, hp.winnings - SUM(ha.amount) profit
|
||||
FROM HandsPlayers hp
|
||||
INNER JOIN Players pl ON hp.playerId = pl.id
|
||||
INNER JOIN Hands h ON h.id = hp.handId
|
||||
INNER JOIN HandsActions ha ON ha.handPlayerId = hp.id
|
||||
WHERE pl.name = %s
|
||||
AND pl.siteId = %s
|
||||
AND hp.tourneysPlayersId IS NULL
|
||||
group by hp.handId, hp.winnings, h.handStart
|
||||
ORDER BY h.handStart"""
|
||||
elif(self.dbname == 'SQLite'):
|
||||
#May not work.
|
||||
self.query['getRingProfitAllHandsPlayerIdSite'] = """
|
||||
SELECT hp.handId, hp.winnings, SUM(ha.amount) costs, hp.winnings - SUM(ha.amount) profit
|
||||
FROM HandsPlayers hp
|
||||
INNER JOIN Players pl ON hp.playerId = pl.id
|
||||
INNER JOIN Hands h ON h.id = hp.handId
|
||||
INNER JOIN HandsActions ha ON ha.handPlayerId = hp.id
|
||||
WHERE pl.name = %s
|
||||
AND pl.siteId = %s
|
||||
AND hp.tourneysPlayersId IS NULL
|
||||
group by hp.handId, hp.winnings, h.handStart
|
||||
ORDER BY h.handStart"""
|
||||
|
||||
# Returns the profit for a given ring game handId, Total pot - money invested by playerId - WRONG, returns players costs
|
||||
if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'):
|
||||
self.query['getRingProfitFromHandId'] = """SELECT SUM(amount) FROM HandsActions
|
||||
INNER JOIN HandsPlayers ON HandsActions.handPlayerId = HandsPlayers.id
|
||||
|
|
|
@ -1,216 +1,211 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#Copyright 2008 Steffen Jobbagy-Felso
|
||||
#This program is free software: you can redistribute it and/or modify
|
||||
#it under the terms of the GNU Affero General Public License as published by
|
||||
#the Free Software Foundation, version 3 of the License.
|
||||
#
|
||||
#This program is distributed in the hope that it will be useful,
|
||||
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
#GNU General Public License for more details.
|
||||
#
|
||||
#You should have received a copy of the GNU Affero General Public License
|
||||
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#In the "official" distribution you can find the license in
|
||||
#agpl-3.0.txt in the docs folder of the package.
|
||||
|
||||
import threading
|
||||
import subprocess
|
||||
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk
|
||||
import gobject
|
||||
import os
|
||||
import time
|
||||
import fpdb_import
|
||||
|
||||
class GuiAutoImport (threading.Thread):
|
||||
def starsBrowseClicked(self, widget, data):
|
||||
"""runs when user clicks browse on auto import tab"""
|
||||
#print "start of GuiAutoImport.starsBrowseClicked"
|
||||
current_path=self.starsDirPath.get_text()
|
||||
|
||||
dia_chooser = gtk.FileChooserDialog(title="Please choose the path that you want to auto import",
|
||||
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
|
||||
#dia_chooser.set_current_folder(pathname)
|
||||
dia_chooser.set_filename(current_path)
|
||||
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
|
||||
|
||||
response = dia_chooser.run()
|
||||
if response == gtk.RESPONSE_OK:
|
||||
#print dia_chooser.get_filename(), 'selected'
|
||||
self.starsDirPath.set_text(dia_chooser.get_filename())
|
||||
elif response == gtk.RESPONSE_CANCEL:
|
||||
print 'Closed, no files selected'
|
||||
dia_chooser.destroy()
|
||||
#end def GuiAutoImport.starsBrowseClicked
|
||||
|
||||
def tiltBrowseClicked(self, widget, data):
|
||||
"""runs when user clicks browse on auto import tab"""
|
||||
#print "start of GuiAutoImport.tiltBrowseClicked"
|
||||
current_path=self.tiltDirPath.get_text()
|
||||
|
||||
dia_chooser = gtk.FileChooserDialog(title="Please choose the path that you want to auto import",
|
||||
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
|
||||
#dia_chooser.set_current_folder(pathname)
|
||||
dia_chooser.set_filename(current_path)
|
||||
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
|
||||
|
||||
response = dia_chooser.run()
|
||||
if response == gtk.RESPONSE_OK:
|
||||
#print dia_chooser.get_filename(), 'selected'
|
||||
self.tiltDirPath.set_text(dia_chooser.get_filename())
|
||||
elif response == gtk.RESPONSE_CANCEL:
|
||||
print 'Closed, no files selected'
|
||||
dia_chooser.destroy()
|
||||
#end def GuiAutoImport.tiltBrowseClicked
|
||||
|
||||
def do_import(self):
|
||||
"""Callback for timer to do an import iteration."""
|
||||
self.importer.runUpdated()
|
||||
print "GuiAutoImport.import_dir done"
|
||||
return True
|
||||
|
||||
def startClicked(self, widget, data):
|
||||
"""runs when user clicks start on auto import tab"""
|
||||
|
||||
# Check to see if we have an open file handle to the HUD and open one if we do not.
|
||||
# bufsize = 1 means unbuffered
|
||||
# We need to close this file handle sometime.
|
||||
|
||||
# TODO: Allow for importing from multiple dirs - REB 29AUG2008
|
||||
# As presently written this function does nothing if there is already a pipe open.
|
||||
# That is not correct. It should open another dir for importing while piping the
|
||||
# results to the same pipe. This means that self.path should be a a list of dirs
|
||||
# to watch.
|
||||
try: #uhhh, I don't this this is the best way to check for the existence of an attr
|
||||
getattr(self, "pipe_to_hud")
|
||||
except AttributeError:
|
||||
if os.name == 'nt':
|
||||
command = "python HUD_main.py" + " %s" % (self.database)
|
||||
bs = 0 # windows is not happy with line buffing here
|
||||
self.pipe_to_hud = subprocess.Popen(command, bufsize = bs, stdin = subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
else:
|
||||
cwd = os.getcwd()
|
||||
command = os.path.join(cwd, 'HUD_main.py')
|
||||
bs = 1
|
||||
self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
# self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
|
||||
# universal_newlines=True)
|
||||
# command = command + " %s" % (self.database)
|
||||
# print "command = ", command
|
||||
# self.pipe_to_hud = os.popen(command, 'w')
|
||||
self.starspath=self.starsDirPath.get_text()
|
||||
self.tiltpath=self.tiltDirPath.get_text()
|
||||
|
||||
# Add directory to importer object.
|
||||
self.importer.addImportDirectory(self.starspath, True, "PokerStars", "passthrough")
|
||||
self.importer.addImportDirectory(self.tiltpath, True, "FullTilt", "passthrough")
|
||||
self.do_import()
|
||||
|
||||
interval=int(self.intervalEntry.get_text())
|
||||
gobject.timeout_add(interval*1000, self.do_import)
|
||||
#end def GuiAutoImport.startClicked
|
||||
|
||||
def get_vbox(self):
|
||||
"""returns the vbox of this thread"""
|
||||
return self.mainVBox
|
||||
#end def get_vbox
|
||||
|
||||
def __init__(self, settings, config, debug=True):
|
||||
"""Constructor for GuiAutoImport"""
|
||||
self.settings=settings
|
||||
self.config=config
|
||||
self.importer = fpdb_import.Importer(self,self.settings)
|
||||
self.importer.setCallHud(True)
|
||||
self.importer.setMinPrint(30)
|
||||
self.importer.setQuiet(False)
|
||||
self.importer.setFailOnError(False)
|
||||
self.importer.setHandCount(0)
|
||||
# self.importer.setWatchTime()
|
||||
|
||||
self.server=settings['db-host']
|
||||
self.user=settings['db-user']
|
||||
self.password=settings['db-password']
|
||||
self.database=settings['db-databaseName']
|
||||
|
||||
self.mainVBox=gtk.VBox(False,1)
|
||||
self.mainVBox.show()
|
||||
|
||||
self.settingsHBox = gtk.HBox(False, 0)
|
||||
self.mainVBox.pack_start(self.settingsHBox, False, True, 0)
|
||||
self.settingsHBox.show()
|
||||
|
||||
self.intervalLabel = gtk.Label("Interval (ie. break) between imports in seconds:")
|
||||
self.settingsHBox.pack_start(self.intervalLabel)
|
||||
self.intervalLabel.show()
|
||||
|
||||
self.intervalEntry=gtk.Entry()
|
||||
self.intervalEntry.set_text(str(self.settings['hud-defaultInterval']))
|
||||
self.settingsHBox.pack_start(self.intervalEntry)
|
||||
self.intervalEntry.show()
|
||||
|
||||
self.pathHBox = gtk.HBox(False, 0)
|
||||
self.mainVBox.pack_start(self.pathHBox, False, True, 0)
|
||||
self.pathHBox.show()
|
||||
|
||||
self.pathStarsLabel = gtk.Label("Path to PokerStars auto-import:")
|
||||
self.pathHBox.pack_start(self.pathStarsLabel, False, False, 0)
|
||||
self.pathStarsLabel.show()
|
||||
|
||||
self.starsDirPath=gtk.Entry()
|
||||
paths = self.config.get_default_paths("PokerStars")
|
||||
self.starsDirPath.set_text(paths['hud-defaultPath'])
|
||||
self.pathHBox.pack_start(self.starsDirPath, False, True, 0)
|
||||
self.starsDirPath.show()
|
||||
|
||||
self.browseButton=gtk.Button("Browse...")
|
||||
self.browseButton.connect("clicked", self.starsBrowseClicked, "Browse clicked")
|
||||
self.pathHBox.pack_start(self.browseButton, False, False, 0)
|
||||
self.browseButton.show()
|
||||
|
||||
self.pathTiltLabel = gtk.Label("Path to Full Tilt auto-import:")
|
||||
self.pathHBox.pack_start(self.pathTiltLabel, False, False, 0)
|
||||
self.pathTiltLabel.show()
|
||||
|
||||
self.tiltDirPath=gtk.Entry()
|
||||
paths = self.config.get_default_paths("Full Tilt")
|
||||
self.tiltDirPath.set_text(paths['hud-defaultPath'])
|
||||
self.pathHBox.pack_start(self.tiltDirPath, False, True, 0)
|
||||
self.tiltDirPath.show()
|
||||
|
||||
self.browseButton=gtk.Button("Browse...")
|
||||
self.browseButton.connect("clicked", self.tiltBrowseClicked, "Browse clicked")
|
||||
self.pathHBox.pack_start(self.browseButton, False, False, 0)
|
||||
self.browseButton.show()
|
||||
|
||||
self.startButton=gtk.Button("Start Autoimport")
|
||||
self.startButton.connect("clicked", self.startClicked, "start clicked")
|
||||
self.mainVBox.add(self.startButton)
|
||||
self.startButton.show()
|
||||
#end of GuiAutoImport.__init__
|
||||
if __name__== "__main__":
|
||||
def destroy(*args): # call back for terminating the main eventloop
|
||||
gtk.main_quit()
|
||||
|
||||
settings = {}
|
||||
settings['db-host'] = "192.168.1.100"
|
||||
settings['db-user'] = "mythtv"
|
||||
settings['db-password'] = "mythtv"
|
||||
settings['db-databaseName'] = "fpdb"
|
||||
settings['hud-defaultInterval'] = 10
|
||||
settings['hud-defaultPath'] = 'C:/Program Files/PokerStars/HandHistory/nutOmatic'
|
||||
settings['imp-callFpdbHud'] = True
|
||||
|
||||
i = GuiAutoImport(settings)
|
||||
main_window = gtk.Window()
|
||||
main_window.connect("destroy", destroy)
|
||||
main_window.add(i.mainVBox)
|
||||
main_window.show()
|
||||
gtk.main()
|
||||
#!/usr/bin/python
|
||||
|
||||
#Copyright 2008 Steffen Jobbagy-Felso
|
||||
#This program is free software: you can redistribute it and/or modify
|
||||
#it under the terms of the GNU Affero General Public License as published by
|
||||
#the Free Software Foundation, version 3 of the License.
|
||||
#
|
||||
#This program is distributed in the hope that it will be useful,
|
||||
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
#GNU General Public License for more details.
|
||||
#
|
||||
#You should have received a copy of the GNU Affero General Public License
|
||||
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#In the "official" distribution you can find the license in
|
||||
#agpl-3.0.txt in the docs folder of the package.
|
||||
|
||||
import threading
|
||||
import subprocess
|
||||
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk
|
||||
import gobject
|
||||
import os
|
||||
import time
|
||||
import fpdb_import
|
||||
|
||||
|
||||
class GuiAutoImport (threading.Thread):
|
||||
def __init__(self, settings, config):
|
||||
"""Constructor for GuiAutoImport"""
|
||||
self.settings=settings
|
||||
self.config=config
|
||||
|
||||
imp = self.config.get_import_parameters()
|
||||
|
||||
print "Import parameters"
|
||||
print imp
|
||||
|
||||
self.input_settings = {}
|
||||
|
||||
self.importer = fpdb_import.Importer(self, self.settings, self.config)
|
||||
self.importer.setCallHud(True)
|
||||
self.importer.setMinPrint(30)
|
||||
self.importer.setQuiet(False)
|
||||
self.importer.setFailOnError(False)
|
||||
self.importer.setHandCount(0)
|
||||
# self.importer.setWatchTime()
|
||||
|
||||
self.server=settings['db-host']
|
||||
self.user=settings['db-user']
|
||||
self.password=settings['db-password']
|
||||
self.database=settings['db-databaseName']
|
||||
|
||||
self.mainVBox=gtk.VBox(False,1)
|
||||
self.mainVBox.show()
|
||||
|
||||
self.settingsHBox = gtk.HBox(False, 0)
|
||||
self.mainVBox.pack_start(self.settingsHBox, False, True, 0)
|
||||
self.settingsHBox.show()
|
||||
|
||||
self.intervalLabel = gtk.Label("Time between imports in seconds:")
|
||||
self.settingsHBox.pack_start(self.intervalLabel)
|
||||
self.intervalLabel.show()
|
||||
|
||||
self.intervalEntry=gtk.Entry()
|
||||
self.intervalEntry.set_text(str(self.config.get_import_parameters().get("interval")))
|
||||
self.settingsHBox.pack_start(self.intervalEntry)
|
||||
self.intervalEntry.show()
|
||||
|
||||
self.addSites(self.mainVBox)
|
||||
|
||||
self.startButton=gtk.Button("Start Autoimport")
|
||||
self.startButton.connect("clicked", self.startClicked, "start clicked")
|
||||
self.mainVBox.add(self.startButton)
|
||||
self.startButton.show()
|
||||
|
||||
|
||||
#end of GuiAutoImport.__init__
|
||||
def browseClicked(self, widget, data):
|
||||
"""runs when user clicks one of the browse buttons in the auto import tab"""
|
||||
current_path=data[1].get_text()
|
||||
|
||||
dia_chooser = gtk.FileChooserDialog(title="Please choose the path that you want to auto import",
|
||||
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
|
||||
#dia_chooser.set_current_folder(pathname)
|
||||
dia_chooser.set_filename(current_path)
|
||||
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
|
||||
|
||||
response = dia_chooser.run()
|
||||
if response == gtk.RESPONSE_OK:
|
||||
#print dia_chooser.get_filename(), 'selected'
|
||||
data[1].set_text(dia_chooser.get_filename())
|
||||
self.input_settings[data[0]][0] = dia_chooser.get_filename()
|
||||
elif response == gtk.RESPONSE_CANCEL:
|
||||
print 'Closed, no files selected'
|
||||
dia_chooser.destroy()
|
||||
#end def GuiAutoImport.browseClicked
|
||||
|
||||
def do_import(self):
|
||||
"""Callback for timer to do an import iteration."""
|
||||
self.importer.runUpdated()
|
||||
print "GuiAutoImport.import_dir done"
|
||||
return True
|
||||
|
||||
def startClicked(self, widget, data):
|
||||
"""runs when user clicks start on auto import tab"""
|
||||
|
||||
# Check to see if we have an open file handle to the HUD and open one if we do not.
|
||||
# bufsize = 1 means unbuffered
|
||||
# We need to close this file handle sometime.
|
||||
|
||||
# TODO: Allow for importing from multiple dirs - REB 29AUG2008
|
||||
# As presently written this function does nothing if there is already a pipe open.
|
||||
# That is not correct. It should open another dir for importing while piping the
|
||||
# results to the same pipe. This means that self.path should be a a list of dirs
|
||||
# to watch.
|
||||
try: #uhhh, I don't this this is the best way to check for the existence of an attr
|
||||
getattr(self, "pipe_to_hud")
|
||||
except AttributeError:
|
||||
if os.name == 'nt':
|
||||
command = "python HUD_main.py" + " %s" % (self.database)
|
||||
bs = 0 # windows is not happy with line buffing here
|
||||
self.pipe_to_hud = subprocess.Popen(command, bufsize = bs, stdin = subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
else:
|
||||
cwd = os.getcwd()
|
||||
command = os.path.join(cwd, 'HUD_main.py')
|
||||
bs = 1
|
||||
self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
# self.pipe_to_hud = subprocess.Popen((command, self.database), bufsize = bs, stdin = subprocess.PIPE,
|
||||
# universal_newlines=True)
|
||||
# command = command + " %s" % (self.database)
|
||||
# print "command = ", command
|
||||
# self.pipe_to_hud = os.popen(command, 'w')
|
||||
|
||||
# Add directories to importer object.
|
||||
for site in self.input_settings:
|
||||
self.importer.addImportDirectory(self.input_settings[site][0], True, site, self.input_settings[site][1])
|
||||
print "Adding import directories - Site: " + site + " dir: "+ str(self.input_settings[site][0])
|
||||
self.do_import()
|
||||
|
||||
interval=int(self.intervalEntry.get_text())
|
||||
gobject.timeout_add(interval*1000, self.do_import)
|
||||
#end def GuiAutoImport.startClicked
|
||||
|
||||
def get_vbox(self):
|
||||
"""returns the vbox of this thread"""
|
||||
return self.mainVBox
|
||||
#end def get_vbox
|
||||
|
||||
#Create the site line given required info and setup callbacks
|
||||
#enabling and disabling sites from this interface not possible
|
||||
#expects a box to layout the line horizontally
|
||||
def createSiteLine(self, hbox, site, iconpath, hhpath, filter_name, active = True):
|
||||
label = gtk.Label(site + " auto-import:")
|
||||
hbox.pack_start(label, False, False, 0)
|
||||
label.show()
|
||||
|
||||
dirPath=gtk.Entry()
|
||||
dirPath.set_text(hhpath)
|
||||
hbox.pack_start(dirPath, False, True, 0)
|
||||
dirPath.show()
|
||||
|
||||
browseButton=gtk.Button("Browse...")
|
||||
browseButton.connect("clicked", self.browseClicked, [site] + [dirPath])
|
||||
hbox.pack_start(browseButton, False, False, 0)
|
||||
browseButton.show()
|
||||
|
||||
label = gtk.Label(site + " filter:")
|
||||
hbox.pack_start(label, False, False, 0)
|
||||
label.show()
|
||||
|
||||
filter=gtk.Entry()
|
||||
filter.set_text(filter_name)
|
||||
hbox.pack_start(filter, False, True, 0)
|
||||
filter.show()
|
||||
|
||||
def addSites(self, vbox):
|
||||
for site in self.config.supported_sites.keys():
|
||||
pathHBox = gtk.HBox(False, 0)
|
||||
vbox.pack_start(pathHBox, False, True, 0)
|
||||
pathHBox.show()
|
||||
|
||||
paths = self.config.get_default_paths(site)
|
||||
params = self.config.get_site_parameters(site)
|
||||
self.createSiteLine(pathHBox, site, False, paths['hud-defaultPath'], params['converter'], params['enabled'])
|
||||
self.input_settings[site] = [paths['hud-defaultPath']] + [params['converter']]
|
||||
|
||||
if __name__== "__main__":
|
||||
def destroy(*args): # call back for terminating the main eventloop
|
||||
gtk.main_quit()
|
||||
|
||||
settings = {}
|
||||
settings['db-host'] = "192.168.1.100"
|
||||
settings['db-user'] = "mythtv"
|
||||
settings['db-password'] = "mythtv"
|
||||
settings['db-databaseName'] = "fpdb"
|
||||
settings['hud-defaultInterval'] = 10
|
||||
settings['hud-defaultPath'] = 'C:/Program Files/PokerStars/HandHistory/nutOmatic'
|
||||
settings['callFpdbHud'] = True
|
||||
|
||||
i = GuiAutoImport(settings)
|
||||
main_window = gtk.Window()
|
||||
main_window.connect("destroy", destroy)
|
||||
main_window.add(i.mainVBox)
|
||||
main_window.show()
|
||||
gtk.main()
|
||||
|
|
|
@ -87,16 +87,20 @@ class GuiGraphViewer (threading.Thread):
|
|||
#end of def showClicked
|
||||
|
||||
def getRingProfitGraph(self, name, site):
|
||||
self.cursor.execute(self.sql.query['getRingWinningsAllGamesPlayerIdSite'], (name, site))
|
||||
#self.cursor.execute(self.sql.query['getRingWinningsAllGamesPlayerIdSite'], (name, site))
|
||||
self.cursor.execute(self.sql.query['getRingProfitAllHandsPlayerIdSite'], (name, site))
|
||||
# returns (HandId,Winnings,Costs,Profit)
|
||||
winnings = self.db.cursor.fetchall()
|
||||
|
||||
profit=range(len(winnings))
|
||||
for i in profit:
|
||||
self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site))
|
||||
spent = self.db.cursor.fetchone()
|
||||
profit[i]=(i, winnings[i][1]-spent[0])
|
||||
#profit=range(len(winnings))
|
||||
#for i in profit:
|
||||
# self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site))
|
||||
# spent = self.db.cursor.fetchone()
|
||||
# profit[i]=(i, winnings[i][1]-spent[0])
|
||||
|
||||
#y=map(lambda x:float(x[1]), profit)
|
||||
y=map(lambda x:float(x[3]), winnings)
|
||||
|
||||
y=map(lambda x:float(x[1]), profit)
|
||||
line = cumsum(y)
|
||||
return line/100
|
||||
#end of def getRingProfitGraph
|
||||
|
|
337
pyfpdb/HUD_main.py
Executable file → Normal file
337
pyfpdb/HUD_main.py
Executable file → Normal file
|
@ -1,166 +1,171 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""Hud_main.py
|
||||
|
||||
Main for FreePokerTools HUD.
|
||||
"""
|
||||
# Copyright 2008, Ray E. Barker
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
########################################################################
|
||||
|
||||
# to do kill window on my seat
|
||||
# to do adjust for preferred seat
|
||||
# to do allow window resizing
|
||||
# to do hud to echo, but ignore non numbers
|
||||
# to do no hud window for hero
|
||||
# to do things to add to config.xml
|
||||
# to do font and size
|
||||
# to do opacity
|
||||
|
||||
# Standard Library modules
|
||||
import sys
|
||||
import os
|
||||
import thread
|
||||
import time
|
||||
import string
|
||||
import re
|
||||
|
||||
errorfile = open('HUD-error.txt', 'w', 0)
|
||||
sys.stderr = errorfile
|
||||
|
||||
# pyGTK modules
|
||||
import pygtk
|
||||
import gtk
|
||||
import gobject
|
||||
|
||||
# FreePokerTools modules
|
||||
import Configuration
|
||||
import Database
|
||||
import Tables
|
||||
import Hud
|
||||
|
||||
# global dict for keeping the huds
|
||||
hud_dict = {}
|
||||
|
||||
db_connection = 0;
|
||||
config = 0;
|
||||
|
||||
def destroy(*args): # call back for terminating the main eventloop
|
||||
gtk.main_quit()
|
||||
|
||||
def create_HUD(new_hand_id, table, db_name, table_name, max, poker_game, db_connection, config, stat_dict):
|
||||
global hud_dict
|
||||
def idle_func():
|
||||
global hud_dict
|
||||
gtk.gdk.threads_enter()
|
||||
try:
|
||||
hud_dict[table_name] = Hud.Hud(table, max, poker_game, config, db_name)
|
||||
hud_dict[table_name].create(new_hand_id, config)
|
||||
hud_dict[table_name].update(new_hand_id, config, stat_dict)
|
||||
hud_dict[table_name].reposition_windows()
|
||||
return False
|
||||
finally:
|
||||
gtk.gdk.threads_leave()
|
||||
gobject.idle_add(idle_func)
|
||||
|
||||
def update_HUD(new_hand_id, table_name, config, stat_dict):
|
||||
global hud_dict
|
||||
def idle_func():
|
||||
gtk.gdk.threads_enter()
|
||||
try:
|
||||
hud_dict[table_name].update(new_hand_id, config, stat_dict)
|
||||
return False
|
||||
finally:
|
||||
gtk.gdk.threads_leave()
|
||||
gobject.idle_add(idle_func)
|
||||
|
||||
def read_stdin(): # This is the thread function
|
||||
global hud_dict
|
||||
|
||||
db_connection = Database.Database(config, db_name, 'temp')
|
||||
# tourny_finder = re.compile('(\d+) (\d+)')
|
||||
|
||||
while True: # wait for a new hand number on stdin
|
||||
new_hand_id = sys.stdin.readline()
|
||||
new_hand_id = string.rstrip(new_hand_id)
|
||||
if new_hand_id == "": # blank line means quit
|
||||
destroy()
|
||||
|
||||
# delete hud_dict entries for any HUD destroyed since last iteration
|
||||
for h in hud_dict.keys():
|
||||
if hud_dict[h].deleted:
|
||||
del(hud_dict[h])
|
||||
|
||||
# get basic info about the new hand from the db
|
||||
(table_name, max, poker_game) = db_connection.get_table_name(new_hand_id)
|
||||
|
||||
# find out if this hand is from a tournament
|
||||
is_tournament = False
|
||||
# (t_number, s_number) = (0, 0)
|
||||
# mat_obj = tourny_finder(table_name)
|
||||
# if len(mat_obj.groups) == 2:
|
||||
# is_tournament = True
|
||||
# (t_number, s_number) = mat_obj.group(1, 2)
|
||||
|
||||
stat_dict = db_connection.get_stats_from_hand(new_hand_id)
|
||||
|
||||
# if a hud for this CASH table exists, just update it
|
||||
if hud_dict.has_key(table_name):
|
||||
update_HUD(new_hand_id, table_name, config, stat_dict)
|
||||
# if a hud for this TOURNAMENT table exists, just update it
|
||||
# elif hud_dict.has_key(t_number):
|
||||
# update_HUD(new_hand_id, t_number, config, stat_dict)
|
||||
# otherwise create a new hud
|
||||
else:
|
||||
if is_tournament:
|
||||
tablewindow = Tables.discover_tournament_table(config, t_number, s_number)
|
||||
if tablewindow == None:
|
||||
sys.stderr.write("table name "+table_name+" not found\n")
|
||||
else:
|
||||
create_HUD(new_hand_id, tablewindow, db_name, t_number, max, poker_game, db_connection, config, stat_dict)
|
||||
else:
|
||||
tablewindow = Tables.discover_table_by_name(config, table_name)
|
||||
if tablewindow == None:
|
||||
sys.stderr.write("table name "+table_name+" not found\n")
|
||||
else:
|
||||
create_HUD(new_hand_id, tablewindow, db_name, table_name, max, poker_game, db_connection, config, stat_dict)
|
||||
|
||||
if __name__== "__main__":
|
||||
sys.stderr.write("HUD_main starting\n")
|
||||
|
||||
try:
|
||||
db_name = sys.argv[1]
|
||||
except:
|
||||
db_name = 'fpdb'
|
||||
sys.stderr.write("Using db name = %s\n" % (db_name))
|
||||
|
||||
config = Configuration.Config()
|
||||
|
||||
gobject.threads_init() # this is required
|
||||
thread.start_new_thread(read_stdin, ()) # starts the thread
|
||||
|
||||
main_window = gtk.Window()
|
||||
main_window.connect("destroy", destroy)
|
||||
eb = gtk.EventBox()
|
||||
label = gtk.Label('Closing this window will exit from the HUD.')
|
||||
eb.add(label)
|
||||
main_window.add(eb)
|
||||
main_window.set_title("HUD Main Window")
|
||||
main_window.show_all()
|
||||
|
||||
gtk.main()
|
||||
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""Hud_main.py
|
||||
|
||||
Main for FreePokerTools HUD.
|
||||
"""
|
||||
# Copyright 2008, Ray E. Barker
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
########################################################################
|
||||
|
||||
# to do kill window on my seat
|
||||
# to do adjust for preferred seat
|
||||
# to do allow window resizing
|
||||
# to do hud to echo, but ignore non numbers
|
||||
# to do no hud window for hero
|
||||
# to do things to add to config.xml
|
||||
# to do font and size
|
||||
# to do opacity
|
||||
|
||||
# Standard Library modules
|
||||
import sys
|
||||
import os
|
||||
import thread
|
||||
import time
|
||||
import string
|
||||
import re
|
||||
|
||||
errorfile = open('HUD-error.txt', 'w', 0)
|
||||
sys.stderr = errorfile
|
||||
|
||||
# pyGTK modules
|
||||
import pygtk
|
||||
import gtk
|
||||
import gobject
|
||||
|
||||
# FreePokerTools modules
|
||||
import Configuration
|
||||
import Database
|
||||
import Tables
|
||||
import Hud
|
||||
|
||||
# global dict for keeping the huds
|
||||
hud_dict = {}
|
||||
|
||||
db_connection = 0;
|
||||
config = 0;
|
||||
|
||||
def destroy(*args): # call back for terminating the main eventloop
|
||||
gtk.main_quit()
|
||||
|
||||
def create_HUD(new_hand_id, table, db_name, table_name, max, poker_game, db_connection, config, stat_dict):
|
||||
global hud_dict
|
||||
def idle_func():
|
||||
global hud_dict
|
||||
gtk.gdk.threads_enter()
|
||||
try:
|
||||
hud_dict[table_name] = Hud.Hud(table, max, poker_game, config, db_name)
|
||||
hud_dict[table_name].create(new_hand_id, config)
|
||||
hud_dict[table_name].update(new_hand_id, config, stat_dict)
|
||||
hud_dict[table_name].reposition_windows()
|
||||
return False
|
||||
finally:
|
||||
gtk.gdk.threads_leave()
|
||||
gobject.idle_add(idle_func)
|
||||
|
||||
def update_HUD(new_hand_id, table_name, config, stat_dict):
|
||||
global hud_dict
|
||||
def idle_func():
|
||||
gtk.gdk.threads_enter()
|
||||
try:
|
||||
hud_dict[table_name].update(new_hand_id, config, stat_dict)
|
||||
for m in hud_dict[table_name].aux_windows:
|
||||
m.update_gui(new_hand_id)
|
||||
return False
|
||||
finally:
|
||||
gtk.gdk.threads_leave()
|
||||
gobject.idle_add(idle_func)
|
||||
|
||||
def read_stdin(): # This is the thread function
|
||||
global hud_dict
|
||||
|
||||
db_connection = Database.Database(config, db_name, 'temp')
|
||||
tourny_finder = re.compile('(\d+) (\d+)')
|
||||
|
||||
while True: # wait for a new hand number on stdin
|
||||
new_hand_id = sys.stdin.readline()
|
||||
new_hand_id = string.rstrip(new_hand_id)
|
||||
if new_hand_id == "": # blank line means quit
|
||||
destroy()
|
||||
|
||||
# delete hud_dict entries for any HUD destroyed since last iteration
|
||||
for h in hud_dict.keys():
|
||||
if hud_dict[h].deleted:
|
||||
del(hud_dict[h])
|
||||
|
||||
# get basic info about the new hand from the db
|
||||
(table_name, max, poker_game) = db_connection.get_table_name(new_hand_id)
|
||||
|
||||
# find out if this hand is from a tournament
|
||||
is_tournament = False
|
||||
(tour_number, tab_number) = (0, 0)
|
||||
mat_obj = tourny_finder.search(table_name)
|
||||
# if len(mat_obj.groups) == 2:
|
||||
if mat_obj:
|
||||
is_tournament = True
|
||||
(tour_number, tab_number) = mat_obj.group(1, 2)
|
||||
|
||||
stat_dict = db_connection.get_stats_from_hand(new_hand_id)
|
||||
|
||||
# if a hud for this CASH table exists, just update it
|
||||
if hud_dict.has_key(table_name):
|
||||
# update the data for the aux_windows
|
||||
for aw in hud_dict[table_name].aux_windows:
|
||||
aw.update_data(new_hand_id)
|
||||
update_HUD(new_hand_id, table_name, config, stat_dict)
|
||||
# if a hud for this TOURNAMENT table exists, just update it
|
||||
elif hud_dict.has_key(tour_number):
|
||||
update_HUD(new_hand_id, tour_number, config, stat_dict)
|
||||
# otherwise create a new hud
|
||||
else:
|
||||
if is_tournament:
|
||||
tablewindow = Tables.discover_tournament_table(config, tour_number, tab_number)
|
||||
if tablewindow == None:
|
||||
sys.stderr.write("tournament %s, table %s not found\n" % (tour_number, tab_number))
|
||||
else:
|
||||
create_HUD(new_hand_id, tablewindow, db_name, tour_number, max, poker_game, db_connection, config, stat_dict)
|
||||
else:
|
||||
tablewindow = Tables.discover_table_by_name(config, table_name)
|
||||
if tablewindow == None:
|
||||
sys.stderr.write("table name "+table_name+" not found\n")
|
||||
else:
|
||||
create_HUD(new_hand_id, tablewindow, db_name, table_name, max, poker_game, db_connection, config, stat_dict)
|
||||
|
||||
if __name__== "__main__":
|
||||
sys.stderr.write("HUD_main starting\n")
|
||||
|
||||
try:
|
||||
db_name = sys.argv[1]
|
||||
except:
|
||||
db_name = 'fpdb'
|
||||
sys.stderr.write("Using db name = %s\n" % (db_name))
|
||||
|
||||
config = Configuration.Config()
|
||||
|
||||
gobject.threads_init() # this is required
|
||||
thread.start_new_thread(read_stdin, ()) # starts the thread
|
||||
|
||||
main_window = gtk.Window()
|
||||
main_window.connect("destroy", destroy)
|
||||
eb = gtk.EventBox()
|
||||
label = gtk.Label('Closing this window will exit from the HUD.')
|
||||
eb.add(label)
|
||||
main_window.add(eb)
|
||||
main_window.set_title("HUD Main Window")
|
||||
main_window.show_all()
|
||||
|
||||
gtk.main()
|
||||
|
|
1140
pyfpdb/Hud.py
1140
pyfpdb/Hud.py
File diff suppressed because it is too large
Load Diff
|
@ -229,14 +229,21 @@ class Sql:
|
|||
sum(street3CheckCallRaiseDone) AS ccr_3,
|
||||
sum(street4CheckCallRaiseChance) AS ccr_opp_4,
|
||||
sum(street4CheckCallRaiseDone) AS ccr_4
|
||||
FROM HudCache, Hands
|
||||
WHERE HudCache.PlayerId in
|
||||
(SELECT PlayerId FROM HandsPlayers
|
||||
WHERE handId = %s)
|
||||
AND Hands.id = %s
|
||||
AND Hands.gametypeId = HudCache.gametypeId
|
||||
FROM Hands
|
||||
INNER JOIN HandsPlayers ON (HandsPlayers.handId = %s)
|
||||
INNER JOIN HudCache ON ( HudCache.PlayerId = HandsPlayers.PlayerId+0
|
||||
AND HudCache.gametypeId+0 = Hands.gametypeId+0)
|
||||
WHERE Hands.id = %s
|
||||
GROUP BY HudCache.PlayerId
|
||||
"""
|
||||
|
||||
# FROM HudCache, Hands
|
||||
# WHERE HudCache.PlayerId in
|
||||
# (SELECT PlayerId FROM HandsPlayers
|
||||
# WHERE handId = %s)
|
||||
# AND Hands.id = %s
|
||||
# AND Hands.gametypeId = HudCache.gametypeId
|
||||
|
||||
# AND PlayerId LIKE %s
|
||||
# HudCache.gametypeId AS gametypeId,
|
||||
# activeSeats AS n_active,
|
||||
|
|
110
pyfpdb/Stats.py
110
pyfpdb/Stats.py
|
@ -71,6 +71,7 @@ def do_stat(stat_dict, player = 24, stat = 'vpip'):
|
|||
# functions that return individual stats
|
||||
|
||||
def playername(stat_dict, player):
|
||||
""" Player Name."""
|
||||
return (stat_dict[player]['screen_name'],
|
||||
stat_dict[player]['screen_name'],
|
||||
stat_dict[player]['screen_name'],
|
||||
|
@ -98,6 +99,26 @@ def vpip(stat_dict, player):
|
|||
'wtsd'
|
||||
)
|
||||
|
||||
def vpip_0(stat_dict, player):
|
||||
""" Voluntarily put $ in the pot (no decimals)."""
|
||||
stat = 0.0
|
||||
try:
|
||||
stat = float(stat_dict[player]['vpip'])/float(stat_dict[player]['n'])
|
||||
return (stat,
|
||||
'%2.0f' % (100*stat) + '%',
|
||||
'v=%2.0f' % (100*stat) + '%',
|
||||
'vpip=%2.0f' % (100*stat) + '%',
|
||||
'(%d/%d)' % (stat_dict[player]['vpip'], stat_dict[player]['n']),
|
||||
'vpip'
|
||||
)
|
||||
except: return (stat,
|
||||
'%2.0f' % (0) + '%',
|
||||
'w=%2.0f' % (0) + '%',
|
||||
'wtsd=%2.0f' % (0) + '%',
|
||||
'(%d/%d)' % (0, 0),
|
||||
'wtsd'
|
||||
)
|
||||
|
||||
def pfr(stat_dict, player):
|
||||
""" Preflop (3rd street) raise."""
|
||||
stat = 0.0
|
||||
|
@ -119,6 +140,27 @@ def pfr(stat_dict, player):
|
|||
'pfr'
|
||||
)
|
||||
|
||||
def pfr_0(stat_dict, player):
|
||||
""" Preflop (3rd street) raise (no decimals)."""
|
||||
stat = 0.0
|
||||
try:
|
||||
stat = float(stat_dict[player]['pfr'])/float(stat_dict[player]['n'])
|
||||
return (stat,
|
||||
'%2.0f' % (100*stat) + '%',
|
||||
'p=%2.0f' % (100*stat) + '%',
|
||||
'pfr=%2.0f' % (100*stat) + '%',
|
||||
'(%d/%d)' % (stat_dict[player]['pfr'], stat_dict[player]['n']),
|
||||
'pfr'
|
||||
)
|
||||
except:
|
||||
return (stat,
|
||||
'%2.0f' % (0) + '%',
|
||||
'p=%2.0f' % (0) + '%',
|
||||
'pfr=%2.0f' % (0) + '%',
|
||||
'(%d/%d)' % (0, 0),
|
||||
'pfr'
|
||||
)
|
||||
|
||||
def wtsd(stat_dict, player):
|
||||
""" Went to SD when saw flop/4th."""
|
||||
stat = 0.0
|
||||
|
@ -149,7 +191,7 @@ def wmsd(stat_dict, player):
|
|||
'%3.1f' % (100*stat) + '%',
|
||||
'w=%3.1f' % (100*stat) + '%',
|
||||
'wmsd=%3.1f' % (100*stat) + '%',
|
||||
'(%f5.0/%d)' % (stat_dict[player]['wmsd'], stat_dict[player]['sd']),
|
||||
'(%5.1f/%d)' % (float(stat_dict[player]['wmsd']), stat_dict[player]['sd']),
|
||||
'% won money at showdown'
|
||||
)
|
||||
except:
|
||||
|
@ -414,6 +456,61 @@ def a_freq_4(stat_dict, player):
|
|||
'(%d/%d)' % (0, 0),
|
||||
'Aggression Freq flop/4th'
|
||||
)
|
||||
|
||||
def a_freq_123(stat_dict, player):
|
||||
""" Post-Flop aggression frequency."""
|
||||
stat = 0.0
|
||||
try:
|
||||
stat = float( stat_dict[player]['aggr_1'] + stat_dict[player]['aggr_2'] + stat_dict[player]['aggr_3']
|
||||
) / float( stat_dict[player]['saw_1'] + stat_dict[player]['saw_2'] + stat_dict[player]['saw_3']);
|
||||
return (stat,
|
||||
'%3.1f' % (100*stat) + '%',
|
||||
'afq=%3.1f' % (100*stat) + '%',
|
||||
'postf_aggfq=%3.1f' % (100*stat) + '%',
|
||||
'(%d/%d)' % ( stat_dict[player]['aggr_1']
|
||||
+ stat_dict[player]['aggr_2']
|
||||
+ stat_dict[player]['aggr_3']
|
||||
, stat_dict[player]['saw_1']
|
||||
+ stat_dict[player]['saw_2']
|
||||
+ stat_dict[player]['saw_3']
|
||||
),
|
||||
'Post-Flop Aggression Freq'
|
||||
)
|
||||
except:
|
||||
return (stat,
|
||||
'%2.0f' % (0) + '%',
|
||||
'a3=%2.0f' % (0) + '%',
|
||||
'a_fq_3=%2.0f' % (0) + '%',
|
||||
'(%d/%d)' % (0, 0),
|
||||
'Post-Flop Aggression Freq'
|
||||
)
|
||||
|
||||
def a_freq_123_0(stat_dict, player):
|
||||
""" Post-Flop aggression frequency (no decimals)."""
|
||||
stat = 0.0
|
||||
try:
|
||||
stat = float( stat_dict[player]['aggr_1'] + stat_dict[player]['aggr_2'] + stat_dict[player]['aggr_3']) / float( stat_dict[player]['saw_1'] + stat_dict[player]['saw_2'] + stat_dict[player]['saw_3']);
|
||||
return (stat,
|
||||
'%2.0f' % (100*stat) + '%',
|
||||
'afq=%2.0f' % (100*stat) + '%',
|
||||
'postf_aggfq=%2.0f' % (100*stat) + '%',
|
||||
'(%d/%d)' % ( stat_dict[player]['aggr_1']
|
||||
+ stat_dict[player]['aggr_2']
|
||||
+ stat_dict[player]['aggr_3']
|
||||
, stat_dict[player]['saw_1']
|
||||
+ stat_dict[player]['saw_2']
|
||||
+ stat_dict[player]['saw_3']
|
||||
),
|
||||
'Post-Flop Aggression Freq'
|
||||
)
|
||||
except:
|
||||
return (stat,
|
||||
'%2.0f' % (0) + '%',
|
||||
'a3=%2.0f' % (0) + '%',
|
||||
'a_fq_3=%2.0f' % (0) + '%',
|
||||
'(%d/%d)' % (0, 0),
|
||||
'Post-Flop Aggression Freq'
|
||||
)
|
||||
|
||||
def cb_1(stat_dict, player):
|
||||
""" Flop continuation bet."""
|
||||
|
@ -591,7 +688,9 @@ if __name__== "__main__":
|
|||
|
||||
for player in stat_dict.keys():
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'vpip')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'vpip_0')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'pfr')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'pfr_0')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'wtsd')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'saw_f')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'n')
|
||||
|
@ -606,6 +705,8 @@ if __name__== "__main__":
|
|||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_2')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_3')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_4')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_123')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_123_0')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_1')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_2')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb_3')
|
||||
|
@ -613,7 +714,8 @@ if __name__== "__main__":
|
|||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_1')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_2')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_3')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_4')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'ffreq_4')
|
||||
print "\n"
|
||||
|
||||
print "\n\nLegal stats:"
|
||||
for attr in dir():
|
||||
|
@ -621,8 +723,8 @@ if __name__== "__main__":
|
|||
if attr in ("Configuration", "Database", "GInitiallyUnowned", "gtk", "pygtk",
|
||||
"player", "c", "db_connection", "do_stat", "do_tip", "stat_dict",
|
||||
"h"): continue
|
||||
print attr, eval("%s.__doc__" % (attr))
|
||||
print "%-14s %s" % (attr, eval("%s.__doc__" % (attr)))
|
||||
# print " <pu_stat pu_stat_name = \"%s\"> </pu_stat>" % (attr)
|
||||
|
||||
db_connection.close
|
||||
db_connection.close_connection
|
||||
|
||||
|
|
898
pyfpdb/fpdb.py
Executable file → Normal file
898
pyfpdb/fpdb.py
Executable file → Normal file
|
@ -1,449 +1,449 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#Copyright 2008 Steffen Jobbagy-Felso
|
||||
#This program is free software: you can redistribute it and/or modify
|
||||
#it under the terms of the GNU Affero General Public License as published by
|
||||
#the Free Software Foundation, version 3 of the License.
|
||||
#
|
||||
#This program is distributed in the hope that it will be useful,
|
||||
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
#GNU General Public License for more details.
|
||||
#
|
||||
#You should have received a copy of the GNU Affero General Public License
|
||||
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#In the "official" distribution you can find the license in
|
||||
#agpl-3.0.txt in the docs folder of the package.
|
||||
|
||||
import os
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option("-x", "--errorsToConsole", action="store_true",
|
||||
help="If passed error output will go to the console rather than .")
|
||||
(options, sys.argv) = parser.parse_args()
|
||||
|
||||
if not options.errorsToConsole:
|
||||
print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_."
|
||||
errorFile = open('fpdb-error-log.txt', 'w', 0)
|
||||
sys.stderr = errorFile
|
||||
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk
|
||||
|
||||
import fpdb_db
|
||||
import fpdb_simple
|
||||
import GuiBulkImport
|
||||
import GuiTableViewer
|
||||
import GuiAutoImport
|
||||
import GuiGraphViewer
|
||||
import FpdbSQLQueries
|
||||
import Configuration
|
||||
|
||||
class fpdb:
|
||||
def tab_clicked(self, widget, tab_name):
|
||||
"""called when a tab button is clicked to activate that tab"""
|
||||
#print "start of tab_clicked"
|
||||
self.display_tab(tab_name)
|
||||
#end def tab_clicked
|
||||
|
||||
def add_and_display_tab(self, new_tab, new_tab_name):
|
||||
"""just calls the component methods"""
|
||||
self.add_tab(new_tab, new_tab_name)
|
||||
self.display_tab(new_tab_name)
|
||||
#end def add_and_display_tab
|
||||
|
||||
def add_tab(self, new_tab, new_tab_name):
|
||||
"""adds a tab, namely creates the button and displays it and appends all the relevant arrays"""
|
||||
#print "start of add_tab"
|
||||
for i in self.tab_names: #todo: check this is valid
|
||||
if i==new_tab_name:
|
||||
raise fpdb_simple.FpdbError("duplicate tab_name not permitted")
|
||||
|
||||
self.tabs.append(new_tab)
|
||||
self.tab_names.append(new_tab_name)
|
||||
|
||||
new_tab_sel_button=gtk.ToggleButton(new_tab_name)
|
||||
new_tab_sel_button.connect("clicked", self.tab_clicked, new_tab_name)
|
||||
self.tab_box.add(new_tab_sel_button)
|
||||
new_tab_sel_button.show()
|
||||
self.tab_buttons.append(new_tab_sel_button)
|
||||
#end def add_tab
|
||||
|
||||
def display_tab(self, new_tab_name):
|
||||
"""displays the indicated tab"""
|
||||
#print "start of display_tab, len(self.tab_names):",len(self.tab_names)
|
||||
tab_no=-1
|
||||
#if len(self.tab_names)>1:
|
||||
for i in range(len(self.tab_names)):
|
||||
#print "display_tab, new_tab_name:",new_tab_name," self.tab_names[i]:", self.tab_names[i]
|
||||
if (new_tab_name==self.tab_names[i]):
|
||||
tab_no=i
|
||||
#self.tab_buttons[i].set_active(False)
|
||||
#else:
|
||||
# tab_no=0
|
||||
|
||||
#current_tab_no=-1
|
||||
for i in range(len(self.tab_names)):
|
||||
if self.current_tab==self.tabs[i]:
|
||||
#self.tab_buttons[i].set_active(False)
|
||||
pass
|
||||
|
||||
if tab_no==-1:
|
||||
raise fpdb_simple.FpdbError("invalid tab_no")
|
||||
else:
|
||||
self.main_vbox.remove(self.current_tab)
|
||||
#self.current_tab.destroy()
|
||||
self.current_tab=self.tabs[tab_no]
|
||||
self.main_vbox.add(self.current_tab)
|
||||
self.tab_buttons[tab_no].set_active(True)
|
||||
self.current_tab.show()
|
||||
#end def display_tab
|
||||
|
||||
def delete_event(self, widget, event, data=None):
|
||||
return False
|
||||
#end def delete_event
|
||||
|
||||
def destroy(self, widget, data=None):
|
||||
self.quit(widget, data)
|
||||
#end def destroy
|
||||
|
||||
def dia_about(self, widget, data):
|
||||
print "todo: implement dia_about"
|
||||
#end def dia_about
|
||||
|
||||
def dia_create_del_database(self, widget, data):
|
||||
print "todo: implement dia_create_del_database"
|
||||
obtain_global_lock()
|
||||
#end def dia_create_del_database
|
||||
|
||||
def dia_create_del_user(self, widget, data):
|
||||
print "todo: implement dia_create_del_user"
|
||||
obtain_global_lock()
|
||||
#end def dia_create_del_user
|
||||
|
||||
def dia_database_stats(self, widget, data):
|
||||
print "todo: implement dia_database_stats"
|
||||
#string=fpdb_db.getDbStats(db, cursor)
|
||||
#end def dia_database_stats
|
||||
|
||||
def dia_delete_db_parts(self, widget, data):
|
||||
print "todo: implement dia_delete_db_parts"
|
||||
obtain_global_lock()
|
||||
#end def dia_delete_db_parts
|
||||
|
||||
def dia_edit_profile(self, widget=None, data=None, create_default=False, path=None):
|
||||
print "todo: implement dia_edit_profile"
|
||||
obtain_global_lock()
|
||||
#end def dia_edit_profile
|
||||
|
||||
def dia_export_db(self, widget, data):
|
||||
print "todo: implement dia_export_db"
|
||||
obtain_global_lock()
|
||||
#end def dia_export_db
|
||||
|
||||
def dia_get_db_root_credentials(self):
|
||||
"""obtains db root credentials from user"""
|
||||
print "todo: implement dia_get_db_root_credentials"
|
||||
# user, pw=None, None
|
||||
#
|
||||
# dialog=gtk.Dialog(title="DB Credentials needed", parent=None, flags=0,
|
||||
# buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,"Connect and recreate",gtk.RESPONSE_OK))
|
||||
#
|
||||
# label_warning1=gtk.Label("Please enter credentials for a database user for "+self.host+" that has permissions to create a database.")
|
||||
#
|
||||
#
|
||||
# label_user=gtk.Label("Username")
|
||||
# dialog.vbox.add(label_user)
|
||||
# label_user.show()
|
||||
#
|
||||
# response=dialog.run()
|
||||
# dialog.destroy()
|
||||
# return (user, pw, response)
|
||||
#end def dia_get_db_root_credentials
|
||||
|
||||
def dia_import_db(self, widget, data):
|
||||
print "todo: implement dia_import_db"
|
||||
obtain_global_lock()
|
||||
#end def dia_import_db
|
||||
|
||||
def dia_licensing(self, widget, data):
|
||||
print "todo: implement dia_licensing"
|
||||
#end def dia_licensing
|
||||
|
||||
def dia_load_profile(self, widget, data):
|
||||
"""Dialogue to select a file to load a profile from"""
|
||||
self.obtain_global_lock()
|
||||
chooser = gtk.FileChooserDialog(title="Please select a profile file to load",
|
||||
action=gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
|
||||
chooser.set_filename(self.profile)
|
||||
|
||||
response = chooser.run()
|
||||
chooser.destroy()
|
||||
if response == gtk.RESPONSE_OK:
|
||||
self.load_profile(chooser.get_filename())
|
||||
elif response == gtk.RESPONSE_CANCEL:
|
||||
print 'User cancelled loading profile'
|
||||
#end def dia_load_profile
|
||||
|
||||
def dia_recreate_tables(self, widget, data):
|
||||
"""Dialogue that asks user to confirm that he wants to delete and recreate the tables"""
|
||||
self.obtain_global_lock()
|
||||
dia_confirm=gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
|
||||
buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables")
|
||||
diastring=("Please confirm that you want to (re-)create the tables. If there already are tables in the database "+self.db.database+" on "+self.db.host+" they will be deleted.")
|
||||
dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted
|
||||
|
||||
response=dia_confirm.run()
|
||||
dia_confirm.destroy()
|
||||
if response == gtk.RESPONSE_YES:
|
||||
self.db.recreate_tables()
|
||||
elif response == gtk.RESPONSE_NO:
|
||||
print 'User cancelled recreating tables'
|
||||
#end def dia_recreate_tables
|
||||
|
||||
def dia_regression_test(self, widget, data):
|
||||
print "todo: implement dia_regression_test"
|
||||
self.obtain_global_lock()
|
||||
#end def dia_regression_test
|
||||
|
||||
def dia_save_profile(self, widget, data):
|
||||
print "todo: implement dia_save_profile"
|
||||
#end def dia_save_profile
|
||||
|
||||
def diaSetupWizard(self, path):
|
||||
print "todo: implement setup wizard"
|
||||
print "setup wizard not implemented - please create the default configuration file:", path
|
||||
diaSetupWizard = gtk.Dialog(title="Fatal Error - Config File Missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
|
||||
|
||||
label = gtk.Label("Please copy the config file from the docs folder to:")
|
||||
diaSetupWizard.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
label = gtk.Label(path)
|
||||
diaSetupWizard.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
label = gtk.Label("and edit it according to the install documentation at http://fpdb.sourceforge.net")
|
||||
diaSetupWizard.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
response = diaSetupWizard.run()
|
||||
sys.exit(1)
|
||||
#end def diaSetupWizard
|
||||
|
||||
def get_menu(self, window):
|
||||
"""returns the menu for this program"""
|
||||
accel_group = gtk.AccelGroup()
|
||||
self.item_factory = gtk.ItemFactory(gtk.MenuBar, "<main>", accel_group)
|
||||
self.item_factory.create_items(self.menu_items)
|
||||
window.add_accel_group(accel_group)
|
||||
return self.item_factory.get_widget("<main>")
|
||||
#end def get_menu
|
||||
|
||||
def load_profile(self):
|
||||
"""Loads profile from the provided path name."""
|
||||
self.settings = {}
|
||||
if (os.sep=="/"):
|
||||
self.settings['os']="linuxmac"
|
||||
else:
|
||||
self.settings['os']="windows"
|
||||
|
||||
self.settings.update(self.config.get_db_parameters())
|
||||
self.settings.update(self.config.get_tv_parameters())
|
||||
self.settings.update(self.config.get_import_parameters())
|
||||
self.settings.update(self.config.get_default_paths())
|
||||
|
||||
if self.db!=None:
|
||||
self.db.disconnect()
|
||||
|
||||
self.db = fpdb_db.fpdb_db()
|
||||
#print "end of fpdb.load_profile, databaseName:",self.settings['db-databaseName']
|
||||
self.db.connect(self.settings['db-backend'], self.settings['db-host'], self.settings['db-databaseName'], self.settings['db-user'], self.settings['db-password'])
|
||||
if self.db.wrongDbVersion:
|
||||
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
||||
|
||||
label = gtk.Label("An invalid DB version or missing tables have been detected.")
|
||||
diaDbVersionWarning.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
label = gtk.Label("This error is not necessarily fatal but it is strongly recommended that you recreate the tables by using the Database menu.")
|
||||
diaDbVersionWarning.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
label = gtk.Label("Not doing this will likely lead to misbehaviour including fpdb crashes, corrupt data etc.")
|
||||
diaDbVersionWarning.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
response = diaDbVersionWarning.run()
|
||||
diaDbVersionWarning.destroy()
|
||||
|
||||
# Database connected to successfully, load queries to pass on to other classes
|
||||
self.querydict = FpdbSQLQueries.FpdbSQLQueries(self.db.get_backend_name())
|
||||
#end def load_profile
|
||||
|
||||
def not_implemented(self):
|
||||
print "todo: called unimplemented menu entry (users: pls ignore this)"#remove this once more entries are implemented
|
||||
#end def not_implemented
|
||||
|
||||
def obtain_global_lock(self):
|
||||
print "todo: implement obtain_global_lock (users: pls ignore this)"
|
||||
#end def obtain_global_lock
|
||||
|
||||
def quit(self, widget, data):
|
||||
print "Quitting normally"
|
||||
#check if current settings differ from profile, if so offer to save or abort
|
||||
self.db.disconnect()
|
||||
gtk.main_quit()
|
||||
#end def quit_cliecked
|
||||
|
||||
def release_global_lock(self):
|
||||
print "todo: implement release_global_lock"
|
||||
#end def release_global_lock
|
||||
|
||||
def tab_abbreviations(self, widget, data):
|
||||
print "todo: implement tab_abbreviations"
|
||||
#end def tab_abbreviations
|
||||
|
||||
def tab_auto_import(self, widget, data):
|
||||
"""opens the auto import tab"""
|
||||
new_aimp_thread=GuiAutoImport.GuiAutoImport(self.settings, self.config)
|
||||
self.threads.append(new_aimp_thread)
|
||||
aimp_tab=new_aimp_thread.get_vbox()
|
||||
self.add_and_display_tab(aimp_tab, "Auto Import")
|
||||
#end def tab_auto_import
|
||||
|
||||
def tab_bulk_import(self, widget, data):
|
||||
"""opens a tab for bulk importing"""
|
||||
#print "start of tab_bulk_import"
|
||||
new_import_thread=GuiBulkImport.GuiBulkImport(self.db, self.settings, self.config)
|
||||
self.threads.append(new_import_thread)
|
||||
bulk_tab=new_import_thread.get_vbox()
|
||||
self.add_and_display_tab(bulk_tab, "Bulk Import")
|
||||
#end def tab_bulk_import
|
||||
|
||||
def tab_main_help(self, widget, data):
|
||||
"""Displays a tab with the main fpdb help screen"""
|
||||
#print "start of tab_main_help"
|
||||
mh_tab=gtk.Label("""Welcome to Fpdb!
|
||||
For documentation please visit our website at http://fpdb.sourceforge.net/ or check the docs directory in the fpdb folder.
|
||||
Please note that default.conf is no longer needed nor used, all configuration now happens in HUD_config.xml
|
||||
This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||
self.add_and_display_tab(mh_tab, "Help")
|
||||
#end def tab_main_help
|
||||
|
||||
def tab_table_viewer(self, widget, data):
|
||||
"""opens a table viewer tab"""
|
||||
#print "start of tab_table_viewer"
|
||||
new_tv_thread=GuiTableViewer.GuiTableViewer(self.db, self.settings)
|
||||
self.threads.append(new_tv_thread)
|
||||
tv_tab=new_tv_thread.get_vbox()
|
||||
self.add_and_display_tab(tv_tab, "Table Viewer")
|
||||
#end def tab_table_viewer
|
||||
|
||||
def tabGraphViewer(self, widget, data):
|
||||
"""opens a graph viewer tab"""
|
||||
#print "start of tabGraphViewer"
|
||||
new_gv_thread=GuiGraphViewer.GuiGraphViewer(self.db, self.settings, self.querydict, self.config)
|
||||
self.threads.append(new_gv_thread)
|
||||
gv_tab=new_gv_thread.get_vbox()
|
||||
self.add_and_display_tab(gv_tab, "Graphs")
|
||||
#end def tabGraphViewer
|
||||
|
||||
def __init__(self):
|
||||
self.threads=[]
|
||||
self.db=None
|
||||
self.config = Configuration.Config()
|
||||
self.load_profile()
|
||||
|
||||
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||
self.window.connect("delete_event", self.delete_event)
|
||||
self.window.connect("destroy", self.destroy)
|
||||
self.window.set_title("Free Poker DB - version: alpha9+, p143 or higher")
|
||||
self.window.set_border_width(1)
|
||||
self.window.set_size_request(1020,400)
|
||||
self.window.set_resizable(True)
|
||||
|
||||
self.menu_items = (
|
||||
( "/_Main", None, None, 0, "<Branch>" ),
|
||||
( "/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/_Save Profile (todo)", None, self.dia_save_profile, 0, None ),
|
||||
("/Main/sep1", None, None, 0, "<Separator>" ),
|
||||
("/Main/_Quit", "<control>Q", self.quit, 0, None ),
|
||||
("/_Import", None, None, 0, "<Branch>" ),
|
||||
("/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 _Rating (todo)", "<control>R", self.not_implemented, 0, None ),
|
||||
("/_Viewers", None, None, 0, "<Branch>" ),
|
||||
("/_Viewers/_Auto Import and HUD", "<control>A", self.tab_auto_import, 0, None ),
|
||||
("/Viewers/_Graphs", "<control>G", self.tabGraphViewer, 0, None ),
|
||||
("/Viewers/Hand _Replayer (todo)", None, self.not_implemented, 0, None ),
|
||||
("/Viewers/Player _Details (todo)", None, self.not_implemented, 0, None ),
|
||||
("/Viewers/_Player Stats (tabulated view) (todo)", None, self.not_implemented, 0, None ),
|
||||
("/Viewers/Starting _Hands (todo)", None, self.not_implemented, 0, None ),
|
||||
("/Viewers/_Session Replayer (todo)", None, self.not_implemented, 0, None ),
|
||||
("/Viewers/Poker_table Viewer (mostly obselete)", "<control>T", self.tab_table_viewer, 0, None ),
|
||||
#( "/Viewers/Tourney Replayer
|
||||
( "/_Database", None, None, 0, "<Branch>" ),
|
||||
( "/Database/Create or Delete _Database (todo)", None, self.dia_create_del_database, 0, None ),
|
||||
( "/Database/Create or Delete _User (todo)", None, self.dia_create_del_user, 0, None ),
|
||||
( "/Database/Create or Recreate _Tables", None, self.dia_recreate_tables, 0, None ),
|
||||
( "/Database/_Statistics (todo)", None, self.dia_database_stats, 0, None ),
|
||||
( "/D_ebugging", None, None, 0, "<Branch>" ),
|
||||
( "/Debugging/_Delete Parts of Database (todo)", None, self.dia_delete_db_parts, 0, None ),
|
||||
( "/Debugging/_Export DB (todo)", None, self.dia_export_db, 0, None ),
|
||||
( "/Debugging/_Import DB (todo)", None, self.dia_import_db, 0, None ),
|
||||
( "/Debugging/_Regression test (todo)", None, self.dia_regression_test, 0, None ),
|
||||
( "/_Help", None, None, 0, "<LastBranch>" ),
|
||||
( "/Help/_Main Help", "<control>H", self.tab_main_help, 0, None ),
|
||||
( "/Help/_Abbrevations (todo)", None, self.tab_abbreviations, 0, None ),
|
||||
( "/Help/sep1", None, None, 0, "<Separator>" ),
|
||||
( "/Help/A_bout (todo)", None, self.dia_about, 0, None ),
|
||||
( "/Help/_License and Copying (todo)", None, self.dia_licensing, 0, None )
|
||||
)
|
||||
|
||||
self.main_vbox = gtk.VBox(False, 1)
|
||||
self.main_vbox.set_border_width(1)
|
||||
self.window.add(self.main_vbox)
|
||||
self.main_vbox.show()
|
||||
|
||||
menubar = self.get_menu(self.window)
|
||||
self.main_vbox.pack_start(menubar, False, True, 0)
|
||||
menubar.show()
|
||||
#done menubar
|
||||
|
||||
self.tabs=[]
|
||||
self.tab_names=[]
|
||||
self.tab_buttons=[]
|
||||
self.tab_box = gtk.HBox(False,1)
|
||||
self.main_vbox.pack_start(self.tab_box, False, True, 0)
|
||||
self.tab_box.show()
|
||||
#done tab bar
|
||||
|
||||
self.current_tab = gtk.VBox(False,1)
|
||||
self.current_tab.set_border_width(1)
|
||||
self.main_vbox.add(self.current_tab)
|
||||
self.current_tab.show()
|
||||
|
||||
self.tab_main_help(None, None)
|
||||
|
||||
self.status_bar = gtk.Label("Status: Connected to "+self.db.get_backend_name()+" database named "+self.db.database+" on host "+self.db.host)
|
||||
self.main_vbox.pack_end(self.status_bar, False, True, 0)
|
||||
self.status_bar.show()
|
||||
|
||||
self.window.show()
|
||||
#end def __init__
|
||||
|
||||
def main(self):
|
||||
gtk.main()
|
||||
return 0
|
||||
#end def main
|
||||
|
||||
if __name__ == "__main__":
|
||||
me = fpdb()
|
||||
me.main()
|
||||
#!/usr/bin/python
|
||||
|
||||
#Copyright 2008 Steffen Jobbagy-Felso
|
||||
#This program is free software: you can redistribute it and/or modify
|
||||
#it under the terms of the GNU Affero General Public License as published by
|
||||
#the Free Software Foundation, version 3 of the License.
|
||||
#
|
||||
#This program is distributed in the hope that it will be useful,
|
||||
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
#GNU General Public License for more details.
|
||||
#
|
||||
#You should have received a copy of the GNU Affero General Public License
|
||||
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#In the "official" distribution you can find the license in
|
||||
#agpl-3.0.txt in the docs folder of the package.
|
||||
|
||||
import os
|
||||
import sys
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option("-x", "--errorsToConsole", action="store_true",
|
||||
help="If passed error output will go to the console rather than .")
|
||||
(options, sys.argv) = parser.parse_args()
|
||||
|
||||
if not options.errorsToConsole:
|
||||
print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_."
|
||||
errorFile = open('fpdb-error-log.txt', 'w', 0)
|
||||
sys.stderr = errorFile
|
||||
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
import gtk
|
||||
|
||||
import fpdb_db
|
||||
import fpdb_simple
|
||||
import GuiBulkImport
|
||||
import GuiTableViewer
|
||||
import GuiAutoImport
|
||||
import GuiGraphViewer
|
||||
import FpdbSQLQueries
|
||||
import Configuration
|
||||
|
||||
class fpdb:
|
||||
def tab_clicked(self, widget, tab_name):
|
||||
"""called when a tab button is clicked to activate that tab"""
|
||||
#print "start of tab_clicked"
|
||||
self.display_tab(tab_name)
|
||||
#end def tab_clicked
|
||||
|
||||
def add_and_display_tab(self, new_tab, new_tab_name):
|
||||
"""just calls the component methods"""
|
||||
self.add_tab(new_tab, new_tab_name)
|
||||
self.display_tab(new_tab_name)
|
||||
#end def add_and_display_tab
|
||||
|
||||
def add_tab(self, new_tab, new_tab_name):
|
||||
"""adds a tab, namely creates the button and displays it and appends all the relevant arrays"""
|
||||
#print "start of add_tab"
|
||||
for i in self.tab_names: #todo: check this is valid
|
||||
if i==new_tab_name:
|
||||
raise fpdb_simple.FpdbError("duplicate tab_name not permitted")
|
||||
|
||||
self.tabs.append(new_tab)
|
||||
self.tab_names.append(new_tab_name)
|
||||
|
||||
new_tab_sel_button=gtk.ToggleButton(new_tab_name)
|
||||
new_tab_sel_button.connect("clicked", self.tab_clicked, new_tab_name)
|
||||
self.tab_box.add(new_tab_sel_button)
|
||||
new_tab_sel_button.show()
|
||||
self.tab_buttons.append(new_tab_sel_button)
|
||||
#end def add_tab
|
||||
|
||||
def display_tab(self, new_tab_name):
|
||||
"""displays the indicated tab"""
|
||||
#print "start of display_tab, len(self.tab_names):",len(self.tab_names)
|
||||
tab_no=-1
|
||||
#if len(self.tab_names)>1:
|
||||
for i in range(len(self.tab_names)):
|
||||
#print "display_tab, new_tab_name:",new_tab_name," self.tab_names[i]:", self.tab_names[i]
|
||||
if (new_tab_name==self.tab_names[i]):
|
||||
tab_no=i
|
||||
#self.tab_buttons[i].set_active(False)
|
||||
#else:
|
||||
# tab_no=0
|
||||
|
||||
#current_tab_no=-1
|
||||
for i in range(len(self.tab_names)):
|
||||
if self.current_tab==self.tabs[i]:
|
||||
#self.tab_buttons[i].set_active(False)
|
||||
pass
|
||||
|
||||
if tab_no==-1:
|
||||
raise fpdb_simple.FpdbError("invalid tab_no")
|
||||
else:
|
||||
self.main_vbox.remove(self.current_tab)
|
||||
#self.current_tab.destroy()
|
||||
self.current_tab=self.tabs[tab_no]
|
||||
self.main_vbox.add(self.current_tab)
|
||||
self.tab_buttons[tab_no].set_active(True)
|
||||
self.current_tab.show()
|
||||
#end def display_tab
|
||||
|
||||
def delete_event(self, widget, event, data=None):
|
||||
return False
|
||||
#end def delete_event
|
||||
|
||||
def destroy(self, widget, data=None):
|
||||
self.quit(widget, data)
|
||||
#end def destroy
|
||||
|
||||
def dia_about(self, widget, data):
|
||||
print "todo: implement dia_about"
|
||||
#end def dia_about
|
||||
|
||||
def dia_create_del_database(self, widget, data):
|
||||
print "todo: implement dia_create_del_database"
|
||||
obtain_global_lock()
|
||||
#end def dia_create_del_database
|
||||
|
||||
def dia_create_del_user(self, widget, data):
|
||||
print "todo: implement dia_create_del_user"
|
||||
obtain_global_lock()
|
||||
#end def dia_create_del_user
|
||||
|
||||
def dia_database_stats(self, widget, data):
|
||||
print "todo: implement dia_database_stats"
|
||||
#string=fpdb_db.getDbStats(db, cursor)
|
||||
#end def dia_database_stats
|
||||
|
||||
def dia_delete_db_parts(self, widget, data):
|
||||
print "todo: implement dia_delete_db_parts"
|
||||
obtain_global_lock()
|
||||
#end def dia_delete_db_parts
|
||||
|
||||
def dia_edit_profile(self, widget=None, data=None, create_default=False, path=None):
|
||||
print "todo: implement dia_edit_profile"
|
||||
obtain_global_lock()
|
||||
#end def dia_edit_profile
|
||||
|
||||
def dia_export_db(self, widget, data):
|
||||
print "todo: implement dia_export_db"
|
||||
obtain_global_lock()
|
||||
#end def dia_export_db
|
||||
|
||||
def dia_get_db_root_credentials(self):
|
||||
"""obtains db root credentials from user"""
|
||||
print "todo: implement dia_get_db_root_credentials"
|
||||
# user, pw=None, None
|
||||
#
|
||||
# dialog=gtk.Dialog(title="DB Credentials needed", parent=None, flags=0,
|
||||
# buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,"Connect and recreate",gtk.RESPONSE_OK))
|
||||
#
|
||||
# label_warning1=gtk.Label("Please enter credentials for a database user for "+self.host+" that has permissions to create a database.")
|
||||
#
|
||||
#
|
||||
# label_user=gtk.Label("Username")
|
||||
# dialog.vbox.add(label_user)
|
||||
# label_user.show()
|
||||
#
|
||||
# response=dialog.run()
|
||||
# dialog.destroy()
|
||||
# return (user, pw, response)
|
||||
#end def dia_get_db_root_credentials
|
||||
|
||||
def dia_import_db(self, widget, data):
|
||||
print "todo: implement dia_import_db"
|
||||
obtain_global_lock()
|
||||
#end def dia_import_db
|
||||
|
||||
def dia_licensing(self, widget, data):
|
||||
print "todo: implement dia_licensing"
|
||||
#end def dia_licensing
|
||||
|
||||
def dia_load_profile(self, widget, data):
|
||||
"""Dialogue to select a file to load a profile from"""
|
||||
self.obtain_global_lock()
|
||||
chooser = gtk.FileChooserDialog(title="Please select a profile file to load",
|
||||
action=gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
|
||||
chooser.set_filename(self.profile)
|
||||
|
||||
response = chooser.run()
|
||||
chooser.destroy()
|
||||
if response == gtk.RESPONSE_OK:
|
||||
self.load_profile(chooser.get_filename())
|
||||
elif response == gtk.RESPONSE_CANCEL:
|
||||
print 'User cancelled loading profile'
|
||||
#end def dia_load_profile
|
||||
|
||||
def dia_recreate_tables(self, widget, data):
|
||||
"""Dialogue that asks user to confirm that he wants to delete and recreate the tables"""
|
||||
self.obtain_global_lock()
|
||||
dia_confirm=gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
|
||||
buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables")
|
||||
diastring=("Please confirm that you want to (re-)create the tables. If there already are tables in the database "+self.db.database+" on "+self.db.host+" they will be deleted.")
|
||||
dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted
|
||||
|
||||
response=dia_confirm.run()
|
||||
dia_confirm.destroy()
|
||||
if response == gtk.RESPONSE_YES:
|
||||
self.db.recreate_tables()
|
||||
elif response == gtk.RESPONSE_NO:
|
||||
print 'User cancelled recreating tables'
|
||||
#end def dia_recreate_tables
|
||||
|
||||
def dia_regression_test(self, widget, data):
|
||||
print "todo: implement dia_regression_test"
|
||||
self.obtain_global_lock()
|
||||
#end def dia_regression_test
|
||||
|
||||
def dia_save_profile(self, widget, data):
|
||||
print "todo: implement dia_save_profile"
|
||||
#end def dia_save_profile
|
||||
|
||||
def diaSetupWizard(self, path):
|
||||
print "todo: implement setup wizard"
|
||||
print "setup wizard not implemented - please create the default configuration file:", path
|
||||
diaSetupWizard = gtk.Dialog(title="Fatal Error - Config File Missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
|
||||
|
||||
label = gtk.Label("Please copy the config file from the docs folder to:")
|
||||
diaSetupWizard.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
label = gtk.Label(path)
|
||||
diaSetupWizard.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
label = gtk.Label("and edit it according to the install documentation at http://fpdb.sourceforge.net")
|
||||
diaSetupWizard.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
response = diaSetupWizard.run()
|
||||
sys.exit(1)
|
||||
#end def diaSetupWizard
|
||||
|
||||
def get_menu(self, window):
|
||||
"""returns the menu for this program"""
|
||||
accel_group = gtk.AccelGroup()
|
||||
self.item_factory = gtk.ItemFactory(gtk.MenuBar, "<main>", accel_group)
|
||||
self.item_factory.create_items(self.menu_items)
|
||||
window.add_accel_group(accel_group)
|
||||
return self.item_factory.get_widget("<main>")
|
||||
#end def get_menu
|
||||
|
||||
def load_profile(self):
|
||||
"""Loads profile from the provided path name."""
|
||||
self.settings = {}
|
||||
if (os.sep=="/"):
|
||||
self.settings['os']="linuxmac"
|
||||
else:
|
||||
self.settings['os']="windows"
|
||||
|
||||
self.settings.update(self.config.get_db_parameters())
|
||||
self.settings.update(self.config.get_tv_parameters())
|
||||
self.settings.update(self.config.get_import_parameters())
|
||||
self.settings.update(self.config.get_default_paths())
|
||||
|
||||
if self.db!=None:
|
||||
self.db.disconnect()
|
||||
|
||||
self.db = fpdb_db.fpdb_db()
|
||||
#print "end of fpdb.load_profile, databaseName:",self.settings['db-databaseName']
|
||||
self.db.connect(self.settings['db-backend'], self.settings['db-host'], self.settings['db-databaseName'], self.settings['db-user'], self.settings['db-password'])
|
||||
if self.db.wrongDbVersion:
|
||||
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
||||
|
||||
label = gtk.Label("An invalid DB version or missing tables have been detected.")
|
||||
diaDbVersionWarning.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
label = gtk.Label("This error is not necessarily fatal but it is strongly recommended that you recreate the tables by using the Database menu.")
|
||||
diaDbVersionWarning.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
label = gtk.Label("Not doing this will likely lead to misbehaviour including fpdb crashes, corrupt data etc.")
|
||||
diaDbVersionWarning.vbox.add(label)
|
||||
label.show()
|
||||
|
||||
response = diaDbVersionWarning.run()
|
||||
diaDbVersionWarning.destroy()
|
||||
|
||||
# Database connected to successfully, load queries to pass on to other classes
|
||||
self.querydict = FpdbSQLQueries.FpdbSQLQueries(self.db.get_backend_name())
|
||||
#end def load_profile
|
||||
|
||||
def not_implemented(self):
|
||||
print "todo: called unimplemented menu entry (users: pls ignore this)"#remove this once more entries are implemented
|
||||
#end def not_implemented
|
||||
|
||||
def obtain_global_lock(self):
|
||||
print "todo: implement obtain_global_lock (users: pls ignore this)"
|
||||
#end def obtain_global_lock
|
||||
|
||||
def quit(self, widget, data):
|
||||
print "Quitting normally"
|
||||
#check if current settings differ from profile, if so offer to save or abort
|
||||
self.db.disconnect()
|
||||
gtk.main_quit()
|
||||
#end def quit_cliecked
|
||||
|
||||
def release_global_lock(self):
|
||||
print "todo: implement release_global_lock"
|
||||
#end def release_global_lock
|
||||
|
||||
def tab_abbreviations(self, widget, data):
|
||||
print "todo: implement tab_abbreviations"
|
||||
#end def tab_abbreviations
|
||||
|
||||
def tab_auto_import(self, widget, data):
|
||||
"""opens the auto import tab"""
|
||||
new_aimp_thread=GuiAutoImport.GuiAutoImport(self.settings, self.config)
|
||||
self.threads.append(new_aimp_thread)
|
||||
aimp_tab=new_aimp_thread.get_vbox()
|
||||
self.add_and_display_tab(aimp_tab, "Auto Import")
|
||||
#end def tab_auto_import
|
||||
|
||||
def tab_bulk_import(self, widget, data):
|
||||
"""opens a tab for bulk importing"""
|
||||
#print "start of tab_bulk_import"
|
||||
new_import_thread=GuiBulkImport.GuiBulkImport(self.db, self.settings, self.config)
|
||||
self.threads.append(new_import_thread)
|
||||
bulk_tab=new_import_thread.get_vbox()
|
||||
self.add_and_display_tab(bulk_tab, "Bulk Import")
|
||||
#end def tab_bulk_import
|
||||
|
||||
def tab_main_help(self, widget, data):
|
||||
"""Displays a tab with the main fpdb help screen"""
|
||||
#print "start of tab_main_help"
|
||||
mh_tab=gtk.Label("""Welcome to Fpdb!
|
||||
For documentation please visit our website at http://fpdb.sourceforge.net/ or check the docs directory in the fpdb folder.
|
||||
Please note that default.conf is no longer needed nor used, all configuration now happens in HUD_config.xml
|
||||
This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||
self.add_and_display_tab(mh_tab, "Help")
|
||||
#end def tab_main_help
|
||||
|
||||
def tab_table_viewer(self, widget, data):
|
||||
"""opens a table viewer tab"""
|
||||
#print "start of tab_table_viewer"
|
||||
new_tv_thread=GuiTableViewer.GuiTableViewer(self.db, self.settings)
|
||||
self.threads.append(new_tv_thread)
|
||||
tv_tab=new_tv_thread.get_vbox()
|
||||
self.add_and_display_tab(tv_tab, "Table Viewer")
|
||||
#end def tab_table_viewer
|
||||
|
||||
def tabGraphViewer(self, widget, data):
|
||||
"""opens a graph viewer tab"""
|
||||
#print "start of tabGraphViewer"
|
||||
new_gv_thread=GuiGraphViewer.GuiGraphViewer(self.db, self.settings, self.querydict, self.config)
|
||||
self.threads.append(new_gv_thread)
|
||||
gv_tab=new_gv_thread.get_vbox()
|
||||
self.add_and_display_tab(gv_tab, "Graphs")
|
||||
#end def tabGraphViewer
|
||||
|
||||
def __init__(self):
|
||||
self.threads=[]
|
||||
self.db=None
|
||||
self.config = Configuration.Config()
|
||||
self.load_profile()
|
||||
|
||||
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||
self.window.connect("delete_event", self.delete_event)
|
||||
self.window.connect("destroy", self.destroy)
|
||||
self.window.set_title("Free Poker DB - version: alpha9+, p143 or higher")
|
||||
self.window.set_border_width(1)
|
||||
self.window.set_size_request(1020,400)
|
||||
self.window.set_resizable(True)
|
||||
|
||||
self.menu_items = (
|
||||
( "/_Main", None, None, 0, "<Branch>" ),
|
||||
( "/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/_Save Profile (todo)", None, self.dia_save_profile, 0, None ),
|
||||
("/Main/sep1", None, None, 0, "<Separator>" ),
|
||||
("/Main/_Quit", "<control>Q", self.quit, 0, None ),
|
||||
("/_Import", None, None, 0, "<Branch>" ),
|
||||
("/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 _Rating (todo)", "<control>R", self.not_implemented, 0, None ),
|
||||
("/_Viewers", None, None, 0, "<Branch>" ),
|
||||
("/_Viewers/_Auto Import and HUD", "<control>A", self.tab_auto_import, 0, None ),
|
||||
("/Viewers/_Graphs", "<control>G", self.tabGraphViewer, 0, None ),
|
||||
("/Viewers/Hand _Replayer (todo)", None, self.not_implemented, 0, None ),
|
||||
("/Viewers/Player _Details (todo)", None, self.not_implemented, 0, None ),
|
||||
("/Viewers/_Player Stats (tabulated view) (todo)", None, self.not_implemented, 0, None ),
|
||||
("/Viewers/Starting _Hands (todo)", None, self.not_implemented, 0, None ),
|
||||
("/Viewers/_Session Replayer (todo)", None, self.not_implemented, 0, None ),
|
||||
("/Viewers/Poker_table Viewer (mostly obselete)", "<control>T", self.tab_table_viewer, 0, None ),
|
||||
#( "/Viewers/Tourney Replayer
|
||||
( "/_Database", None, None, 0, "<Branch>" ),
|
||||
( "/Database/Create or Delete _Database (todo)", None, self.dia_create_del_database, 0, None ),
|
||||
( "/Database/Create or Delete _User (todo)", None, self.dia_create_del_user, 0, None ),
|
||||
( "/Database/Create or Recreate _Tables", None, self.dia_recreate_tables, 0, None ),
|
||||
( "/Database/_Statistics (todo)", None, self.dia_database_stats, 0, None ),
|
||||
( "/D_ebugging", None, None, 0, "<Branch>" ),
|
||||
( "/Debugging/_Delete Parts of Database (todo)", None, self.dia_delete_db_parts, 0, None ),
|
||||
( "/Debugging/_Export DB (todo)", None, self.dia_export_db, 0, None ),
|
||||
( "/Debugging/_Import DB (todo)", None, self.dia_import_db, 0, None ),
|
||||
( "/Debugging/_Regression test (todo)", None, self.dia_regression_test, 0, None ),
|
||||
( "/_Help", None, None, 0, "<LastBranch>" ),
|
||||
( "/Help/_Main Help", "<control>H", self.tab_main_help, 0, None ),
|
||||
( "/Help/_Abbrevations (todo)", None, self.tab_abbreviations, 0, None ),
|
||||
( "/Help/sep1", None, None, 0, "<Separator>" ),
|
||||
( "/Help/A_bout (todo)", None, self.dia_about, 0, None ),
|
||||
( "/Help/_License and Copying (todo)", None, self.dia_licensing, 0, None )
|
||||
)
|
||||
|
||||
self.main_vbox = gtk.VBox(False, 1)
|
||||
self.main_vbox.set_border_width(1)
|
||||
self.window.add(self.main_vbox)
|
||||
self.main_vbox.show()
|
||||
|
||||
menubar = self.get_menu(self.window)
|
||||
self.main_vbox.pack_start(menubar, False, True, 0)
|
||||
menubar.show()
|
||||
#done menubar
|
||||
|
||||
self.tabs=[]
|
||||
self.tab_names=[]
|
||||
self.tab_buttons=[]
|
||||
self.tab_box = gtk.HBox(False,1)
|
||||
self.main_vbox.pack_start(self.tab_box, False, True, 0)
|
||||
self.tab_box.show()
|
||||
#done tab bar
|
||||
|
||||
self.current_tab = gtk.VBox(False,1)
|
||||
self.current_tab.set_border_width(1)
|
||||
self.main_vbox.add(self.current_tab)
|
||||
self.current_tab.show()
|
||||
|
||||
self.tab_main_help(None, None)
|
||||
|
||||
self.status_bar = gtk.Label("Status: Connected to "+self.db.get_backend_name()+" database named "+self.db.database+" on host "+self.db.host)
|
||||
self.main_vbox.pack_end(self.status_bar, False, True, 0)
|
||||
self.status_bar.show()
|
||||
|
||||
self.window.show()
|
||||
#end def __init__
|
||||
|
||||
def main(self):
|
||||
gtk.main()
|
||||
return 0
|
||||
#end def main
|
||||
|
||||
if __name__ == "__main__":
|
||||
me = fpdb()
|
||||
me.main()
|
||||
|
|
0
pyfpdb/fpdb_db.py
Executable file → Normal file
0
pyfpdb/fpdb_db.py
Executable file → Normal file
608
pyfpdb/fpdb_import.py
Executable file → Normal file
608
pyfpdb/fpdb_import.py
Executable file → Normal file
|
@ -1,298 +1,310 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
#Copyright 2008 Steffen Jobbagy-Felso
|
||||
#This program is free software: you can redistribute it and/or modify
|
||||
#it under the terms of the GNU Affero General Public License as published by
|
||||
#the Free Software Foundation, version 3 of the License.
|
||||
#
|
||||
#This program is distributed in the hope that it will be useful,
|
||||
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
#GNU General Public License for more details.
|
||||
#
|
||||
#You should have received a copy of the GNU Affero General Public License
|
||||
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#In the "official" distribution you can find the license in
|
||||
#agpl-3.0.txt in the docs folder of the package.
|
||||
|
||||
#see status.txt for site/games support info
|
||||
|
||||
import sys
|
||||
|
||||
try:
|
||||
import MySQLdb
|
||||
mysqlLibFound=True
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
import psycopg2
|
||||
pgsqlLibFound=True
|
||||
except:
|
||||
pass
|
||||
|
||||
import math
|
||||
import os
|
||||
import datetime
|
||||
import re
|
||||
import fpdb_simple
|
||||
import fpdb_parse_logic
|
||||
from time import time
|
||||
|
||||
class Importer:
|
||||
|
||||
def __init__(self, caller, settings):
|
||||
"""Constructor"""
|
||||
self.settings=settings
|
||||
self.caller=caller
|
||||
self.db = None
|
||||
self.cursor = None
|
||||
self.filelist = {}
|
||||
self.dirlist = {}
|
||||
self.monitor = False
|
||||
self.updated = {} #Time last import was run {file:mtime}
|
||||
self.callHud = False
|
||||
self.lines = None
|
||||
self.faobs = None #File as one big string
|
||||
self.pos_in_file = {} # dict to remember how far we have read in the file
|
||||
#Set defaults
|
||||
if not self.settings.has_key('imp-callFpdbHud'):
|
||||
self.settings['imp-callFpdbHud'] = False
|
||||
if not self.settings.has_key('minPrint'):
|
||||
self.settings['minPrint'] = 30
|
||||
self.dbConnect()
|
||||
|
||||
def dbConnect(self):
|
||||
#connect to DB
|
||||
if self.settings['db-backend'] == 2:
|
||||
if not mysqlLibFound:
|
||||
raise fpdb_simple.FpdbError("interface library MySQLdb not found but MySQL selected as backend - please install the library or change the config file")
|
||||
self.db = MySQLdb.connect(self.settings['db-host'], self.settings['db-user'],
|
||||
self.settings['db-password'], self.settings['db-databaseName'])
|
||||
elif self.settings['db-backend'] == 3:
|
||||
if not pgsqlLibFound:
|
||||
raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
|
||||
print self.settings
|
||||
self.db = psycopg2.connect(host = self.settings['db-host'],
|
||||
user = self.settings['db-user'],
|
||||
password = self.settings['db-password'],
|
||||
database = self.settings['db-databaseName'])
|
||||
elif self.settings['db-backend'] == 4:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
self.cursor = self.db.cursor()
|
||||
|
||||
#Set functions
|
||||
def setCallHud(self, value):
|
||||
self.callHud = value
|
||||
|
||||
def setMinPrint(self, value):
|
||||
self.settings['minPrint'] = int(value)
|
||||
|
||||
def setHandCount(self, value):
|
||||
self.settings['handCount'] = int(value)
|
||||
|
||||
def setQuiet(self, value):
|
||||
self.settings['quiet'] = value
|
||||
|
||||
def setFailOnError(self, value):
|
||||
self.settings['failOnError'] = value
|
||||
|
||||
# def setWatchTime(self):
|
||||
# self.updated = time()
|
||||
|
||||
def clearFileList(self):
|
||||
self.filelist = {}
|
||||
|
||||
#Add an individual file to filelist
|
||||
def addImportFile(self, filename, site = "default", filter = "passthrough"):
|
||||
#TODO: test it is a valid file
|
||||
self.filelist[filename] = [site] + [filter]
|
||||
|
||||
#Add a directory of files to filelist
|
||||
#Only one import directory per site supported.
|
||||
#dirlist is a hash of lists:
|
||||
#dirlist{ 'PokerStars' => ["/path/to/import/", "filtername"] }
|
||||
def addImportDirectory(self,dir,monitor = False, site = "default", filter = "passthrough"):
|
||||
if os.path.isdir(dir):
|
||||
if monitor == True:
|
||||
self.monitor = True
|
||||
self.dirlist[site] = [dir] + [filter]
|
||||
|
||||
for file in os.listdir(dir):
|
||||
self.addImportFile(os.path.join(dir, file), site, filter)
|
||||
else:
|
||||
print "Warning: Attempted to add: '" + str(dir) + "' as an import directory"
|
||||
|
||||
#Run full import on filelist
|
||||
def runImport(self):
|
||||
for file in self.filelist:
|
||||
self.import_file_dict(file)
|
||||
|
||||
#Run import on updated files, then store latest update time.
|
||||
def runUpdated(self):
|
||||
#Check for new files in directory
|
||||
#todo: make efficient - always checks for new file, should be able to use mtime of directory
|
||||
# ^^ May not work on windows
|
||||
for site in self.dirlist:
|
||||
self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1])
|
||||
|
||||
for file in self.filelist:
|
||||
stat_info = os.stat(file)
|
||||
try:
|
||||
lastupdate = self.updated[file]
|
||||
if stat_info.st_mtime > lastupdate:
|
||||
self.import_file_dict(file)
|
||||
self.updated[file] = time()
|
||||
except:
|
||||
self.updated[file] = time()
|
||||
# This codepath only runs first time the file is found, if modified in the last
|
||||
# minute run an immediate import.
|
||||
if (time() - stat_info.st_mtime) < 60:
|
||||
self.import_file_dict(file)
|
||||
|
||||
# This is now an internal function that should not be called directly.
|
||||
def import_file_dict(self, file):
|
||||
starttime = time()
|
||||
last_read_hand=0
|
||||
loc = 0
|
||||
if (file=="stdin"):
|
||||
inputFile=sys.stdin
|
||||
else:
|
||||
inputFile=open(file, "rU")
|
||||
try: loc = self.pos_in_file[file]
|
||||
except: pass
|
||||
|
||||
# Read input file into class and close file
|
||||
inputFile.seek(loc)
|
||||
self.lines=fpdb_simple.removeTrailingEOL(inputFile.readlines())
|
||||
self.pos_in_file[file] = inputFile.tell()
|
||||
inputFile.close()
|
||||
|
||||
firstline = self.lines[0]
|
||||
|
||||
if firstline.find("Tournament Summary")!=-1:
|
||||
print "TODO: implement importing tournament summaries"
|
||||
#self.faobs = readfile(inputFile)
|
||||
#self.parseTourneyHistory()
|
||||
return 0
|
||||
|
||||
site=fpdb_simple.recogniseSite(firstline)
|
||||
category=fpdb_simple.recogniseCategory(firstline)
|
||||
|
||||
startpos=0
|
||||
stored=0 #counter
|
||||
duplicates=0 #counter
|
||||
partial=0 #counter
|
||||
errors=0 #counter
|
||||
|
||||
for i in range (len(self.lines)): #main loop, iterates through the lines of a file and calls the appropriate parser method
|
||||
if (len(self.lines[i])<2):
|
||||
endpos=i
|
||||
hand=self.lines[startpos:endpos]
|
||||
|
||||
if (len(hand[0])<2):
|
||||
hand=hand[1:]
|
||||
|
||||
cancelled=False
|
||||
damaged=False
|
||||
if (site=="ftp"):
|
||||
for i in range (len(hand)):
|
||||
if (hand[i].endswith(" has been canceled")): #this is their typo. this is a typo, right?
|
||||
cancelled=True
|
||||
|
||||
seat1=hand[i].find("Seat ") #todo: make this recover by skipping this line
|
||||
if (seat1!=-1):
|
||||
if (hand[i].find("Seat ", seat1+3)!=-1):
|
||||
damaged=True
|
||||
|
||||
if (len(hand)<3):
|
||||
pass
|
||||
#todo: the above 2 lines are kind of a dirty hack, the mentioned circumstances should be handled elsewhere but that doesnt work with DOS/Win EOL. actually this doesnt work.
|
||||
elif (hand[0].endswith(" (partial)")): #partial hand - do nothing
|
||||
partial+=1
|
||||
elif (hand[1].find("Seat")==-1 and hand[2].find("Seat")==-1 and hand[3].find("Seat")==-1):#todo: should this be or instead of and?
|
||||
partial+=1
|
||||
elif (cancelled or damaged):
|
||||
partial+=1
|
||||
else: #normal processing
|
||||
isTourney=fpdb_simple.isTourney(hand[0])
|
||||
if not isTourney:
|
||||
fpdb_simple.filterAnteBlindFold(site,hand)
|
||||
hand=fpdb_simple.filterCrap(site, hand, isTourney)
|
||||
self.hand=hand
|
||||
|
||||
try:
|
||||
handsId=fpdb_parse_logic.mainParser(self.db, self.cursor, site, category, hand)
|
||||
self.db.commit()
|
||||
|
||||
stored+=1
|
||||
self.db.commit()
|
||||
# if settings['imp-callFpdbHud'] and self.callHud and os.sep=='/':
|
||||
if self.settings['imp-callFpdbHud'] and self.callHud:
|
||||
#print "call to HUD here. handsId:",handsId
|
||||
#pipe the Hands.id out to the HUD
|
||||
self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
|
||||
except fpdb_simple.DuplicateError:
|
||||
duplicates+=1
|
||||
except (ValueError), fe:
|
||||
errors+=1
|
||||
self.printEmailErrorMessage(errors, file, hand[0])
|
||||
|
||||
if (self.settings['failOnError']):
|
||||
self.db.commit() #dont remove this, in case hand processing was cancelled.
|
||||
raise
|
||||
except (fpdb_simple.FpdbError), fe:
|
||||
errors+=1
|
||||
self.printEmailErrorMessage(errors, file, hand[0])
|
||||
|
||||
#fe.printStackTrace() #todo: get stacktrace
|
||||
self.db.rollback()
|
||||
|
||||
if (self.settings['failOnError']):
|
||||
self.db.commit() #dont remove this, in case hand processing was cancelled.
|
||||
raise
|
||||
if (self.settings['minPrint']!=0):
|
||||
if ((stored+duplicates+partial+errors)%self.settings['minPrint']==0):
|
||||
print "stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors
|
||||
|
||||
if (self.settings['handCount']!=0):
|
||||
if ((stored+duplicates+partial+errors)>=self.settings['handCount']):
|
||||
if (not self.settings['quiet']):
|
||||
print "quitting due to reaching the amount of hands to be imported"
|
||||
print "Total stored:", stored, "duplicates:", duplicates, "partial/damaged:", partial, "errors:", errors, " time:", (time() - starttime)
|
||||
sys.exit(0)
|
||||
startpos=endpos
|
||||
print "Total stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors, " time:", (time() - starttime)
|
||||
|
||||
if stored==0:
|
||||
if duplicates>0:
|
||||
for line_no in range(len(self.lines)):
|
||||
if self.lines[line_no].find("Game #")!=-1:
|
||||
final_game_line=self.lines[line_no]
|
||||
handsId=fpdb_simple.parseSiteHandNo(final_game_line)
|
||||
else:
|
||||
print "failed to read a single hand from file:", inputFile
|
||||
handsId=0
|
||||
#todo: this will cause return of an unstored hand number if the last hand was error or partial
|
||||
self.db.commit()
|
||||
self.handsId=handsId
|
||||
return handsId
|
||||
#end def import_file_dict
|
||||
|
||||
def parseTourneyHistory(self):
|
||||
print "Tourney history parser stub"
|
||||
#Find tournament boundaries.
|
||||
#print self.foabs
|
||||
|
||||
|
||||
def printEmailErrorMessage(self, errors, filename, line):
|
||||
print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it."
|
||||
print "Filename:", filename
|
||||
print "Here is the first line so you can identify it. Please mention that the error was a ValueError:"
|
||||
print self.hand[0]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print "CLI for fpdb_import is now available as CliFpdb.py"
|
||||
#!/usr/bin/python
|
||||
|
||||
#Copyright 2008 Steffen Jobbagy-Felso
|
||||
#This program is free software: you can redistribute it and/or modify
|
||||
#it under the terms of the GNU Affero General Public License as published by
|
||||
#the Free Software Foundation, version 3 of the License.
|
||||
#
|
||||
#This program is distributed in the hope that it will be useful,
|
||||
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
#GNU General Public License for more details.
|
||||
#
|
||||
#You should have received a copy of the GNU Affero General Public License
|
||||
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#In the "official" distribution you can find the license in
|
||||
#agpl-3.0.txt in the docs folder of the package.
|
||||
|
||||
#see status.txt for site/games support info
|
||||
|
||||
import sys
|
||||
|
||||
try:
|
||||
import MySQLdb
|
||||
mysqlLibFound=True
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
import psycopg2
|
||||
pgsqlLibFound=True
|
||||
except:
|
||||
pass
|
||||
|
||||
import math
|
||||
import os
|
||||
import datetime
|
||||
import re
|
||||
import fpdb_simple
|
||||
import fpdb_parse_logic
|
||||
from time import time
|
||||
|
||||
class Importer:
|
||||
|
||||
def __init__(self, caller, settings, config):
|
||||
"""Constructor"""
|
||||
self.settings=settings
|
||||
self.caller=caller
|
||||
self.config = config
|
||||
self.db = None
|
||||
self.cursor = None
|
||||
self.filelist = {}
|
||||
self.dirlist = {}
|
||||
self.monitor = False
|
||||
self.updated = {} #Time last import was run {file:mtime}
|
||||
self.lines = None
|
||||
self.faobs = None #File as one big string
|
||||
self.pos_in_file = {} # dict to remember how far we have read in the file
|
||||
#Set defaults
|
||||
self.callHud = self.config.get_import_parameters().get("callFpdbHud")
|
||||
if not self.settings.has_key('minPrint'):
|
||||
self.settings['minPrint'] = 30
|
||||
self.dbConnect()
|
||||
|
||||
def dbConnect(self):
|
||||
#connect to DB
|
||||
if self.settings['db-backend'] == 2:
|
||||
if not mysqlLibFound:
|
||||
raise fpdb_simple.FpdbError("interface library MySQLdb not found but MySQL selected as backend - please install the library or change the config file")
|
||||
self.db = MySQLdb.connect(self.settings['db-host'], self.settings['db-user'],
|
||||
self.settings['db-password'], self.settings['db-databaseName'])
|
||||
elif self.settings['db-backend'] == 3:
|
||||
if not pgsqlLibFound:
|
||||
raise fpdb_simple.FpdbError("interface library psycopg2 not found but PostgreSQL selected as backend - please install the library or change the config file")
|
||||
print self.settings
|
||||
self.db = psycopg2.connect(host = self.settings['db-host'],
|
||||
user = self.settings['db-user'],
|
||||
password = self.settings['db-password'],
|
||||
database = self.settings['db-databaseName'])
|
||||
elif self.settings['db-backend'] == 4:
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
self.cursor = self.db.cursor()
|
||||
|
||||
#Set functions
|
||||
def setCallHud(self, value):
|
||||
self.callHud = value
|
||||
|
||||
def setMinPrint(self, value):
|
||||
self.settings['minPrint'] = int(value)
|
||||
|
||||
def setHandCount(self, value):
|
||||
self.settings['handCount'] = int(value)
|
||||
|
||||
def setQuiet(self, value):
|
||||
self.settings['quiet'] = value
|
||||
|
||||
def setFailOnError(self, value):
|
||||
self.settings['failOnError'] = value
|
||||
|
||||
# def setWatchTime(self):
|
||||
# self.updated = time()
|
||||
|
||||
def clearFileList(self):
|
||||
self.filelist = {}
|
||||
|
||||
#Add an individual file to filelist
|
||||
def addImportFile(self, filename, site = "default", filter = "passthrough"):
|
||||
#TODO: test it is a valid file
|
||||
self.filelist[filename] = [site] + [filter]
|
||||
|
||||
#Add a directory of files to filelist
|
||||
#Only one import directory per site supported.
|
||||
#dirlist is a hash of lists:
|
||||
#dirlist{ 'PokerStars' => ["/path/to/import/", "filtername"] }
|
||||
def addImportDirectory(self, dir, monitor = False, site = "default", filter = "passthrough"):
|
||||
if dir != "/dev/null" and dir.lower() != "none":
|
||||
if os.path.isdir(dir):
|
||||
if monitor == True:
|
||||
self.monitor = True
|
||||
self.dirlist[site] = [dir] + [filter]
|
||||
|
||||
for file in os.listdir(dir):
|
||||
self.addImportFile(os.path.join(dir, file), site, filter)
|
||||
else:
|
||||
print "Warning: Attempted to add: '" + str(dir) + "' as an import directory\n"
|
||||
|
||||
#Run full import on filelist
|
||||
def runImport(self):
|
||||
for file in self.filelist:
|
||||
self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
|
||||
|
||||
#Run import on updated files, then store latest update time.
|
||||
def runUpdated(self):
|
||||
#Check for new files in directory
|
||||
#todo: make efficient - always checks for new file, should be able to use mtime of directory
|
||||
# ^^ May not work on windows
|
||||
for site in self.dirlist:
|
||||
self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1])
|
||||
|
||||
for file in self.filelist:
|
||||
stat_info = os.stat(file)
|
||||
try:
|
||||
lastupdate = self.updated[file]
|
||||
if stat_info.st_mtime > lastupdate:
|
||||
self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
|
||||
self.updated[file] = time()
|
||||
except:
|
||||
self.updated[file] = time()
|
||||
# This codepath only runs first time the file is found, if modified in the last
|
||||
# minute run an immediate import.
|
||||
if (time() - stat_info.st_mtime) < 60:
|
||||
self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
|
||||
|
||||
# This is now an internal function that should not be called directly.
|
||||
def import_file_dict(self, file, site, filter):
|
||||
if(filter == "passthrough"):
|
||||
self.import_fpdb_file(file, site)
|
||||
else:
|
||||
#Load filter, and run filtered file though main importer
|
||||
self.import_fpdb_file(file, site)
|
||||
|
||||
|
||||
def import_fpdb_file(self, file, site):
|
||||
starttime = time()
|
||||
last_read_hand=0
|
||||
loc = 0
|
||||
if (file=="stdin"):
|
||||
inputFile=sys.stdin
|
||||
else:
|
||||
inputFile=open(file, "rU")
|
||||
try: loc = self.pos_in_file[file]
|
||||
except: pass
|
||||
|
||||
# Read input file into class and close file
|
||||
inputFile.seek(loc)
|
||||
self.lines=fpdb_simple.removeTrailingEOL(inputFile.readlines())
|
||||
self.pos_in_file[file] = inputFile.tell()
|
||||
inputFile.close()
|
||||
|
||||
try: # sometimes we seem to be getting an empty self.lines, in which case, we just want to return.
|
||||
firstline = self.lines[0]
|
||||
except:
|
||||
# print "import_fpdb_file", file, site, self.lines, "\n"
|
||||
return
|
||||
|
||||
if firstline.find("Tournament Summary")!=-1:
|
||||
print "TODO: implement importing tournament summaries"
|
||||
#self.faobs = readfile(inputFile)
|
||||
#self.parseTourneyHistory()
|
||||
return 0
|
||||
|
||||
site=fpdb_simple.recogniseSite(firstline)
|
||||
category=fpdb_simple.recogniseCategory(firstline)
|
||||
|
||||
startpos=0
|
||||
stored=0 #counter
|
||||
duplicates=0 #counter
|
||||
partial=0 #counter
|
||||
errors=0 #counter
|
||||
|
||||
for i in range (len(self.lines)): #main loop, iterates through the lines of a file and calls the appropriate parser method
|
||||
if (len(self.lines[i])<2):
|
||||
endpos=i
|
||||
hand=self.lines[startpos:endpos]
|
||||
|
||||
if (len(hand[0])<2):
|
||||
hand=hand[1:]
|
||||
|
||||
cancelled=False
|
||||
damaged=False
|
||||
if (site=="ftp"):
|
||||
for i in range (len(hand)):
|
||||
if (hand[i].endswith(" has been canceled")): #this is their typo. this is a typo, right?
|
||||
cancelled=True
|
||||
|
||||
seat1=hand[i].find("Seat ") #todo: make this recover by skipping this line
|
||||
if (seat1!=-1):
|
||||
if (hand[i].find("Seat ", seat1+3)!=-1):
|
||||
damaged=True
|
||||
|
||||
if (len(hand)<3):
|
||||
pass
|
||||
#todo: the above 2 lines are kind of a dirty hack, the mentioned circumstances should be handled elsewhere but that doesnt work with DOS/Win EOL. actually this doesnt work.
|
||||
elif (hand[0].endswith(" (partial)")): #partial hand - do nothing
|
||||
partial+=1
|
||||
elif (hand[1].find("Seat")==-1 and hand[2].find("Seat")==-1 and hand[3].find("Seat")==-1):#todo: should this be or instead of and?
|
||||
partial+=1
|
||||
elif (cancelled or damaged):
|
||||
partial+=1
|
||||
else: #normal processing
|
||||
isTourney=fpdb_simple.isTourney(hand[0])
|
||||
if not isTourney:
|
||||
fpdb_simple.filterAnteBlindFold(site,hand)
|
||||
hand=fpdb_simple.filterCrap(site, hand, isTourney)
|
||||
self.hand=hand
|
||||
|
||||
try:
|
||||
handsId=fpdb_parse_logic.mainParser(self.db, self.cursor, site, category, hand)
|
||||
self.db.commit()
|
||||
|
||||
stored+=1
|
||||
self.db.commit()
|
||||
if self.callHud:
|
||||
#print "call to HUD here. handsId:",handsId
|
||||
#pipe the Hands.id out to the HUD
|
||||
self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
|
||||
except fpdb_simple.DuplicateError:
|
||||
duplicates+=1
|
||||
except (ValueError), fe:
|
||||
errors+=1
|
||||
self.printEmailErrorMessage(errors, file, hand[0])
|
||||
|
||||
if (self.settings['failOnError']):
|
||||
self.db.commit() #dont remove this, in case hand processing was cancelled.
|
||||
raise
|
||||
except (fpdb_simple.FpdbError), fe:
|
||||
errors+=1
|
||||
self.printEmailErrorMessage(errors, file, hand[0])
|
||||
|
||||
#fe.printStackTrace() #todo: get stacktrace
|
||||
self.db.rollback()
|
||||
|
||||
if (self.settings['failOnError']):
|
||||
self.db.commit() #dont remove this, in case hand processing was cancelled.
|
||||
raise
|
||||
if (self.settings['minPrint']!=0):
|
||||
if ((stored+duplicates+partial+errors)%self.settings['minPrint']==0):
|
||||
print "stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors
|
||||
|
||||
if (self.settings['handCount']!=0):
|
||||
if ((stored+duplicates+partial+errors)>=self.settings['handCount']):
|
||||
if (not self.settings['quiet']):
|
||||
print "quitting due to reaching the amount of hands to be imported"
|
||||
print "Total stored:", stored, "duplicates:", duplicates, "partial/damaged:",
|
||||
partial, "errors:", errors, " time: %5.3f" % (time() - starttime)
|
||||
sys.exit(0)
|
||||
startpos=endpos
|
||||
print "Total stored:", stored, "duplicates:", duplicates, "partial:", partial, "errors:", errors, " time: %5.3f" % (time() - starttime)
|
||||
|
||||
if stored==0:
|
||||
if duplicates>0:
|
||||
for line_no in range(len(self.lines)):
|
||||
if self.lines[line_no].find("Game #")!=-1:
|
||||
final_game_line=self.lines[line_no]
|
||||
handsId=fpdb_simple.parseSiteHandNo(final_game_line)
|
||||
else:
|
||||
print "failed to read a single hand from file:", inputFile
|
||||
handsId=0
|
||||
#todo: this will cause return of an unstored hand number if the last hand was error or partial
|
||||
self.db.commit()
|
||||
self.handsId=handsId
|
||||
return handsId
|
||||
#end def import_file_dict
|
||||
|
||||
def parseTourneyHistory(self):
|
||||
print "Tourney history parser stub"
|
||||
#Find tournament boundaries.
|
||||
#print self.foabs
|
||||
|
||||
|
||||
def printEmailErrorMessage(self, errors, filename, line):
|
||||
print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it."
|
||||
print "Filename:", filename
|
||||
print "Here is the first line so you can identify it. Please mention that the error was a ValueError:"
|
||||
print self.hand[0]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print "CLI for fpdb_import is now available as CliFpdb.py"
|
||||
|
|
|
@ -46,7 +46,7 @@ def mainParser(db, cursor, site, category, hand):
|
|||
#print "found small blind line:",smallBlindLine
|
||||
break
|
||||
#print "small blind line:",smallBlindLine
|
||||
gametypeID=fpdb_simple.recogniseGametypeID(cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
|
||||
gametypeID=fpdb_simple.recogniseGametypeID(db, cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
|
||||
if isTourney:
|
||||
if site!="ps":
|
||||
raise fpdb_simple.FpdbError("tourneys are only supported on PS right now")
|
||||
|
@ -142,18 +142,18 @@ def mainParser(db, cursor, site, category, hand):
|
|||
payin_amounts=fpdb_simple.calcPayin(len(names), buyin, fee)
|
||||
|
||||
if base=="hold":
|
||||
result = fpdb_save_to_db.tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
|
||||
result = fpdb_save_to_db.tourney_holdem_omaha(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
|
||||
siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
|
||||
elif base=="stud":
|
||||
result = fpdb_save_to_db.tourney_stud(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
|
||||
result = fpdb_save_to_db.tourney_stud(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteID,
|
||||
siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
|
||||
else:
|
||||
raise fpdb_simple.FpdbError ("unrecognised category")
|
||||
else:
|
||||
if base=="hold":
|
||||
result = fpdb_save_to_db.ring_holdem_omaha(cursor, base, category, siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
|
||||
result = fpdb_save_to_db.ring_holdem_omaha(db, cursor, base, category, siteHandNo, gametypeID, handStartTime, names, playerIDs, startCashes, positions, cardValues, cardSuits, boardValues, boardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
|
||||
elif base=="stud":
|
||||
result = fpdb_save_to_db.ring_stud(cursor, base, category, siteHandNo, gametypeID,
|
||||
result = fpdb_save_to_db.ring_stud(db, cursor, base, category, siteHandNo, gametypeID,
|
||||
handStartTime, names, playerIDs, startCashes, antes, cardValues,
|
||||
cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos)
|
||||
else:
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
import fpdb_simple
|
||||
|
||||
#stores a stud/razz hand into the database
|
||||
def ring_stud(cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||
def ring_stud(db, cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
||||
|
||||
hands_id=fpdb_simple.storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
|
||||
hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
|
||||
|
||||
#print "before calling store_hands_players_stud, antes:", antes
|
||||
hands_players_ids=fpdb_simple.store_hands_players_stud(cursor, hands_id, player_ids,
|
||||
hands_players_ids=fpdb_simple.store_hands_players_stud(db, cursor, hands_id, player_ids,
|
||||
start_cashes, antes, card_values, card_suits, winnings, rakes, seatNos)
|
||||
|
||||
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
|
||||
|
@ -36,14 +36,14 @@ def ring_stud(cursor, base, category, site_hand_no, gametype_id, hand_start_time
|
|||
return hands_id
|
||||
#end def ring_stud
|
||||
|
||||
def ring_holdem_omaha(cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||
def ring_holdem_omaha(db, cursor, base, category, site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||
"""stores a holdem/omaha hand into the database"""
|
||||
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
||||
fpdb_simple.fill_board_cards(board_values, board_suits)
|
||||
|
||||
hands_id=fpdb_simple.storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
|
||||
hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
|
||||
|
||||
hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos)
|
||||
hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos)
|
||||
|
||||
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
|
||||
|
||||
|
@ -53,7 +53,7 @@ def ring_holdem_omaha(cursor, base, category, site_hand_no, gametype_id, hand_st
|
|||
return hands_id
|
||||
#end def ring_holdem_omaha
|
||||
|
||||
def tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId, siteId, #end of tourney specific params
|
||||
def tourney_holdem_omaha(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId, siteId, #end of tourney specific params
|
||||
site_hand_no, gametype_id, hand_start_time, names, player_ids, start_cashes, positions, card_values, card_suits, board_values, board_suits, winnings, rakes, action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||
"""stores a tourney holdem/omaha hand into the database"""
|
||||
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
||||
|
@ -62,9 +62,9 @@ def tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knoc
|
|||
tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourney_start)
|
||||
tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings)
|
||||
|
||||
hands_id=fpdb_simple.storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
|
||||
hands_id=fpdb_simple.storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats)
|
||||
|
||||
hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha_tourney(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids)
|
||||
hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha_tourney(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids)
|
||||
|
||||
fpdb_simple.storeHudCache(cursor, base, category, gametype_id, player_ids, hudImportData)
|
||||
|
||||
|
@ -74,7 +74,7 @@ def tourney_holdem_omaha(cursor, base, category, siteTourneyNo, buyin, fee, knoc
|
|||
return hands_id
|
||||
#end def tourney_holdem_omaha
|
||||
|
||||
def tourney_stud(cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId,
|
||||
def tourney_stud(db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries, prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId,
|
||||
siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
|
||||
#stores a tourney stud/razz hand into the database
|
||||
fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits)
|
||||
|
@ -83,9 +83,9 @@ def tourney_stud(cursor, base, category, siteTourneyNo, buyin, fee, knockout, en
|
|||
|
||||
tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, playerIds, payin_amounts, ranks, winnings)
|
||||
|
||||
hands_id=fpdb_simple.storeHands(cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats)
|
||||
hands_id=fpdb_simple.storeHands(db, cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats)
|
||||
|
||||
hands_players_ids=fpdb_simple.store_hands_players_stud_tourney(cursor, hands_id, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, seatNos, tourneys_players_ids)
|
||||
hands_players_ids=fpdb_simple.store_hands_players_stud_tourney(db, cursor, hands_id, playerIds, startCashes, antes, cardValues, cardSuits, winnings, rakes, seatNos, tourneys_players_ids)
|
||||
|
||||
fpdb_simple.storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData)
|
||||
|
||||
|
|
|
@ -484,7 +484,8 @@ def isActionLine(line):
|
|||
|
||||
#returns whether this is a duplicate
|
||||
def isAlreadyInDB(cursor, gametypeID, siteHandNo):
|
||||
cursor.execute ("SELECT id FROM Hands WHERE gametypeId=%s AND siteHandNo=%s", (gametypeID, siteHandNo))
|
||||
#print "isAlreadyInDB gtid,shand:",gametypeID, siteHandNo
|
||||
cursor.execute ("SELECT id FROM Hands WHERE gametypeId=%s AND siteHandNo=%s", (gametypeID, siteHandNo))
|
||||
result=cursor.fetchall()
|
||||
if (len(result)>=1):
|
||||
raise DuplicateError ("dupl")
|
||||
|
@ -1021,7 +1022,7 @@ def recogniseCategory(line):
|
|||
#end def recogniseCategory
|
||||
|
||||
#returns the int for the gametype_id for the given line
|
||||
def recogniseGametypeID(cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy
|
||||
def recogniseGametypeID(db, cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy
|
||||
#if (topline.find("HORSE")!=-1):
|
||||
# raise FpdbError("recogniseGametypeID: HORSE is not yet supported.")
|
||||
|
||||
|
@ -1072,7 +1073,10 @@ def recogniseGametypeID(cursor, topline, smallBlindLine, site_id, category, isTo
|
|||
else:
|
||||
cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
|
||||
result=cursor.fetchone()
|
||||
#print "tried SELECTing gametypes.id, result:",result
|
||||
#print "recgt1 result=",result
|
||||
#ret=result[0]
|
||||
#print "recgt1 ret=",ret
|
||||
#print "tried SELECTing gametypes.id, result:",result
|
||||
|
||||
try:
|
||||
len(result)
|
||||
|
@ -1105,17 +1109,19 @@ def recogniseGametypeID(cursor, topline, smallBlindLine, site_id, category, isTo
|
|||
cursor.execute("""INSERT INTO Gametypes
|
||||
(siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_blind, big_blind, small_bet, big_bet))
|
||||
cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
|
||||
#cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet))
|
||||
else:
|
||||
cursor.execute("""INSERT INTO Gametypes
|
||||
(siteId, type, base, category, limitType, hiLo, smallBlind, bigBlind, smallBet, bigBet)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (site_id, type, base, category, limit_type, hiLo, small_bet, big_bet, 0, 0))#remember, for these bet means blind
|
||||
cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
|
||||
#cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet))
|
||||
|
||||
result=cursor.fetchone()
|
||||
result=(db.insert_id(),)
|
||||
#print "recgt2 result=",result
|
||||
#print "created new gametypes.id:",result
|
||||
|
||||
return result[0]
|
||||
#print "recgt3: result=", result
|
||||
return result[0]
|
||||
#end def recogniseGametypeID
|
||||
|
||||
def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon):
|
||||
|
@ -1248,15 +1254,16 @@ def store_board_cards(cursor, hands_id, board_values, board_suits):
|
|||
board_values[4], board_suits[4]))
|
||||
#end def store_board_cards
|
||||
|
||||
def storeHands(cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats):
|
||||
def storeHands(db, cursor, site_hand_no, gametype_id, hand_start_time, names, tableName, maxSeats):
|
||||
#stores into table hands
|
||||
cursor.execute ("INSERT INTO Hands (siteHandNo, gametypeId, handStart, seats, tableName, importTime, maxSeats) VALUES (%s, %s, %s, %s, %s, %s, %s)", (site_hand_no, gametype_id, hand_start_time, len(names), tableName, datetime.datetime.today(), maxSeats))
|
||||
#todo: find a better way of doing this...
|
||||
cursor.execute("SELECT id FROM Hands WHERE siteHandNo=%s AND gametypeId=%s", (site_hand_no, gametype_id))
|
||||
return cursor.fetchall()[0][0]
|
||||
#cursor.execute("SELECT id FROM Hands WHERE siteHandNo=%s AND gametypeId=%s", (site_hand_no, gametype_id))
|
||||
#return cursor.fetchall()[0][0]
|
||||
return db.insert_id() # mysql only
|
||||
#end def storeHands
|
||||
|
||||
def store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos):
|
||||
def store_hands_players_holdem_omaha(db, cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos):
|
||||
result=[]
|
||||
if (category=="holdem"):
|
||||
for i in range (len(player_ids)):
|
||||
|
@ -1268,8 +1275,9 @@ def store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, sta
|
|||
(hands_id, player_ids[i], start_cashes[i], positions[i],
|
||||
card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
|
||||
winnings[i], rakes[i], seatNos[i]))
|
||||
cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
|
||||
result.append(cursor.fetchall()[0][0])
|
||||
#cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
|
||||
#result.append(cursor.fetchall()[0][0])
|
||||
result.append( db.insert_id() ) # mysql only
|
||||
elif (category=="omahahi" or category=="omahahilo"):
|
||||
for i in range (len(player_ids)):
|
||||
cursor.execute ("""INSERT INTO HandsPlayers
|
||||
|
@ -1281,14 +1289,15 @@ def store_hands_players_holdem_omaha(cursor, category, hands_id, player_ids, sta
|
|||
card_values[i][0], card_suits[i][0], card_values[i][1], card_suits[i][1],
|
||||
card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
|
||||
winnings[i], rakes[i], seatNos[i]))
|
||||
cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
|
||||
result.append(cursor.fetchall()[0][0])
|
||||
#cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
|
||||
#result.append(cursor.fetchall()[0][0])
|
||||
result.append( db.insert_id() ) # mysql only
|
||||
else:
|
||||
raise FpdbError("invalid category")
|
||||
return result
|
||||
#end def store_hands_players_holdem_omaha
|
||||
|
||||
def store_hands_players_stud(cursor, hands_id, player_ids, start_cashes, antes,
|
||||
def store_hands_players_stud(db, cursor, hands_id, player_ids, start_cashes, antes,
|
||||
card_values, card_suits, winnings, rakes, seatNos):
|
||||
#stores hands_players rows for stud/razz games. returns an array of the resulting IDs
|
||||
result=[]
|
||||
|
@ -1307,12 +1316,14 @@ def store_hands_players_stud(cursor, hands_id, player_ids, start_cashes, antes,
|
|||
card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
|
||||
card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
|
||||
card_values[i][6], card_suits[i][6], winnings[i], rakes[i], seatNos[i]))
|
||||
cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
|
||||
result.append(cursor.fetchall()[0][0])
|
||||
#cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
|
||||
#result.append(cursor.fetchall()[0][0])
|
||||
result.append( db.insert_id() ) # mysql only
|
||||
return result
|
||||
#end def store_hands_players_stud
|
||||
|
||||
def store_hands_players_holdem_omaha_tourney(cursor, category, hands_id, player_ids, start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
|
||||
def store_hands_players_holdem_omaha_tourney(db, cursor, category, hands_id, player_ids,
|
||||
start_cashes, positions, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
|
||||
#stores hands_players for tourney holdem/omaha hands
|
||||
result=[]
|
||||
for i in range (len(player_ids)):
|
||||
|
@ -1338,13 +1349,14 @@ def store_hands_players_holdem_omaha_tourney(cursor, category, hands_id, player_
|
|||
winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
|
||||
else:
|
||||
raise FpdbError ("invalid card_values length:"+str(len(card_values[0])))
|
||||
cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
|
||||
result.append(cursor.fetchall()[0][0])
|
||||
#cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
|
||||
#result.append(cursor.fetchall()[0][0])
|
||||
result.append( db.insert_id() ) # mysql only
|
||||
|
||||
return result
|
||||
#end def store_hands_players_holdem_omaha_tourney
|
||||
|
||||
def store_hands_players_stud_tourney(cursor, hands_id, player_ids, start_cashes,
|
||||
def store_hands_players_stud_tourney(db, cursor, hands_id, player_ids, start_cashes,
|
||||
antes, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids):
|
||||
#stores hands_players for tourney stud/razz hands
|
||||
result=[]
|
||||
|
@ -1362,8 +1374,9 @@ def store_hands_players_stud_tourney(cursor, hands_id, player_ids, start_cashes,
|
|||
card_values[i][2], card_suits[i][2], card_values[i][3], card_suits[i][3],
|
||||
card_values[i][4], card_suits[i][4], card_values[i][5], card_suits[i][5],
|
||||
card_values[i][6], card_suits[i][6], winnings[i], rakes[i], tourneys_players_ids[i], seatNos[i]))
|
||||
cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId=%s", (hands_id, player_ids[i]))
|
||||
result.append(cursor.fetchall()[0][0])
|
||||
#cursor.execute("SELECT id FROM HandsPlayers WHERE handId=%s AND playerId+0=%s", (hands_id, player_ids[i]))
|
||||
#result.append(cursor.fetchall()[0][0])
|
||||
result.append( db.insert_id() ) # mysql only
|
||||
return result
|
||||
#end def store_hands_players_stud_tourney
|
||||
|
||||
|
@ -1949,9 +1962,9 @@ def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
|
|||
|
||||
for player in range (len(playerIds)):
|
||||
if base=="hold":
|
||||
cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player]))
|
||||
cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s AND position=%s", (gametypeId, playerIds[player], len(playerIds), hudImportData['position'][player]))
|
||||
else:
|
||||
cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats=%s", (gametypeId, playerIds[player], len(playerIds)))
|
||||
cursor.execute("SELECT * FROM HudCache WHERE gametypeId+0=%s AND playerId=%s AND activeSeats=%s", (gametypeId, playerIds[player], len(playerIds)))
|
||||
row=cursor.fetchone()
|
||||
#print "gametypeId:", gametypeId, "playerIds[player]",playerIds[player], "len(playerIds):",len(playerIds), "row:",row
|
||||
|
||||
|
@ -2097,7 +2110,7 @@ def storeHudCache(cursor, base, category, gametypeId, playerIds, hudImportData):
|
|||
#end def storeHudCache
|
||||
|
||||
def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, startTime):
|
||||
cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId=%s", (siteTourneyNo, tourneyTypeId))
|
||||
cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
|
||||
tmp=cursor.fetchone()
|
||||
#print "tried SELECTing tourneys.id, result:",tmp
|
||||
|
||||
|
@ -2107,7 +2120,7 @@ def store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, sta
|
|||
cursor.execute("""INSERT INTO Tourneys
|
||||
(tourneyTypeId, siteTourneyNo, entries, prizepool, startTime)
|
||||
VALUES (%s, %s, %s, %s, %s)""", (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime))
|
||||
cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId=%s", (siteTourneyNo, tourneyTypeId))
|
||||
cursor.execute("SELECT id FROM Tourneys WHERE siteTourneyNo=%s AND tourneyTypeId+0=%s", (siteTourneyNo, tourneyTypeId))
|
||||
tmp=cursor.fetchone()
|
||||
#print "created new tourneys.id:",tmp
|
||||
return tmp[0]
|
||||
|
@ -2121,7 +2134,7 @@ def store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks,
|
|||
#print "ranks:",ranks
|
||||
#print "winnings:",winnings
|
||||
for i in range (len(player_ids)):
|
||||
cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId=%s", (tourney_id, player_ids[i]))
|
||||
cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s", (tourney_id, player_ids[i]))
|
||||
tmp=cursor.fetchone()
|
||||
#print "tried SELECTing tourneys_players.id:",tmp
|
||||
|
||||
|
@ -2132,7 +2145,7 @@ def store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks,
|
|||
(tourneyId, playerId, payinAmount, rank, winnings) VALUES (%s, %s, %s, %s, %s)""",
|
||||
(tourney_id, player_ids[i], payin_amounts[i], ranks[i], winnings[i]))
|
||||
|
||||
cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId=%s",
|
||||
cursor.execute("SELECT id FROM TourneysPlayers WHERE tourneyId=%s AND playerId+0=%s",
|
||||
(tourney_id, player_ids[i]))
|
||||
tmp=cursor.fetchone()
|
||||
#print "created new tourneys_players.id:",tmp
|
||||
|
|
Loading…
Reference in New Issue
Block a user