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

📄 sb_pop3dnd.py

📁 用python实现的邮件过滤器
💻 PY
📖 第 1 页 / 共 3 页
字号:
        self.listeners.remove(listener)class SpambayesMailbox(IMAPMailbox):    def __init__(self, name, id, directory):        IMAPMailbox.__init__(self, name, "spambayes", id)        self.UID_validity = id        ensureDir(directory)        self.storage = FileCorpus.FileCorpus(IMAPFileMessageFactory(),                                             directory, r"[0123456789]*")        # UIDs are required to be strictly ascending.        if len(self.storage.keys()) == 0:            self.nextUID = 1        else:            self.nextUID = long(self.storage.keys()[-1]) + 1        # Calculate initial recent and unseen counts        self.unseen_count = 0        self.recent_count = 0        for msg in self.storage:            if not msg.seen:                self.unseen_count += 1            if msg.recent:                self.recent_count += 1    def getUIDNext(self, increase=False):        """Return the likely UID for the next message added to this        mailbox."""        reply = str(self.nextUID)        if increase:            self.nextUID += 1        return reply    def getUID(self, msg):        """Return the UID of a message in the mailbox."""        # Note that IMAP messages are 1-based, our messages are 0-based.        d = self.storage        return long(d.keys()[msg - 1])    def getFlags(self):        """Return the flags defined in this mailbox."""        return ["\\Answered", "\\Flagged", "\\Deleted", "\\Seen",                "\\Draft"]    def getMessageCount(self):        """Return the number of messages in this mailbox."""        return len(self.storage.keys())    def getRecentCount(self):        """Return the number of messages with the 'Recent' flag."""        return self.recent_count    def getUnseenCount(self):        """Return the number of messages with the 'Unseen' flag."""        return self.unseen_count    def isWriteable(self):        """Get the read/write status of the mailbox."""        return True    def destroy(self):        """Called before this mailbox is deleted, permanently."""        # Our mailboxes cannot be deleted        raise NotImplementedError    def getHierarchicalDelimiter(self):        """Get the character which delimits namespaces for in this        mailbox."""        return '.'    def requestStatus(self, names):        """Return status information about this mailbox."""        answer = {}        for request in names:            request = request.upper()            if request == "MESSAGES":                answer[request] = self.getMessageCount()            elif request == "RECENT":                answer[request] = self.getRecentCount()            elif request == "UIDNEXT":                answer[request] = self.getUIDNext()            elif request == "UIDVALIDITY":                answer[request] = self.getUIDValidity()            elif request == "UNSEEN":                answer[request] = self.getUnseenCount()        return answer    def addMessage(self, content, flags=(), date=None):        """Add the given message to this mailbox."""        msg = self.storage.makeMessage(self.getUIDNext(True),                                       content.read())        msg.date = date        self.storage.addMessage(msg)        self.store(MessageSet(long(msg.id), long(msg.id)), flags, 1, True)        msg.recent = True        msg.store()        self.recent_count += 1        self.unseen_count += 1        for listener in self.listeners:            listener.newMessages(self.getMessageCount(),                                 self.getRecentCount())        d = defer.Deferred()        reactor.callLater(0, d.callback, self.storage.keys().index(msg.id))        return d    def expunge(self):        """Remove all messages flagged \\Deleted."""        deleted_messages = []        for msg in self.storage:            if msg.deleted:                if not msg.seen:                    self.unseen_count -= 1                if msg.recent:                    self.recent_count -= 1                deleted_messages.append(long(msg.id))                self.storage.removeMessage(msg)        if deleted_messages != []:            for listener in self.listeners:                listener.newMessages(self.getMessageCount(),                                     self.getRecentCount())        return deleted_messages    def search(self, query, uid):        """Search for messages that meet the given query criteria.        @type query: C{list}        @param query: The search criteria        @rtype: C{list}        @return: A list of message sequence numbers or message UIDs which        match the search criteria.        """        if self.getMessageCount() == 0:            return []        all_msgs = MessageSet(long(self.storage.keys()[0]),                              long(self.storage.keys()[-1]))        matches = []        for id, msg in self._messagesIter(all_msgs, uid):            for q in query:                if msg.matches(q):                    matches.append(id)                    break        return matches    def _messagesIter(self, messages, uid):        if uid:            if not self.storage.keys():                return            messages.last = long(self.storage.keys()[-1])        else:            messages.last = self.getMessageCount()        for id in messages:            if uid:                msg = self.storage.get(str(id))            else:                msg = self.storage.get(str(self.getUID(id)))            if msg is None:                # Non-existant message.                continue            # Load the message, if necessary            if hasattr(msg, "load"):                msg.load()            yield (id, msg)    def fetch(self, messages, uid):        """Retrieve one or more messages."""        return self._messagesIter(messages, uid)    def store(self, messages, flags, mode, uid):        """Set the flags of one or more messages."""        stored_messages = {}        for id, msg in self._messagesIter(messages, uid):            if mode == 0:                msg.clear_flags()                value = True            elif mode == -1:                value = False            elif mode == 1:                value = True            for flag in flags or (): # flags might be None                if flag == '(' or flag == ')':                    continue                if flag == "SEEN" and value == True and msg.seen == False:                    self.unseen_count -= 1                if flag == "SEEN" and value == False and msg.seen == True:                    self.unseen_count += 1                msg.set_flag(flag, value)            stored_messages[id] = msg.flags()        return stored_messagesclass SpambayesInbox(SpambayesMailbox):    """A special mailbox that holds status messages from SpamBayes."""    def __init__(self, id, state):        IMAPMailbox.__init__(self, "INBOX", "spambayes", id)        self.mdb = state.mdb        self.UID_validity = id        self.nextUID = 1        self.unseen_count = 0        self.recent_count = 0        self.storage = {}        self.createMessages()        self.stats = state.stats    def buildStatusMessage(self, body=False, headers=False):        """Build a message containing the current status message.        If body is True, then return the body; if headers is True        return the headers.  If both are true, then return both        (and insert a newline between them).        """        msg = []        if headers:            msg.append("Subject: SpamBayes Status")            msg.append('From: "SpamBayes" <no-reply@spambayes.invalid>')            if body:                msg.append('\r\n')        if body:            state.buildStatusStrings()            msg.append("POP3 proxy running on %s, proxying to %s." % \                       (state.proxyPortsString, state.serversString))            msg.append("Active POP3 conversations: %s." % \                       (state.activeSessions,))            msg.append("POP3 conversations this session: %s." % \                       (state.totalSessions,))            msg.append("IMAP server running on %s." % \                       (state.serverPortString,))            msg.append("Active IMAP4 conversations: %s." % \                       (state.activeIMAPSessions,))            msg.append("IMAP4 conversations this session: %s." % \                       (state.totalIMAPSessions,))            msg.append("Emails classified this session: %s spam, %s ham, "                       "%s unsure." % (state.numSpams, state.numHams,                                       state.numUnsure))            msg.append("Total emails trained: Spam: %s Ham: %s" % \                       (state.bayes.nspam, state.bayes.nham))            msg.append(state.warning or "SpamBayes is operating correctly.\r\n")        return "\r\n".join(msg)    def buildStatisticsMessage(self, body=False, headers=False):        """Build a mesasge containing the current statistics.        If body is True, then return the body; if headers is True        return the headers.  If both are true, then return both        (and insert a newline between them).        """        msg = []        if headers:            msg.append("Subject: SpamBayes Statistics")            msg.append('From: "SpamBayes" <no-reply@spambayes.invalid')            if body:                msg.append('\r\n')        if body:            msg.extend(self.stats.GetStats(use_html=False))        return "\r\n".join(msg)    def createMessages(self):        """Create the special messages that live in this mailbox."""        state.buildStatusStrings()        state.buildServerStrings()        about = 'Subject: About SpamBayes / POP3DND\r\n' \                 'From: "SpamBayes" <no-reply@spambayes.invalid>\r\n\r\n' \                 '%s\r\nSee <http://spambayes.org>.\r\n' % (__doc__,)        date = imaplib.Time2Internaldate(time.time())[1:-1]        msg = email.message_from_string(about, _class=IMAPMessage)        msg.date = date        self.addMessage(msg)        msg = DynamicIMAPMessage(self.buildStatusMessage, self.mdb)        self.addMessage(msg)        msg = DynamicIMAPMessage(self.buildStatisticsMessage, self.mdb)        self.addMessage(msg)        # XXX Add other messages here, for example        # XXX help and other documentation.    def isWriteable(self):        """Get the read/write status of the mailbox."""        return False    def addMessage(self, msg, flags=(), date=None):        """Add the given message to this mailbox."""        msg.id = self.getUIDNext(True)        self.storage[msg.id] = msg        d = defer.Deferred()        reactor.callLater(0, d.callback, self.storage.keys().index(msg.id))        return d    def expunge(self):        """Remove all messages flagged \\Deleted."""        # Mailbox is read-only.        return []    def store(self, messages, flags, mode, uid):        """Set the flags of one or more messages."""        # Mailbox is read-only.        return {}class Trainer(object):    """Listens to a given mailbox and trains new messages as spam or    ham."""    __implements__ = (IMailboxListener,)    def __init__(self, mailbox, asSpam):        self.mailbox = mailbox        self.asSpam = asSpam    def modeChanged(self, writeable):        # We don't care        pass    def flagsChanged(self, newFlags):        # We don't care        pass    def newMessages(self, exists, recent):        # We don't get passed the actual message, or the id of        # the message, or even the message number.  We just get        # the total number of new/recent messages.        # However, this function should be called _every_ time        # that a new message appears, so we should be able to        # assume that the last message is the new one.        # (We ignore the recent count)        if exists is not None:            id = self.mailbox.getUID(exists)            msg = self.mailbox.storage[str(id)]            msg.train(state.bayes, self.asSpam)class SpambayesAccount(MemoryAccount):    """Account for Spambayes server."""    def __init__(self, id, ham, spam, unsure, train_spam, inbox):        MemoryAccount.__init__(self, id)        self.mailboxes = {"SPAM" : spam,                          "UNSURE" : unsure,                          "TRAIN_AS_HAM" : ham,                          "TRAIN_AS_SPAM" : train_spam,                          "INBOX" : inbox}    def select(self, name, readwrite=1):        # 'INBOX' is a special case-insensitive name meaning the        # primary mailbox for the user; for our purposes this contains        # special messages from SpamBayes.        return MemoryAccount.select(self, name, readwrite)

⌨️ 快捷键说明

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