📄 userinterface.py
字号:
# 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) html_key = sect + '_' + opt if not parms.has_key(html_key): # This is a set of checkboxes where none are selected value = () entered_value = "None" else: value = parms[html_key] entered_value = value # Tim thinks that Yes/No makes more sense than True/False if options.is_boolean(sect, opt): if value == _("No"): value = False elif value == _("Yes"): value = True if options.multiple_values_allowed(sect, opt) and \ value == "": value = () value = options.convert(sect, opt, value) if not options.is_valid(sect, opt, value): errmsg += _('<li>\'%s\' is not a value valid for [%s] %s') % \ (entered_value, nice_section_name, options.display_name(sect, opt)) if isinstance(valid_input, types.TupleType): errmsg += _('. Valid values are: ') for valid in valid_input: errmsg += str(valid) + ',' errmsg = errmsg[:-1] # cut last ',' errmsg += '</li>' parms[html_key] = value return errmsg def restoreConfigDefaults(self, parm_map): # note that the behaviour of this function has subtly changed: # previously options were removed from the config file, now the # config file is updated to match the defaults d = OptionsClass() d.load_defaults(defaults) # Only restore the settings that appear on the form. for section, option in parm_map: if option is not None: if not options.no_restore(section, option): options.set(section, option, d.get(section,option)) options.update_file(optionsPathname) def onHelp(self, topic=None): """Provide a help page, either the default if topic is not supplied, or specific to the topic given.""" self._writePreamble(_("Help")) helppage = self.html.helppage.clone() if topic: # Present help specific to a certain page. headerelem_name = "helpheader_" + topic textelem_name = "helptext_" + topic try: helppage.helpheader = self.html[headerelem_name]._content helppage.helptext = self.html[textelem_name]._content % \ { "cache_expiry_days": options["Storage", "cache_expiry_days"] } except KeyError: pass self.write(helppage) self._writePostamble() def onStats(self): """Provide statistics about previous SpamBayes activity.""" self._writePreamble(_("Statistics")) if self.stats: stats = self.stats.GetStats(use_html=True) stats = self._buildBox(_("Statistics"), None, "<br/><br/>".join(stats)) else: stats = self._buildBox(_("Statistics"), None, _("Statistics not available")) self.write(stats) self._writePostamble(help_topic="stats") def onBugreport(self): """Create a message to post to spambayes@python.org that hopefully has enough information for us to help this person with their problem.""" self._writePreamble(_("Send Help Message"), ("help", _("Help"))) report = self.html.bugreport.clone() # Prefill the report v = Version.get_current_version() sb_ver = v.get_long_version(self.app_for_version) if hasattr(sys, "frozen"): sb_type = "binary" else: sb_type = "source" py_ver = sys.version try: # Use "Windows" instead of "nt" or people might be confused. os_name = "Windows %d.%d.%d.%d (%s)" % sys.getwindowsversion() except AttributeError: # Not available in non-Windows, or pre 2.3 os_name = os.name report.message_body = "I am using %s (%s), with version %s of " \ "Python; my operating system is %s. I have " \ "trained %d ham and %d spam.\n\nThe problem " \ "I am having is [DESCRIBE YOUR PROBLEM HERE] " \ % (sb_ver, sb_type, py_ver, os_name, self.classifier.nham, self.classifier.nspam) remote_servers = options["pop3proxy", "remote_servers"] if remote_servers: domain_guess = remote_servers[0] for pre in ["pop.", "pop3.", "mail.",]: if domain_guess.startswith(pre): domain_guess = domain_guess[len(pre):] else: domain_guess = "[YOUR ISP]" report.from_addr.value = "[YOUR EMAIL ADDRESS]@%s" % (domain_guess,) report.subject.value = "Problem with %s: [PROBLEM SUMMARY]" % \ (self.app_for_version,) # If the user has a log file, attach it. try: import win32api except ImportError: pass else: if hasattr(sys, "frozen"): temp_dir = win32api.GetTempPath() for name in ["SpamBayesService", "SpamBayesServer",]: for i in xrange(3): pn = os.path.join(temp_dir, "%s%d.log" % (name, (i+1))) if os.path.exists(pn): # I can't seem to set a default value for a # "File" input type, so have to change it to # "Text" if one is found. report.file.type = "text" report.file.value = pn # For the moment, just attach the first one # we find. break if report.file.value: break try: smtp_server = options["smtpproxy", "remote_servers"][0] except IndexError: smtp_server = None if not smtp_server: self.write(self._buildBox(_("Warning"), "status.gif", _("You will be unable to send this message from " \ "this page, as you do not have your SMTP " \ "server's details entered in your configuration. " \ "Please either <a href='config'>enter those " \ "details</a>, or copy the text below into your " \ "regular mail application."))) del report.submitrow self.write(report) self._writePostamble() def onSubmitreport(self, from_addr, message, subject, attach): """Send the help message/bug report to the specified address.""" # For guessing MIME type based on file name extension import mimetypes from email import Encoders from email.MIMEBase import MIMEBase from email.MIMEAudio import MIMEAudio from email.MIMEMultipart import MIMEMultipart from email.MIMEImage import MIMEImage from email.MIMEText import MIMEText if not self._verifyEnteredDetails(from_addr, subject, message): self._writePreamble(_("Error"), ("help", _("Help"))) self.write(self._buildBox(_("Error"), "status.gif", _("You must fill in the details that " \ "describe your specific problem " \ "before you can send the message."))) else: self._writePreamble(_("Sent"), ("help", _("Help"))) mailer = smtplib.SMTP(options["smtpproxy", "remote_servers"][0]) # Create the enclosing (outer) message outer = MIMEMultipart() outer['Subject'] = subject # Force the message to "spambayes@python.org", rather than # letting the user choose. outer['To'] = '"SpamBayes Mailing List" <spambayes@python.org>' # Always cc the user, so that they get a copy of the message, # even if they're not subscribed to the list. outer['CC'] = from_addr outer['From'] = from_addr v = Version.get_current_version() outer['X-Mailer'] = v.get_long_version(self.app_for_version) outer.preamble = self._wrap(message) # To guarantee the message ends with a newline outer.epilogue = '' # Guess the content type based on the file's extension. try: ctype, encoding = mimetypes.guess_type(attach) if ctype is None or encoding is not None: # No guess could be made, or the file is encoded # (compressed), so use a generic bag-of-bits type. ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) if maintype == 'text': fp = open(attach) # Note: we should handle calculating the charset msg = MIMEText(fp.read(), _subtype=subtype) fp.close() elif maintype == 'image': fp = open(attach, 'rb') msg = MIMEImage(fp.read(), _subtype=subtype) fp.close() elif maintype == 'audio': fp = open(attach, 'rb') msg = MIMEAudio(fp.read(), _subtype=subtype) fp.close() else: fp = open(attach, 'rb') msg = MIMEBase(maintype, subtype) msg.set_payload(fp.read()) fp.close() # Encode the payload using Base64 Encoders.encode_base64(msg) except IOError: # Couldn't access the file, so don't attach it. pass else: # Set the filename parameter msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(attach)) outer.attach(msg) msg = MIMEText(self._wrap(message)) outer.attach(msg) recips = [] # If you are testing, then make sure you change this # address to something else, so that you don't bombard the # list with messages. for r in ["spambayes@python.org", from_addr]: if r: recips.append(r) mailer.sendmail(from_addr, recips, outer.as_string()) self.write(_("Sent message. Please do not send again, or " \ "refresh this page!")) self._writePostamble() def _verifyEnteredDetails(self, from_addr, subject, message): """Ensure that the user didn't just send the form message, and at least changed the fields.""" if from_addr.startswith(_("[YOUR EMAIL ADDRESS]")): return False if message.endswith(_("[DESCRIBE YOUR PROBLEM HERE]")): return False if subject.endswith(_("[PROBLEM SUMMARY]")): return False return True def _wrap(self, text, width=70): """Wrap the text into lines no bigger than the specified width.""" try: from textwrap import fill except ImportError: pass else: return "\n".join([fill(paragraph, width) \ for paragraph in text.split('\n')]) # No textwrap module, so do the same stuff (more-or-less) ourselves. def fill(text, width): if len(text) <= width: return text wordsep_re = re.compile(r'(-*\w{2,}-(?=\w{2,})|' # hyphenated words r'(?<=\S)-{2,}(?=\w))') # em-dash chunks = wordsep_re.split(text) chunks = filter(None, chunks) return '\n'.join(self._wrap_chunks(chunks, width)) return "\n".join([fill(paragraph, width) \ for paragraph in text.split('\n')]) def _wrap_chunks(self, chunks, width): """Stolen from textwrap; see that module in Python >= 2.3 for details.""" lines = [] while chunks: cur_line = [] cur_len = 0 if chunks[0].strip() == '' and lines: del chunks[0] while chunks: l = len(chunks[0]) if cur_len + l <= width: cur_line.append(chunks.pop(0)) cur_len += l else: break if chunks and len(chunks[0]) > width: space_left = width - cur_len cur_line.append(chunks[0][0:space_left]) chunks[0] = chunks[0][space_left:] if cur_line and cur_line[-1].strip() == '': del cur_line[-1] if cur_line: lines.append(''.join(cur_line)) return lines
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -