From 25ae39d7b54c2517bbd3a9b7cc5e13c1de010236 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 3 Mar 2009 00:10:15 +0900 Subject: [PATCH 1/2] Minor fixups: set->list and FullTilt lookup table --- pyfpdb/EverleafToFpdb.py | 1 + pyfpdb/FulltiltToFpdb.py | 8 ++++---- pyfpdb/Hand.py | 7 ++++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/pyfpdb/EverleafToFpdb.py b/pyfpdb/EverleafToFpdb.py index 1f8ecbeb..175b4695 100755 --- a/pyfpdb/EverleafToFpdb.py +++ b/pyfpdb/EverleafToFpdb.py @@ -62,6 +62,7 @@ class Everleaf(HandHistoryConverter): def readSupportedGames(self): return [["ring", "hold", "nl"], ["ring", "hold", "pl"], + ["ring", "hold", "fl"], ["ring", "omahahi", "pl"] ] diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 2d2e36d1..c03c056b 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -181,7 +181,7 @@ class FullTilt(HandHistoryConverter): # "2c, qh" -> set(["2c","qc"]) # Also works with Omaha hands. cards = m.group('CARDS') - cards = set(cards.split(' ')) + cards = cards.split(' ') hand.addHoleCards(cards, m.group('PNAME')) def readPlayerCards(self, hand, street): @@ -195,7 +195,7 @@ class FullTilt(HandHistoryConverter): if player.group('NEWCARD') != None: print cards cards = cards + " " + player.group('NEWCARD') - cards = set(cards.split(' ')) + cards = cards.split(' ') hand.addPlayerCards(cards, player.group('PNAME')) def readAction(self, hand, street): @@ -218,7 +218,7 @@ class FullTilt(HandHistoryConverter): def readShowdownActions(self, hand): for shows in self.re_ShowdownAction.finditer(hand.string): cards = shows.group('CARDS') - cards = set(cards.split(' ')) + cards = cards.split(' ') hand.addShownCards(cards, shows.group('PNAME')) def readCollectPot(self,hand): @@ -229,7 +229,7 @@ class FullTilt(HandHistoryConverter): for m in self.re_ShownCards.finditer(hand.string): if m.group('CARDS') is not None: cards = m.group('CARDS') - cards = set(cards.split(' ')) + cards = cards.split(' ') hand.addShownCards(cards=cards, player=m.group('PNAME')) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 16549cb0..74a12106 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -409,7 +409,12 @@ Map the tuple self.gametype onto the pokerstars string describing it "0.20" : ("0.05", "0.10"), "0.50" : ("0.10", "0.25"), "1.00" : ("0.25", "0.50") - + }, + "FullTilt" : { "0.10" : ("0.02", "0.05"), + "0.20" : ("0.05", "0.10"), + "1" : ("0.25", "0.50"), + "2" : ("0.50", "1"), + "4" : ("1", "2") } } return betlist[self.sitename][self.bb] From 86101c522c36afc98b0de8b34891344c9b482ff9 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 3 Mar 2009 20:32:01 +0900 Subject: [PATCH 2/2] GuiPositionalStats.py New tab, output cols aren't labelled properly but we appear to have something sane --- pyfpdb/GuiPositionalStats.py | 178 ++++++++ pyfpdb/fpdb.py | 798 ++++++++++++++++++----------------- 2 files changed, 581 insertions(+), 395 deletions(-) create mode 100644 pyfpdb/GuiPositionalStats.py diff --git a/pyfpdb/GuiPositionalStats.py b/pyfpdb/GuiPositionalStats.py new file mode 100644 index 00000000..e682ecc4 --- /dev/null +++ b/pyfpdb/GuiPositionalStats.py @@ -0,0 +1,178 @@ +#!/usr/bin/python + +#Copyright 2008 Steffen Jobbagy-Felso +#This program is free software: you can redistribute it and/or modify +#it under the terms of the GNU Affero General Public License as published by +#the Free Software Foundation, version 3 of the License. +# +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. +# +#You should have received a copy of the GNU Affero General Public License +#along with this program. If not, see . +#In the "official" distribution you can find the license in +#agpl-3.0.txt in the docs folder of the package. + +import threading +import pygtk +pygtk.require('2.0') +import gtk +import os + +import fpdb_import +import fpdb_db +import FpdbSQLQueries + +class GuiPositionalStats (threading.Thread): + def get_vbox(self): + """returns the vbox of this thread""" + return self.main_hbox + + def toggleCallback(self, widget, data=None): +# print "%s was toggled %s" % (data, ("OFF", "ON")[widget.get_active()]) + self.activesite = data + print "DEBUG: activesite set to %s" %(self.activesite) + + def refreshStats(self, widget, data): + try: self.stats_table.destroy() + except AttributeError: pass + self.fillStatsFrame(self.stats_frame) + + def fillStatsFrame(self, vbox): + # Get currently active site and grab playerid + print "DEBUG: attempting to fill stats frame" + tmp = self.sql.query['playerStatsByPosition'] + + result = self.cursor.execute(self.sql.query['getPlayerId'], (self.heroes[self.activesite],)) + result = self.cursor.fetchall() + if not result == (): + pid = result[0][0] + pid = result[0][0] + tmp = tmp.replace("", "(" + str(pid) + ")") + self.cursor.execute(tmp) + result = self.cursor.fetchall() + cols = 16 + rows = len(result)+1 # +1 for title row + self.stats_table = gtk.Table(rows, cols, False) + self.stats_table.set_col_spacings(4) + self.stats_table.show() + vbox.add(self.stats_table) + + # Create header row + titles = ("Game", "Hands", "VPIP", "PFR", "Saw_F", "SawSD", "WtSDwsF", "W$SD", "FlAFq", "TuAFq", "RvAFq", "PoFAFq", "Net($)", "BB/100", "$/hand", "Variance") + + col = 0 + row = 0 + for t in titles: + l = gtk.Label(titles[col]) + l.show() + self.stats_table.attach(l, col, col+1, row, row+1, yoptions=gtk.SHRINK) + col +=1 + + for row in range(rows-1): + if(row%2 == 0): + bgcolor = "white" + else: + bgcolor = "lightgrey" + for col in range(cols): + eb = gtk.EventBox() + eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bgcolor)) + if result[row][col]: + l = gtk.Label(result[row][col]) + else: + l = gtk.Label(' ') + if col == 0: + l.set_alignment(xalign=0.0, yalign=0.5) + else: + l.set_alignment(xalign=1.0, yalign=0.5) + eb.add(l) + self.stats_table.attach(eb, col, col+1, row+1, row+2, yoptions=gtk.SHRINK) + l.show() + eb.show() + self.fdb.db.commit() + #end def fillStatsFrame(self, vbox): + + def fillPlayerFrame(self, vbox): + for site in self.conf.supported_sites.keys(): + hbox = gtk.HBox(False, 0) + vbox.pack_start(hbox, False, True, 0) + hbox.show() + + player = self.conf.supported_sites[site].screen_name + self.createPlayerLine(hbox, site, player) + hbox = gtk.HBox(False, 0) + button = gtk.Button("Refresh") + button.connect("clicked", self.refreshStats, False) + button.show() + hbox.add(button) + vbox.pack_start(hbox, False, True, 0) + hbox.show() + + def createPlayerLine(self, hbox, site, player): + if(self.buttongroup == None): + button = gtk.RadioButton(None, site + " id:") + button.set_active(True) + self.buttongroup = button + self.activesite = site + else: + button = gtk.RadioButton(self.buttongroup, site + " id:") + hbox.pack_start(button, True, True, 0) + button.connect("toggled", self.toggleCallback, site) + button.show() + + pname = gtk.Entry() + pname.set_text(player) + pname.set_width_chars(20) + hbox.pack_start(pname, False, True, 0) + pname.connect("changed", self.__set_hero_name, site) + #TODO: Look at GtkCompletion - to fill out usernames + pname.show() + self.__set_hero_name(pname, site) + + def __set_hero_name(self, w, site): + self.heroes[site] = w.get_text() + + def __init__(self, db, config, querylist, debug=True): + self.debug=debug + self.conf=config + + # create new db connection to avoid conflicts with other threads + self.fdb = fpdb_db.fpdb_db() + self.fdb.do_connect(self.conf) + self.cursor=self.fdb.cursor + + self.sql = querylist + + self.activesite = None + self.buttongroup = None + + self.heroes = {} + self.stat_table = None + self.stats_frame = None + + self.main_hbox = gtk.HBox(False, 0) + self.main_hbox.show() + + playerFrame = gtk.Frame("Hero:") + playerFrame.set_label_align(0.0, 0.0) + playerFrame.show() + vbox = gtk.VBox(False, 0) + vbox.show() + + self.fillPlayerFrame(vbox) + playerFrame.add(vbox) + + statsFrame = gtk.Frame("Stats:") + statsFrame.set_label_align(0.0, 0.0) + statsFrame.show() + self.stats_frame = gtk.VBox(False, 0) + self.stats_frame.show() + + self.fillStatsFrame(self.stats_frame) + statsFrame.add(self.stats_frame) + + self.main_hbox.pack_start(playerFrame) + self.main_hbox.pack_start(statsFrame) + diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py index 32f5f059..f1ff7e1a 100755 --- a/pyfpdb/fpdb.py +++ b/pyfpdb/fpdb.py @@ -22,13 +22,13 @@ 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 .") + 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 + 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') @@ -38,6 +38,7 @@ import fpdb_db import fpdb_simple import GuiBulkImport import GuiPlayerStats +import GuiPositionalStats import GuiTableViewer import GuiAutoImport import GuiGraphViewer @@ -47,419 +48,426 @@ import Configuration VERSION = "0.10" 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: - return # we depend on this to not create duplicate tabs, there's no reason to raise an error here? -# 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 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 destroy(self, widget, data=None): - self.quit(widget, data) - #end def destroy - - def dia_about(self, widget, data): - print "todo: implement dia_about", - print " version = %s, requires database version %s" % (VERSION, "118") - #end def dia_about - - def dia_create_del_database(self, widget, data): - print "todo: implement dia_create_del_database" - self.obtain_global_lock() - #end def dia_create_del_database - - def dia_create_del_user(self, widget, data): - print "todo: implement dia_create_del_user" - self.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" - self.obtain_global_lock() - #end def dia_delete_db_parts - - def dia_edit_profile(self, widget=None, data=None, create_default=False, path=None): - print "todo: implement dia_edit_profile" - self.obtain_global_lock() - #end def dia_edit_profile + 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 dia_export_db(self, widget, data): - print "todo: implement dia_export_db" - self.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" - self.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 + 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: + return # we depend on this to not create duplicate tabs, there's no reason to raise an error here? +# raise fpdb_simple.FpdbError("duplicate tab_name not permitted") - 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)) + self.tabs.append(new_tab) + self.tab_names.append(new_tab_name) - 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() + 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 - response = diaSetupWizard.run() - sys.exit(1) - #end def diaSetupWizard - - def get_menu(self, window): - """returns the menu for this program""" - accel_group = gtk.AccelGroup() - self.item_factory = gtk.ItemFactory(gtk.MenuBar, "
", accel_group) - self.item_factory.create_items(self.menu_items) - window.add_accel_group(accel_group) - return self.item_factory.get_widget("
") - #end def get_menu - - def load_profile(self): - """Loads profile from the provided path name.""" - self.settings = {} - if (os.sep=="/"): - self.settings['os']="linuxmac" - else: - self.settings['os']="windows" + 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 - 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'], + #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", + print " version = %s, requires database version %s" % (VERSION, "118") + #end def dia_about + + def dia_create_del_database(self, widget, data): + print "todo: implement dia_create_del_database" + self.obtain_global_lock() + #end def dia_create_del_database + + def dia_create_del_user(self, widget, data): + print "todo: implement dia_create_del_user" + self.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" + self.obtain_global_lock() + #end def dia_delete_db_parts + + def dia_edit_profile(self, widget=None, data=None, create_default=False, path=None): + print "todo: implement dia_edit_profile" + self.obtain_global_lock() + #end def dia_edit_profile + + def dia_export_db(self, widget, data): + print "todo: implement dia_export_db" + self.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" + self.obtain_global_lock() + #end def dia_import_db + + def dia_licensing(self, widget, data): + print "todo: implement dia_licensing" + #end def dia_licensing + + def dia_load_profile(self, widget, data): + """Dialogue to select a file to load a profile from""" + self.obtain_global_lock() + chooser = gtk.FileChooserDialog(title="Please select a profile file to load", + action=gtk.FILE_CHOOSER_ACTION_OPEN, + buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK)) + chooser.set_filename(self.profile) + + response = chooser.run() + chooser.destroy() + if response == gtk.RESPONSE_OK: + self.load_profile(chooser.get_filename()) + elif response == gtk.RESPONSE_CANCEL: + print 'User cancelled loading profile' + #end def dia_load_profile + + def dia_recreate_tables(self, widget, data): + """Dialogue that asks user to confirm that he wants to delete and recreate the tables""" + self.obtain_global_lock() + dia_confirm=gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, + buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables") + diastring=("Please confirm that you want to (re-)create the tables. If there already are tables in the database "+self.db.database+" on "+self.db.host+" they will be deleted.") + dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted + + response=dia_confirm.run() + dia_confirm.destroy() + if response == gtk.RESPONSE_YES: + self.db.recreate_tables() + elif response == gtk.RESPONSE_NO: + print 'User cancelled recreating tables' + #end def dia_recreate_tables + + def dia_regression_test(self, widget, data): + print "todo: implement dia_regression_test" + self.obtain_global_lock() + #end def dia_regression_test + + def dia_save_profile(self, widget, data): + print "todo: implement dia_save_profile" + #end def dia_save_profile + + def diaSetupWizard(self, path): + print "todo: implement setup wizard" + print "setup wizard not implemented - please create the default configuration file:", path + diaSetupWizard = gtk.Dialog(title="Fatal Error - Config File Missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK)) + + label = gtk.Label("Please copy the config file from the docs folder to:") + diaSetupWizard.vbox.add(label) + label.show() + + label = gtk.Label(path) + diaSetupWizard.vbox.add(label) + label.show() + + label = gtk.Label("and edit it according to the install documentation at http://fpdb.sourceforge.net") + diaSetupWizard.vbox.add(label) + label.show() + + response = diaSetupWizard.run() + sys.exit(1) + #end def diaSetupWizard + + def get_menu(self, window): + """returns the menu for this program""" + accel_group = gtk.AccelGroup() + self.item_factory = gtk.ItemFactory(gtk.MenuBar, "
", accel_group) + self.item_factory.create_items(self.menu_items) + window.add_accel_group(accel_group) + return self.item_factory.get_widget("
") + #end def get_menu + + def load_profile(self): + """Loads profile from the provided path name.""" + self.settings = {} + if (os.sep=="/"): + self.settings['os']="linuxmac" + else: + self.settings['os']="windows" + + self.settings.update(self.config.get_db_parameters()) + self.settings.update(self.config.get_tv_parameters()) + self.settings.update(self.config.get_import_parameters()) + self.settings.update(self.config.get_default_paths()) + + if self.db!=None: + self.db.disconnect() + + self.db = fpdb_db.fpdb_db() + #print "end of fpdb.load_profile, databaseName:",self.settings['db-databaseName'] + self.db.connect(self.settings['db-backend'], self.settings['db-host'], self.settings['db-databaseName'], self.settings['db-user'], self.settings['db-password']) - if self.db.wrongDbVersion: - diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK)) + 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() + label = gtk.Label("An invalid DB version or missing tables have been detected.") + diaDbVersionWarning.vbox.add(label) + label.show() - response = diaDbVersionWarning.run() - diaDbVersionWarning.destroy() + 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() - # 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 + label = gtk.Label("Not doing this will likely lead to misbehaviour including fpdb crashes, corrupt data etc.") + diaDbVersionWarning.vbox.add(label) + label.show() - 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 + response = diaDbVersionWarning.run() + diaDbVersionWarning.destroy() - def tab_player_stats(self, widget, data): - new_ps_thread=GuiPlayerStats.GuiPlayerStats(self.db, self.config, self.querydict) - self.threads.append(new_ps_thread) - ps_tab=new_ps_thread.get_vbox() - self.add_and_display_tab(ps_tab, "Player Stats") + # 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_player_stats(self, widget, data): + new_ps_thread=GuiPlayerStats.GuiPlayerStats(self.db, self.config, self.querydict) + self.threads.append(new_ps_thread) + ps_tab=new_ps_thread.get_vbox() + self.add_and_display_tab(ps_tab, "Player Stats") + + def tab_positional_stats(self, widget, data): + new_ps_thread=GuiPositionalStats.GuiPositionalStats(self.db, self.config, self.querydict) + self.threads.append(new_ps_thread) + ps_tab=new_ps_thread.get_vbox() + self.add_and_display_tab(ps_tab, "Ppositional Stats") - 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! + 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 + self.add_and_display_tab(mh_tab, "Help") + #end def tab_main_help - 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 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 __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 - v%s or higher" % (VERSION, )) - self.window.set_border_width(1) - self.window.set_size_request(1020,400) - self.window.set_resizable(True) - - self.menu_items = ( - ( "/_Main", None, None, 0, "" ), - ( "/Main/_Load Profile (broken)", "L", self.dia_load_profile, 0, None ), - ( "/Main/_Edit Profile (todo)", "E", self.dia_edit_profile, 0, None ), - ( "/Main/_Save Profile (todo)", None, self.dia_save_profile, 0, None ), - ("/Main/sep1", None, None, 0, "" ), - ("/Main/_Quit", "Q", self.quit, 0, None ), - ("/_Import", None, None, 0, "" ), - ("/Import/_Bulk Import", "B", self.tab_bulk_import, 0, None ), - ("/Import/_Auto Import and HUD", "A", self.tab_auto_import, 0, None ), - ("/Import/Auto _Rating (todo)", "R", self.not_implemented, 0, None ), - ("/_Viewers", None, None, 0, "" ), - ("/_Viewers/_Auto Import and HUD", "A", self.tab_auto_import, 0, None ), - ("/Viewers/_Graphs", "G", self.tabGraphViewer, 0, None ), - ("/Viewers/Hand _Replayer (todo)", None, self.not_implemented, 0, None ), - ("/Viewers/Player _Details (todo)", None, self.not_implemented, 0, None ), - ("/Viewers/_Player Stats (tabulated view)", None, self.tab_player_stats, 0, None ), - ("/Viewers/Starting _Hands (todo)", None, self.not_implemented, 0, None ), - ("/Viewers/_Session Replayer (todo)", None, self.not_implemented, 0, None ), - ("/Viewers/Poker_table Viewer (mostly obselete)", "T", self.tab_table_viewer, 0, None ), - #( "/Viewers/Tourney Replayer - ( "/_Database", None, None, 0, "" ), - ( "/Database/Create or Delete _Database (todo)", None, self.dia_create_del_database, 0, None ), - ( "/Database/Create or Delete _User (todo)", None, self.dia_create_del_user, 0, None ), - ( "/Database/Create or Recreate _Tables", None, self.dia_recreate_tables, 0, None ), - ( "/Database/_Statistics (todo)", None, self.dia_database_stats, 0, None ), - ( "/D_ebugging", None, None, 0, "" ), - ( "/Debugging/_Delete Parts of Database (todo)", None, self.dia_delete_db_parts, 0, None ), - ( "/Debugging/_Export DB (todo)", None, self.dia_export_db, 0, None ), - ( "/Debugging/_Import DB (todo)", None, self.dia_import_db, 0, None ), - ( "/Debugging/_Regression test (todo)", None, self.dia_regression_test, 0, None ), - ( "/_Help", None, None, 0, "" ), - ( "/Help/_Main Help", "H", self.tab_main_help, 0, None ), - ( "/Help/_Abbrevations (todo)", None, self.tab_abbreviations, 0, None ), - ( "/Help/sep1", None, None, 0, "" ), - ( "/Help/A_bout (todo)", None, self.dia_about, 0, None ), - ( "/Help/_License and Copying (todo)", None, self.dia_licensing, 0, None ) - ) - - self.main_vbox = gtk.VBox(False, 1) - self.main_vbox.set_border_width(1) - self.window.add(self.main_vbox) - self.main_vbox.show() - - menubar = self.get_menu(self.window) - self.main_vbox.pack_start(menubar, False, True, 0) - menubar.show() - #done menubar - - self.tabs=[] - self.tab_names=[] - self.tab_buttons=[] - self.tab_box = gtk.HBox(False,1) - self.main_vbox.pack_start(self.tab_box, False, True, 0) - self.tab_box.show() - #done tab bar - - self.current_tab = gtk.VBox(False,1) - self.current_tab.set_border_width(1) - self.main_vbox.add(self.current_tab) - self.current_tab.show() - - self.tab_main_help(None, None) - - self.status_bar = gtk.Label("Status: Connected to "+self.db.get_backend_name()+" database named "+self.db.database+" on host "+self.db.host) - self.main_vbox.pack_end(self.status_bar, False, True, 0) - self.status_bar.show() - - self.window.show() - #end def __init__ + def 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 main(self): - gtk.main() - return 0 - #end def main + 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 - v%s or higher" % (VERSION, )) + self.window.set_border_width(1) + self.window.set_size_request(1020,400) + self.window.set_resizable(True) + + self.menu_items = ( + ( "/_Main", None, None, 0, "" ), + ( "/Main/_Load Profile (broken)", "L", self.dia_load_profile, 0, None ), + ( "/Main/_Edit Profile (todo)", "E", self.dia_edit_profile, 0, None ), + ( "/Main/_Save Profile (todo)", None, self.dia_save_profile, 0, None ), + ("/Main/sep1", None, None, 0, "" ), + ("/Main/_Quit", "Q", self.quit, 0, None ), + ("/_Import", None, None, 0, "" ), + ("/Import/_Bulk Import", "B", self.tab_bulk_import, 0, None ), + ("/Import/_Auto Import and HUD", "A", self.tab_auto_import, 0, None ), + ("/Import/Auto _Rating (todo)", "R", self.not_implemented, 0, None ), + ("/_Viewers", None, None, 0, "" ), + ("/_Viewers/_Auto Import and HUD", "A", self.tab_auto_import, 0, None ), + ("/Viewers/_Graphs", "G", self.tabGraphViewer, 0, None ), + ("/Viewers/Hand _Replayer (todo)", None, self.not_implemented, 0, None ), + ("/Viewers/Player _Details (todo)", None, self.not_implemented, 0, None ), + ("/Viewers/_Player Stats (tabulated view)", None, self.tab_player_stats, 0, None ), + ("/Viewers/Positional Stats (tabulated view)", None, self.tab_positional_stats, 0, None ), + ("/Viewers/Starting _Hands (todo)", None, self.not_implemented, 0, None ), + ("/Viewers/_Session Replayer (todo)", None, self.not_implemented, 0, None ), + ("/Viewers/Poker_table Viewer (mostly obselete)", "T", self.tab_table_viewer, 0, None ), + #( "/Viewers/Tourney Replayer + ( "/_Database", None, None, 0, "" ), + ( "/Database/Create or Delete _Database (todo)", None, self.dia_create_del_database, 0, None ), + ( "/Database/Create or Delete _User (todo)", None, self.dia_create_del_user, 0, None ), + ( "/Database/Create or Recreate _Tables", None, self.dia_recreate_tables, 0, None ), + ( "/Database/_Statistics (todo)", None, self.dia_database_stats, 0, None ), + ( "/D_ebugging", None, None, 0, "" ), + ( "/Debugging/_Delete Parts of Database (todo)", None, self.dia_delete_db_parts, 0, None ), + ( "/Debugging/_Export DB (todo)", None, self.dia_export_db, 0, None ), + ( "/Debugging/_Import DB (todo)", None, self.dia_import_db, 0, None ), + ( "/Debugging/_Regression test (todo)", None, self.dia_regression_test, 0, None ), + ( "/_Help", None, None, 0, "" ), + ( "/Help/_Main Help", "H", self.tab_main_help, 0, None ), + ( "/Help/_Abbrevations (todo)", None, self.tab_abbreviations, 0, None ), + ( "/Help/sep1", None, None, 0, "" ), + ( "/Help/A_bout (todo)", None, self.dia_about, 0, None ), + ( "/Help/_License and Copying (todo)", None, self.dia_licensing, 0, None ) + ) + + self.main_vbox = gtk.VBox(False, 1) + self.main_vbox.set_border_width(1) + self.window.add(self.main_vbox) + self.main_vbox.show() + + menubar = self.get_menu(self.window) + self.main_vbox.pack_start(menubar, False, True, 0) + menubar.show() + #done menubar + + self.tabs=[] + self.tab_names=[] + self.tab_buttons=[] + self.tab_box = gtk.HBox(False,1) + self.main_vbox.pack_start(self.tab_box, False, True, 0) + self.tab_box.show() + #done tab bar + + self.current_tab = gtk.VBox(False,1) + self.current_tab.set_border_width(1) + self.main_vbox.add(self.current_tab) + self.current_tab.show() + + self.tab_main_help(None, None) + + self.status_bar = gtk.Label("Status: Connected to "+self.db.get_backend_name()+" database named "+self.db.database+" on host "+self.db.host) + self.main_vbox.pack_end(self.status_bar, False, True, 0) + self.status_bar.show() + + self.window.show() + #end def __init__ + + def main(self): + gtk.main() + return 0 + #end def main if __name__ == "__main__": - me = fpdb() - me.main() + me = fpdb() + me.main()