⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxyui.py

📁 用python实现的邮件过滤器
💻 PY
📖 第 1 页 / 共 3 页
字号:
                            options["Headers", "header_spam_string"]: [],                            }        invalid_keys = []        for key in keys:            if isinstance(key, types.TupleType):                key, sourceCorpus = key            else:                sourceCorpus = state.unknownCorpus            # Parse the message, get the judgement header and build a message            # info object for each message.            message = sourceCorpus[key]            try:                message.load()            except IOError:                # Someone has taken this file away from us.  It was                # probably a virus protection program, so that's ok.                # Don't list it in the review, though.                invalid_keys.append(key)                continue            judgement = message[options["Headers",                                        "classification_header_name"]]            if judgement is None:                judgement = options["Headers", "header_unsure_string"]            else:                judgement = judgement.split(';')[0].strip()            messageInfo = self._makeMessageInfo(message)            keyedMessageInfo[judgement].append((key, messageInfo))        for key in invalid_keys:            keys.remove(key)        # Present the list of messages in their groups in reverse order of        # appearance, by default, or according to the specified sort order.        if keys:            page = self.html.reviewtable.clone()            if prior:                page.prior.value = prior                del page.priorButton.disabled            if next:                page.next.value = next                del page.nextButton.disabled            templateRow = page.reviewRow.clone()            # The decision about whether to reverse the sort            # order has to go here, because _sortMessages gets called            # thrice, and so the ham list would end up sorted backwards.            sort_order = params.get('sort')            if self.previous_sort == sort_order:                reverse = True                self.previous_sort = None            else:                reverse = False                self.previous_sort = sort_order            page.table = ""  # To make way for the real rows.            for header, label in ((options["Headers",                                           "header_unsure_string"], 'Unsure'),                                  (options["Headers",                                           "header_ham_string"], 'Ham'),                                  (options["Headers",                                           "header_spam_string"], 'Spam')):                messages = keyedMessageInfo[header]                if messages:                    sh = self.html.reviewSubHeader.clone()                    # Setup the header row                    sh.optionalHeaders = ''                    h = self.html.headerHeader.clone()                    for header in options["html_ui", "display_headers"]:                        h.headerLink.href = 'review?sort=%sHeader' % \                                            (header.lower(),)                        h.headerName = header.title()                        sh.optionalHeaders += h                    if not options["html_ui", "display_score"]:                        del sh.score_header                    if not options["html_ui", "display_received_time"]:                        del sh.received_header                    subHeader = str(sh)                    subHeader = subHeader.replace('TYPE', label)                    page.table += self.html.blankRow                    page.table += subHeader                    self._appendMessages(page.table, messages, label,                                         sort_order, reverse)            page.table += self.html.trainRow            if title == "":                title = _("Untrained messages received on %s") % date            box = self._buildBox(title, None, page)  # No icon, to save space.        else:            page = _("<p>There are no untrained messages to display. " \                     "Return <a href='home'>Home</a>, or " \                     "<a href='review'>check again</a>.</p>")            title = _("No untrained messages")            box = self._buildBox(title, 'status.gif', page)        self.write(box)        self._writePostamble(help_topic="review")    def _contains(self, a, b, ignore_case=False):        """Return true if substring b is part of string a."""        assert isinstance(a, types.StringTypes)        assert isinstance(b, types.StringTypes)        if ignore_case:            a = a.lower()            b = b.lower()        return a.find(b) >= 0    def onView(self, key, corpus):        """View a message - linked from the Review page."""        self._writePreamble(_("View message"),                            parent=('review', _('Review')))        sourceCorpus = None        message = None        if state.unknownCorpus.get(key) is not None:            sourceCorpus = state.unknownCorpus        elif state.hamCorpus.get(key) is not None:            sourceCorpus = state.hamCorpus        elif state.spamCorpus.get(key) is not None:            sourceCorpus = state.spamCorpus        if sourceCorpus is not None:            message = sourceCorpus.get(key)        if message is not None:            self.write("<pre>%s</pre>" % cgi.escape(message.as_string()))        else:            self.write(_("<p>Can't find message %r. Maybe it expired.</p>") % key)        self._writePostamble()    def onShowclues(self, key, subject, tokens='0'):        """Show clues for a message - linked from the Review page."""        tokens = bool(int(tokens)) # needs the int, as bool('0') is True        self._writePreamble(_("Message clues"),                            parent=('review', _('Review')))        sourceCorpus = None        message = None        if state.unknownCorpus.get(key) is not None:            sourceCorpus = state.unknownCorpus        elif state.hamCorpus.get(key) is not None:            sourceCorpus = state.hamCorpus        elif state.spamCorpus.get(key) is not None:            sourceCorpus = state.spamCorpus        if sourceCorpus is not None:            message = sourceCorpus.get(key).as_string()        if message is not None:            message = message.replace('\r\n', '\n').replace('\r', '\n') # For Macs            results = self._buildCluesTable(message, subject, tokens)            del results.classifyAnother            self.write(results)        else:            self.write(_("<p>Can't find message %r. Maybe it expired.</p>") % key)        self._writePostamble()    def _makeMessageInfo(self, message):        """Given an email.Message, return an object with subjectHeader,        bodySummary and other header (as needed) attributes.  These objects        are passed into appendMessages by onReview - passing email.Message        objects directly uses too much memory.        """        # Remove notations before displaying - see:        # [ 848365 ] Remove subject annotations from message review page        message.delNotations()        subjectHeader = message["Subject"] or "(none)"        headers = {"subject" : subjectHeader}        for header in options["html_ui", "display_headers"]:            headers[header.lower()] = (message[header] or "(none)")        score = message[options["Headers", "score_header_name"]]        if score:            # the score might have the log info at the end            op = score.find('(')            if op >= 0:                score = score[:op]            try:                score = float(score) * 100            except ValueError:                # Hmm.  The score header should only contain a floating                # point number.  What's going on here, then?                score = "Err"  # Let the user know something is wrong.        else:            # If the lookup fails, this means that the "include_score"            # option isn't activated. We have the choice here to either            # calculate it now, which is pretty inefficient, since we have            # already done so, or to admit that we don't know what it is.            # We'll go with the latter.            score = "?"        try:            part = typed_subpart_iterator(message, 'text', 'plain').next()            text = part.get_payload()        except StopIteration:            try:                part = typed_subpart_iterator(message, 'text', 'html').next()                text = part.get_payload()                text, unused = tokenizer.crack_html_style(text)                text, unused = tokenizer.crack_html_comment(text)                text = tokenizer.html_re.sub(' ', text)                text = _('(this message only has an HTML body)\n') + text            except StopIteration:                text = _('(this message has no text body)')        if type(text) == type([]):  # gotta be a 'right' way to do this            text = _("(this message is a digest of %s messages)") % (len(text))        elif text is None:            text = _("(this message has no body)")        else:            text = text.replace('&nbsp;', ' ')      # Else they'll be quoted            text = re.sub(r'(\s)\s+', r'\1', text)  # Eg. multiple blank lines            text = text.strip()        class _MessageInfo:            pass        messageInfo = _MessageInfo()        for headerName, headerValue in headers.items():            headerValue = self._trimHeader(headerValue, 45, True)            setattr(messageInfo, "%sHeader" % (headerName,), headerValue)        messageInfo.score = score        messageInfo.bodySummary = self._trimHeader(text, 200)        return messageInfo    def close_database(self):        state.close()    def reReadOptions(self):        """Called by the config page when the user saves some new options, or        restores the defaults."""        # Re-read the options.        global state        import Options        Options.load_options()        global options        from Options import options        # Recreate the state.        state = self.state_recreator()        self.classifier = state.bayes    def verifyInput(self, parms, pmap):        '''Check that the given input is valid.'''        # Most of the work here is done by the parent class, but        # we have a few extra checks        errmsg = UserInterface.UserInterface.verifyInput(self, parms, pmap)        if pmap != parm_ini_map:            return errmsg        # check for equal number of pop3servers and ports        slist = list(parms['pop3proxy_remote_servers'])        plist = list(parms['pop3proxy_listen_ports'])        if len(slist) != len(plist):            errmsg += _('<li>The number of POP3 proxy ports specified ' \                        'must match the number of servers specified</li>\n')        # check for duplicate ports        plist.sort()        for p in range(len(plist)-1):            try:                if plist[p] == plist[p+1]:                    errmsg += _('<li>All POP3 port numbers must be unique</li>')                    break            except IndexError:                pass        # check for equal number of smtpservers and ports        slist = list(parms['smtpproxy_remote_servers'])        plist = list(parms['smtpproxy_listen_ports'])        if len(slist) != len(plist):            errmsg += _('<li>The number of SMTP proxy ports specified ' \                        'must match the number of servers specified</li>\n')        # check for duplicate ports        plist.sort()        for p in range(len(plist)-1):            try:                if plist[p] == plist[p+1]:                    errmsg += _('<li>All SMTP port numbers must be unique</li>')                    break            except IndexError:                pass        return errmsg

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -