From 6a999f4232b2066021fb46770f7b33fbcb5058bf Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 20 Jun 2010 17:47:23 +0100 Subject: [PATCH 1/9] change shortcut key for import button so that it still works when button label is 'I M P O R T I N G' --- pyfpdb/GuiAutoImport.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyfpdb/GuiAutoImport.py b/pyfpdb/GuiAutoImport.py index 6dd67ba5..5ff28703 100755 --- a/pyfpdb/GuiAutoImport.py +++ b/pyfpdb/GuiAutoImport.py @@ -100,7 +100,7 @@ class GuiAutoImport (threading.Thread): hbox.pack_start(lbl1, expand=True, fill=False) self.doAutoImportBool = False - self.startButton = gtk.ToggleButton(" _Start Autoimport ") + self.startButton = gtk.ToggleButton(" Start Autoimpor_t ") self.startButton.connect("clicked", self.startClicked, "start clicked") hbox.pack_start(self.startButton, expand=False, fill=False) @@ -153,7 +153,7 @@ class GuiAutoImport (threading.Thread): def do_import(self): """Callback for timer to do an import iteration.""" if self.doAutoImportBool: - self.startButton.set_label(u' I M P O R T I N G ') + self.startButton.set_label(u' I M P O R _T I N G ') self.importer.runUpdated() self.addText(".") #sys.stdout.write(".") @@ -164,9 +164,9 @@ class GuiAutoImport (threading.Thread): def reset_startbutton(self): if self.pipe_to_hud is not None: - self.startButton.set_label(u' _Stop Autoimport ') + self.startButton.set_label(u' Stop Autoimpor_t ') else: - self.startButton.set_label(u' _Start Autoimport ') + self.startButton.set_label(u' Start Autoimpor_t ') return False @@ -243,7 +243,7 @@ class GuiAutoImport (threading.Thread): #print >>self.pipe_to_hud.stdin, "\n" self.pipe_to_hud.communicate('\n') # waits for process to terminate self.pipe_to_hud = None - self.startButton.set_label(u' _Start Autoimport ') + self.startButton.set_label(u' Start Autoimpor_t ') #end def GuiAutoImport.startClicked From 1d263c81393ab780c5d1a82914ce4250060c63cf Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 11 Jul 2010 18:36:45 +0100 Subject: [PATCH 2/9] fix call to db.connected() --- pyfpdb/fpdb.pyw | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw index 4554827c..e4d48cf1 100755 --- a/pyfpdb/fpdb.pyw +++ b/pyfpdb/fpdb.pyw @@ -66,6 +66,7 @@ cl_options = string.join(sys.argv[1:]) (options, argv) = Options.fpdb_options() import logging, logging.config +log = logging.getLogger("fpdb") try: import pygtk @@ -854,9 +855,10 @@ class fpdb: print "Quitting normally" # TODO: check if current settings differ from profile, if so offer to save or abort try: - if self.db is not None and self.db.connected: + if self.db is not None and self.db.connected(): self.db.disconnect() except _mysql_exceptions.OperationalError: # oh, damn, we're already disconnected + log.info("fpdb.quit disconnect error being ignored: "+str(sys.exc_info())) pass self.statusIcon.set_visible(False) From 45fa170758dd72409349bf44803730594b4386d7 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 11 Jul 2010 18:53:26 +0100 Subject: [PATCH 3/9] comment out close of fpdb after db recreate, I don't see how it helps --- pyfpdb/fpdb.pyw | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw index e4d48cf1..473c4641 100755 --- a/pyfpdb/fpdb.pyw +++ b/pyfpdb/fpdb.pyw @@ -424,12 +424,18 @@ class fpdb: # TODO: figure out why this seems to be necessary dia_restart = gtk.MessageDialog(parent=self.window, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_OK), message_format="Restart fpdb") - diastring = "Fpdb now needs to close. Please restart it." - dia_restart.format_secondary_text(diastring) - - dia_restart.run() - dia_restart.destroy() - self.quit(None, None) + + # sc: I don't see the need for this closedown - if it is a problem let me know + # and I will look into it .... (if there is a problem with db re-create I + # would expect it to be before here, i.e. maybe user needs to restart before + # the re-create. Once here everything should be ok.) + # The recreate will not work if autoimport is running! Other than that it + # should work. + #diastring = "Fpdb now needs to close. Please restart it." + #dia_restart.format_secondary_text(diastring) + #dia_restart.run() + #dia_restart.destroy() + #self.quit(None, None) elif response == gtk.RESPONSE_NO: self.release_global_lock() print 'User cancelled recreating tables' From b52110d45f94ac725a374c9cb34162739298d5df Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 11 Jul 2010 19:00:27 +0100 Subject: [PATCH 4/9] change tabs to spaces --- pyfpdb/fpdb.pyw | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw index 473c4641..3c42ae1c 100755 --- a/pyfpdb/fpdb.pyw +++ b/pyfpdb/fpdb.pyw @@ -36,9 +36,9 @@ if os.name == 'nt' and sys.version[0:3] not in ('2.5', '2.6') and '-r' not in sy print "Python " + sys.version[0:3] + ' - press return to continue\n' sys.stdin.readline() if os.name=='nt': - os.execvpe('pythonw.exe', ('pythonw.exe', 'fpdb.pyw', '-r'), os.environ) # first arg is ignored (name of program being run) - else: - os.execvpe('python', ('python', 'fpdb.pyw', '-r'), os.environ) # first arg is ignored (name of program being run) + os.execvpe('pythonw.exe', ('pythonw.exe', 'fpdb.pyw', '-r'), os.environ) # first arg is ignored (name of program being run) + else: + os.execvpe('python', ('python', 'fpdb.pyw', '-r'), os.environ) # first arg is ignored (name of program being run) else: print "\npython 2.5 not found, please install python 2.5 or 2.6 for fpdb\n" raw_input("Press ENTER to continue.") @@ -437,7 +437,7 @@ class fpdb: #dia_restart.destroy() #self.quit(None, None) elif response == gtk.RESPONSE_NO: - self.release_global_lock() + self.release_global_lock() print 'User cancelled recreating tables' #if not lock_released: #end def dia_recreate_tables From 02e1a7159202cb0e87daa865cb1394a1c8cf8e8e Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Tue, 13 Jul 2010 20:21:34 +0100 Subject: [PATCH 5/9] fix broken graphing --- pyfpdb/SQL.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 96a45d2c..ed74e9d2 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -2828,7 +2828,7 @@ class Sql: AND h.startTime < '' - AND gt.type is 'ring' + AND gt.type = 'ring' GROUP BY h.startTime, hp.handId, hp.sawShowdown, hp.totalProfit ORDER BY h.startTime""" From d78d69e9f4f8dce057db4721468d79bd8a3ffc53 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Tue, 13 Jul 2010 21:19:18 +0100 Subject: [PATCH 6/9] miss out fl/pl/nl checkbox if no relevant hands --- pyfpdb/RingFilters.py | 49 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/pyfpdb/RingFilters.py b/pyfpdb/RingFilters.py index db7ed4de..5a057937 100644 --- a/pyfpdb/RingFilters.py +++ b/pyfpdb/RingFilters.py @@ -66,6 +66,7 @@ class RingFilters(Filters.Filters): # Outer Packing box self.mainVBox = gtk.VBox(False, 0) + self.found = {'nl':False, 'fl':False, 'pl':False, 'ring':False, 'tour':False} self.label = {} self.callback = {} @@ -364,7 +365,7 @@ class RingFilters(Filters.Filters): #end def __set_game_select def __set_limit_select(self, w, limit): - #print w.get_active() + #print "__set_limit_select: limit =", limit, w.get_active() self.limits[limit] = w.get_active() log.debug("self.limit[%s] set to %s" %(limit, self.limits[limit])) if limit.isdigit() or (len(limit) > 2 and (limit[-2:] == 'nl' or limit[-2:] == 'fl' or limit[-2:] == 'pl')): @@ -488,7 +489,7 @@ class RingFilters(Filters.Filters): if self.limits[limit]: self.type = "ring" for cb in self.cbLimits.values(): - #print "cb label: ", cb.children()[0].get_text() + print "ring: cb label: ", cb.children()[0].get_text() if self.types[cb.get_children()[0].get_text()] == 'tour': cb.set_active(False) elif limit == "tour": @@ -627,7 +628,7 @@ class RingFilters(Filters.Filters): self.cursor.execute(self.sql.query['getCashLimits']) # selects limitType, bigBlind result = self.db.cursor.fetchall() - found = {'nl':False, 'fl':False, 'pl':False, 'ring':False, 'tour':False} + self.found = {'nl':False, 'fl':False, 'pl':False, 'ring':False, 'tour':False} if len(result) >= 1: hbox = gtk.HBox(True, 0) @@ -648,16 +649,16 @@ class RingFilters(Filters.Filters): if True: #line[0] == 'ring': if line[1] == 'fl': name = str(line[2]) - found['fl'] = True + self.found['fl'] = True elif line[1] == 'pl': name = str(line[2])+line[1] - found['pl'] = True + self.found['pl'] = True else: name = str(line[2])+line[1] - found['nl'] = True + self.found['nl'] = True self.cbLimits[name] = self.createLimitLine(hbox, name, name) self.types[name] = line[0] - found[line[0]] = True # type is ring/tour + self.found[line[0]] = True # type is ring/tour self.type = line[0] # if only one type, set it now if "LimitSep" in display and display["LimitSep"] == True and len(result) >= 2: hbox = gtk.HBox(True, 0) @@ -675,24 +676,30 @@ class RingFilters(Filters.Filters): self.cbNoLimits = self.createLimitLine(hbox, 'none', self.filterText['limitsnone']) dest = vbox3 # for ring/tour buttons - if "LimitType" in display and display["LimitType"] == True and found['nl'] and found['fl']: - #if found['fl']: - hbox = gtk.HBox(False, 0) - vbox3.pack_start(hbox, False, False, 0) - self.cbFL = self.createLimitLine(hbox, 'fl', self.filterText['limitsFL']) - #if found['nl']: - hbox = gtk.HBox(False, 0) - vbox3.pack_start(hbox, False, False, 0) - self.cbNL = self.createLimitLine(hbox, 'nl', self.filterText['limitsNL']) - hbox = gtk.HBox(False, 0) - vbox3.pack_start(hbox, False, False, 0) - self.cbPL = self.createLimitLine(hbox, 'pl', self.filterText['limitsPL']) - dest = vbox2 # for ring/tour buttons + if "LimitType" in display and display["LimitType"] == True: + num_limit_types = 0 + if self.found['fl']: num_limit_types = num_limit_types + 1 + if self.found['pl']: num_limit_types = num_limit_types + 1 + if self.found['nl']: num_limit_types = num_limit_types + 1 + if num_limit_types > 1: + if self.found['fl']: + hbox = gtk.HBox(False, 0) + vbox3.pack_start(hbox, False, False, 0) + self.cbFL = self.createLimitLine(hbox, 'fl', self.filterText['limitsFL']) + if self.found['nl']: + hbox = gtk.HBox(False, 0) + vbox3.pack_start(hbox, False, False, 0) + self.cbNL = self.createLimitLine(hbox, 'nl', self.filterText['limitsNL']) + if self.found['pl']: + hbox = gtk.HBox(False, 0) + vbox3.pack_start(hbox, False, False, 0) + self.cbPL = self.createLimitLine(hbox, 'pl', self.filterText['limitsPL']) + dest = vbox2 # for ring/tour buttons else: print "INFO: No games returned from database" log.info("No games returned from database") - if "Type" in display and display["Type"] == True and found['ring'] and found['tour']: + if "Type" in display and display["Type"] == True and self.found['ring'] and self.found['tour']: rb1 = gtk.RadioButton(None, self.filterText['ring']) rb1.connect('clicked', self.__set_limit_select, 'ring') rb2 = gtk.RadioButton(rb1, self.filterText['tour']) From 666161042950f90beaca088fad8fa0ff925224d4 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Tue, 13 Jul 2010 21:22:40 +0100 Subject: [PATCH 7/9] comment out debug msg --- pyfpdb/RingFilters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/RingFilters.py b/pyfpdb/RingFilters.py index 5a057937..47bd5d6f 100644 --- a/pyfpdb/RingFilters.py +++ b/pyfpdb/RingFilters.py @@ -489,7 +489,7 @@ class RingFilters(Filters.Filters): if self.limits[limit]: self.type = "ring" for cb in self.cbLimits.values(): - print "ring: cb label: ", cb.children()[0].get_text() + #print "cb label: ", cb.children()[0].get_text() if self.types[cb.get_children()[0].get_text()] == 'tour': cb.set_active(False) elif limit == "tour": From b07505d3672c5dfcd71f093bc5fc21abe9f3e487 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Tue, 13 Jul 2010 21:23:32 +0100 Subject: [PATCH 8/9] tidy up closedown --- pyfpdb/Database.py | 1 + pyfpdb/fpdb.pyw | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index bf0ed73b..e6b72c1e 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -521,6 +521,7 @@ class Database: self.connection.commit() self.cursor.close() self.connection.close() + self.__connected = False def reconnect(self, due_to_error=False): """Reconnects the DB""" diff --git a/pyfpdb/fpdb.pyw b/pyfpdb/fpdb.pyw index 1203246f..27c5fd6d 100755 --- a/pyfpdb/fpdb.pyw +++ b/pyfpdb/fpdb.pyw @@ -849,18 +849,21 @@ class fpdb: def quit(self, widget, data=None): # TODO: can we get some / all of the stuff done in this function to execute on any kind of abort? #FIXME get two "quitting normally" messages, following the addition of the self.window.destroy() call - print "Quitting normally" + # ... because self.window.destroy() leads to self.destroy() which calls this! + if not self.quitting: + print "Quitting normally" + self.quitting = True # TODO: check if current settings differ from profile, if so offer to save or abort if self.db!=None: if self.db.backend==self.db.MYSQL_INNODB: try: - if self.db is not None and self.db.connected: + if self.db is not None and self.db.connected(): self.db.disconnect() except _mysql_exceptions.OperationalError: # oh, damn, we're already disconnected pass else: - if self.db is not None and self.db.connected: + if self.db is not None and self.db.connected(): self.db.disconnect() else: pass @@ -945,6 +948,7 @@ You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt and gpl-3.0.txt self.lock = interlocks.InterProcessLock(name="fpdb_global_lock") self.db = None self.status_bar = None + self.quitting = False self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.connect("delete_event", self.delete_event) From 397e87b8009852105c10b4483405aebebacf1fa2 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Tue, 13 Jul 2010 23:12:50 +0100 Subject: [PATCH 9/9] autoimport passes filenames to fpdb_import as unicode, so make bulk import do this as well so that add_import_file() always gets same type --- pyfpdb/fpdb_import.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index ac569c95..eeaa63ac 100755 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -152,7 +152,9 @@ class Importer: #Add an individual file to filelist def addImportFile(self, filename, site = "default", filter = "passthrough"): #TODO: test it is a valid file -> put that in config!! - if filename in self.filelist or not os.path.exists(unicode(filename,'utf-8')): + #print "addimportfile: filename is a", filename.__class__ + # filename now comes in as unicode + if filename in self.filelist or not os.path.exists(filename): return self.filelist[filename] = [site] + [filter] if site not in self.siteIds: @@ -177,10 +179,11 @@ class Importer: if os.path.isdir(inputPath): for subdir in os.walk(inputPath): for file in subdir[2]: - self.addImportFile(os.path.join(subdir[0], file), site=site, - filter=filter) + self.addImportFile(unicode(os.path.join(subdir[0], file),'utf-8'), + site=site, filter=filter) else: - self.addImportFile(inputPath, site=site, filter=filter) + + self.addImportFile(unicode(inputPath,'utf-8'), site=site, filter=filter) #Add a directory of files to filelist #Only one import directory per site supported. #dirlist is a hash of lists: @@ -406,7 +409,8 @@ class Importer: conv = None (stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, time()) - file = file.decode("utf-8") #(Configuration.LOCALE_ENCODING) + # sc: is there any need to decode this? maybe easier to skip it than guess at the encoding? + #file = file.decode("utf-8") #(Configuration.LOCALE_ENCODING) # Load filter, process file, pass returned filename to import_fpdb_file if self.settings['threads'] > 0 and self.writeq is not None: