📄 userinterface.py
字号:
def _buildTrainBox(self): """Returns a "Train on a given message" box. This is used on both the Home page and the training results page. The Train form is based on the Upload form.""" form = self.html.upload.clone() del form.submit_classify return self._buildBox(_("Train on a message, mbox file or dbx file"), 'message.gif', form) def reReadOptions(self): """Called by the config page when the user saves some new options, or restores the defaults.""" pass def onExperimentalconfig(self): html = self._buildConfigPage(experimental_ini_map) html.title = _('Home > Experimental Configuration') html.pagename = _('> Experimental Configuration') html.adv_button.name.value = _("Back to basic configuration") html.adv_button.action = "config" html.config_submit.value = _("Save experimental options") html.restore.value = _("Restore experimental options defaults (all off)") del html.exp_button self.writeOKHeaders('text/html') self.write(html) def onAdvancedconfig(self): html = self._buildConfigPage(self.advanced_options_map) html.title = _('Home > Advanced Configuration') html.pagename = _('> Advanced Configuration') html.adv_button.name.value = _("Back to basic configuration") html.adv_button.action = "config" html.config_submit.value = _("Save advanced options") html.restore.value = _("Restore advanced options defaults") del html.exp_button self.writeOKHeaders('text/html') self.write(html) def onConfig(self): html = self._buildConfigPage(self.parm_ini_map) html.title = _('Home > Configure') html.pagename = _('> Configure') self.writeOKHeaders('text/html') self.write(html) def _buildConfigPage(self, parm_map): # Start with an empty config form then add the sections. html = self._getHTMLClone() # "Save and Shutdown" is confusing here - it means "Save database" # but that's not clear. html.shutdownTableCell = " " html.mainContent = self.html.configForm.clone() html.mainContent.configFormContent = "" html.mainContent.optionsPathname = cgi.escape(optionsPathname) return self._buildConfigPageBody(html, parm_map) def _buildConfigPageBody(self, html, parm_map): configTable = None section = None # Loop though the sections. for sect, opt in parm_map: # We need a string to use as the html key that we can change to # and from the sect, opt pair. We like irony, so we use '_' as # the delimiter <wink>. if opt is None: if configTable is not None and section is not None: # Finish off the box for this section and add it # to the form. section.boxContent = configTable html.configFormContent += section # Start the yellow-headed box for this section. section = self.html.headedBox.clone() # Get a clone of the config table and a clone of each # example row, then blank out the example rows to make way # for the real ones. configTable = self.html.configTable.clone() configTextRow1 = configTable.configTextRow1.clone() configTextRow2 = configTable.configTextRow2.clone() configCbRow1 = configTable.configCbRow1.clone() configRow2 = configTable.configRow2.clone() blankRow = configTable.blankRow.clone() del configTable.configTextRow1 del configTable.configTextRow2 del configTable.configCbRow1 del configTable.configRow2 del configTable.blankRow del configTable.folderRow section.heading = sect del section.iconCell continue html_key = sect + '_' + opt # Annoyingly, we have a special case. The notate_to and # notate_subject allowed values have to be set to the same # values as the header_x_ options. See also sf #944109. # This code was originally in Options.py, after loading in the # options. But that doesn't work, because if we are setting # both in a config file, we need it done immediately. # We now need the hack here, *and* in OptionsClass.py if sect == "Headers" and opt in ("notate_to", "notate_subject"): valid_input = (options["Headers", "header_ham_string"], options["Headers", "header_spam_string"], options["Headers", "header_unsure_string"]) else: valid_input = options.valid_input(sect, opt) # Populate the rows with the details and add them to the table. if isinstance(valid_input, types.StringTypes): # we provide a text input newConfigRow1 = configTextRow1.clone() newConfigRow1.label = options.display_name(sect, opt) newConfigRow1.input.name = html_key newConfigRow1.input.value = options.unconvert(sect, opt) else: # we provide checkboxes/radio buttons newConfigRow1 = configCbRow1.clone() newConfigRow1.label = options.display_name(sect, opt) blankOption = newConfigRow1.input.clone() firstOpt = True i = 0 for val in valid_input: newOption = blankOption.clone() if options.multiple_values_allowed(sect, opt): if val in options[sect, opt]: newOption.input_box.checked = "checked" newOption.input_box.type = "checkbox" newOption.input_box.name = html_key + '-' + str(i) i += 1 else: if val == options[sect, opt]: newOption.input_box.checked = "checked" newOption.input_box.type = "radio" newOption.input_box.name = html_key # Tim thinks that Yes/No makes more sense than True/False if options.is_boolean(sect, opt): if val is True: val = "Yes" elif val is False: val = "No" newOption.val_label = str(val) newOption.input_box.value = str(val) if firstOpt: newConfigRow1.input = newOption firstOpt = False else: newConfigRow1.input += newOption # Insert the help text in a cell newConfigRow1.helpCell = '<strong>' + \ options.display_name(sect, opt) + \ ':</strong> ' + \ cgi.escape(options.doc(sect, opt)) newConfigRow2 = configRow2.clone() currentValue = options[sect, opt] if type(currentValue) in types.StringTypes: currentValue = currentValue.replace(',', ', ') newConfigRow2 = configTextRow2.clone() else: currentValue = options.unconvert(sect, opt) newConfigRow2 = configRow2.clone() # Tim thinks that Yes/No makes more sense than True/False if options.is_boolean(sect, opt): if currentValue == "False": currentValue = _("No") elif currentValue == "True": currentValue = _("Yes") # XXX Something needs to be done here, otherwise really # XXX long options squeeze the help text too far to the # XXX right. Browsers can't wrap the text (even if # XXX no-wrap is False) unless there is whitespace to # XXX wrap on - comma's don't count. This works, but # XXX it's a bit ugly. Ideas? # currentValue = str(currentValue).replace(',', '<br />') newConfigRow2.currentValue = currentValue configTable += newConfigRow1 + newConfigRow2 + blankRow # Finish off the box for this section and add it to the form. if section is not None: section.boxContent = configTable html.configFormContent += section return html def onChangeopts(self, **parms): pmap = self.parm_ini_map if parms.has_key("how"): if parms["how"] == _("Save advanced options"): pmap = self.advanced_options_map elif parms["how"] == _("Save experimental options"): pmap = experimental_ini_map del parms["how"] html = self._getHTMLClone() html.shutdownTableCell = " " html.mainContent = self.html.headedBox.clone() errmsg = self.verifyInput(parms, pmap) if errmsg != '': html.mainContent.heading = _("Errors Detected") html.mainContent.boxContent = errmsg html.title = _('Home > Error') html.pagename = _('> Error') self.writeOKHeaders('text/html') self.write(html) return old_database_type = options["Storage", "persistent_use_database"] old_name = options["Storage", "persistent_storage_file"] for name, value in parms.items(): sect, opt = name.split('_', 1) if (sect, opt) in pmap: options.set(sect, opt, value) # If a section name has an underscore in it (like html_ui) # the split won't work the first time else: sect2, opt = opt.split('_', 1) sect += '_' + sect2 options.set(sect, opt, value) options.update_file(optionsPathname) # If the database type changed, then convert it for them. if options["Storage", "persistent_use_database"] != \ old_database_type and os.path.exists(old_name): new_name = options["Storage", "persistent_storage_file"] new_type = options["Storage", "persistent_use_database"] self.close_database() try: os.remove(new_name + ".tmp") except OSError: pass storage.convert(old_name, old_database_type, new_name + ".tmp", new_type) if os.path.exists(new_name): try: os.remove(new_name + ".old") except OSError: pass os.rename(new_name, new_name + ".old") os.rename(new_name + ".tmp", new_name) # Messageinfo db is not converted. if os.path.exists(options["Storage", "messageinfo_storage_file"]): try: os.remove(options["Storage", "messageinfo_storage_file"] + ".old") except OSError: pass os.rename(options["Storage", "messageinfo_storage_file"], options["Storage", "messageinfo_storage_file"] + ".old") self.reReadOptions() html.mainContent.heading = _("Options Changed") html.mainContent.boxContent = _("Options changed. Return " \ "<a href='home'>Home</a>.") html.title = _('Home > Options Changed') html.pagename = _('> Options Changed') self.writeOKHeaders('text/html') self.write(html) def onRestoredefaults(self, how): if how == _("Restore advanced options defaults"): self.restoreConfigDefaults(self.advanced_options_map) elif how == _("Restore experimental options defaults (all off)"): self.restoreConfigDefaults(experimental_ini_map) else: self.restoreConfigDefaults(self.parm_ini_map) self.reReadOptions() html = self._getHTMLClone() html.shutdownTableCell = " " html.mainContent = self.html.headedBox.clone() html.mainContent.heading = _("Option Defaults Restored") html.mainContent.boxContent = _("Defaults restored. Return " \ "<a href='home'>Home</a>.") html.title = _('Home > Defaults Restored') html.pagename = _('> Defaults Restored') self.writeOKHeaders('text/html') self.write(html) self.reReadOptions() def verifyInput(self, parms, pmap): '''Check that the given input is valid.''' # Most of the work here is done by the options class, but # we may have a few extra checks that are beyond its capabilities errmsg = '' # mumbo-jumbo to deal with the checkboxes # XXX This will break with more than 9 checkboxes # XXX A better solution is needed than this for name, value in parms.items(): if name[-2:-1] == '-': if parms.has_key(name[:-2]): parms[name[:-2]] += (value,) else: parms[name[:-2]] = (value,) del parms[name] for sect, opt in pmap: if opt is None: nice_section_name = sect continue # Annoyingly, we have a special case. The notate_to and # notate_subject allowed values have to be set to the same # values as the header_x_ options. See also sf #944109. # This code was originally in Options.py, after loading in the # options. But that doesn't work, because if we are setting # both in a config file, we need it done immediately.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -