def test_unreadMessageCount(self):
        """
        Check that L{InboxScreen.getUnreadMessageCount} return the correct
        message count under a variety of conditions.
        """
        self.makeMessages(13, read=False, spam=False)
        self.makeMessages(6, read=True, spam=False)

        self.assertEqual(self.unreadCount('inbox'), 13)
        self.assertEqual(self.unreadCount('all'), 13)
        self.assertEqual(self.unreadCount('sent'), 0)
        self.assertEqual(self.unreadCount('spam'), 0)

        # mark 1 read message as unread
        sq = MailboxSelector(self.store)

        sq.refineByStatus(READ_STATUS)
        iter(sq).next().markUnread()
        self.assertEqual(self.unreadCount('inbox'), 14)

        # mark 6 unread messages as spam
        sq = MailboxSelector(self.store)
        sq.refineByStatus(UNREAD_STATUS)
        sq.setLimit(6)
        spam = []
        for m in sq:
            m.classifySpam()
            spam.append(m)
        self.assertEqual(self.unreadCount('spam'), 6)

        # return all spam messages to the inbox
        for m in spam:
            m.classifyClean()
        m.archive()
        self.assertEqual(self.unreadCount('spam'), 0)
Example #2
0
    def retrain(self):
        """
        Force all L{iquotient.IHamFilter}s to forget their trained state,
        then retrain them based on L{exmess.Message}s with C{trained} set to
        C{True}, then reclassify all messages.

        This should only be called in the batch process.
        """
        filters = list(self.store.powerupsFor(iquotient.IHamFilter))
        for f in filters:
            f.forgetTraining()

        sq = MailboxSelector(self.store)
        sq.setLimit(5000)
        sq.refineByStatus(TRAINED_STATUS)
        work = iter(list(sq))


        # XXX This really should use in-database state, otherwise a restart in
        # the middle will muck things up.
        def go():
            for msg in work:
                for f in filters:
                    f.train(msg._spam, msg)
                yield None
            self.reclassify()
        return coiterate(go())
Example #3
0
 def queryMessageSenderPerson(typ):
     # having Message.person might speed this up, but it would
     # need some kind of notification thing that fires each time
     # an email address is associated with a Person item so we
     # can update the attribute
     sq = MailboxSelector(store)
     sq.refineByPerson(person)
     return store.query(typ, attributes.AND(
             typ.message == exmess.Message.storeID,
             sq._getComparison()))
Example #4
0
    def assertMessages(self, statuses, messageIndexes):
        """
        Fail this test unless the result of a listing of given message statuses
        matches the given message indices.

        @param statuses: a list of unicode status strings.

        @param messageIndexes: a list of message indexes.
        """
        sq = MailboxSelector(self.store)
        for statusName in statuses:
            sq.refineByStatus(statusName)
        self.assertMessageQuery(sq, messageIndexes)
Example #5
0
    def assertMessages(self, statuses, messageIndexes):
        """
        Fail this test unless the result of a listing of given message statuses
        matches the given message indices.

        @param statuses: a list of unicode status strings.

        @param messageIndexes: a list of message indexes.
        """
        sq = MailboxSelector(self.store)
        for statusName in statuses:
            sq.refineByStatus(statusName)
        self.assertMessageQuery(sq, messageIndexes)
Example #6
0
    def test_unreadMessageCount(self):
        """
        Check that L{InboxScreen.getUnreadMessageCount} return the correct
        message count under a variety of conditions.
        """
        self.makeMessages(13, read=False, spam=False)
        self.makeMessages(6, read=True, spam=False)

        self.assertEqual(self.unreadCount('inbox'), 13)
        self.assertEqual(self.unreadCount('all'), 13)
        self.assertEqual(self.unreadCount('sent'), 0)
        self.assertEqual(self.unreadCount('spam'), 0)

        # mark 1 read message as unread
        sq = MailboxSelector(self.store)

        sq.refineByStatus(READ_STATUS)
        iter(sq).next().markUnread()
        self.assertEqual(self.unreadCount('inbox'), 14)

        # mark 6 unread messages as spam
        sq = MailboxSelector(self.store)
        sq.refineByStatus(UNREAD_STATUS)
        sq.setLimit(6)
        spam = []
        for m in sq:
            m.classifySpam()
            spam.append(m)
        self.assertEqual(self.unreadCount('spam'), 6)

        # return all spam messages to the inbox
        for m in spam:
            m.classifyClean()
        m.archive()
        self.assertEqual(self.unreadCount('spam'), 0)
Example #7
0
    def mostRecentMessages(self, person, n=5):
        """
        @param person: L{xmantissa.people.Person}
        @return: sequence of C{n} L{xquotient.exmess.Message} instances,
                 each one a message either to or from C{person}, ordered
                 descendingly by received date.
        """

        sq = MailboxSelector(self.store)
        sq.refineByStatus(CLEAN_STATUS)
        sq.refineByPerson(person)
        sq.setLimit(n)
        sq.setNewestFirst()
        return list(sq)
Example #8
0
 def test_upgradeCorrespondents(self):
     """
     Verify that Correspondent items are created for each incoming message,
     so that 'view from person' still works.
     """
     ms = MailboxSelector(self.store)
     newPerson = Person(store=self.store, name=u'test bob')
     PersonEmailAddress(store=self.store, person=newPerson,
                        address=u'*****@*****.**')
     ms.refineByPerson(newPerson)
     # As it currently stands, outgoing and draft messages are both not
     # considered for the addition of Correspondent items.  This might not
     # be correct, but it is the current behavior and at the time of writing
     # this test the goal was to ensure that the behavior would not change
     # across this upgrade.  -glyph
     self.assertMessageQuery(ms, [0, 1, 2, 5, 6, 7])
Example #9
0
 def test_upgradeCorrespondents(self):
     """
     Verify that Correspondent items are created for each incoming message,
     so that 'view from person' still works.
     """
     ms = MailboxSelector(self.store)
     newPerson = Person(store=self.store, name=u'test bob')
     PersonEmailAddress(store=self.store,
                        person=newPerson,
                        address=u'*****@*****.**')
     ms.refineByPerson(newPerson)
     # As it currently stands, outgoing and draft messages are both not
     # considered for the addition of Correspondent items.  This might not
     # be correct, but it is the current behavior and at the time of writing
     # this test the goal was to ensure that the behavior would not change
     # across this upgrade.  -glyph
     self.assertMessageQuery(ms, [0, 1, 2, 5, 6, 7])
Example #10
0
    def retrain(self):
        """
        Force all L{iquotient.IHamFilter}s to forget their trained state,
        then retrain them based on L{exmess.Message}s with C{trained} set to
        C{True}, then reclassify all messages.

        This should only be called in the batch process.
        """
        filters = list(self.store.powerupsFor(iquotient.IHamFilter))
        for f in filters:
            f.forgetTraining()

        sq = MailboxSelector(self.store)
        sq.setLimit(5000)
        sq.refineByStatus(TRAINED_STATUS)
        work = iter(list(sq))

        # XXX This really should use in-database state, otherwise a restart in
        # the middle will muck things up.
        def go():
            for msg in work:
                for f in filters:
                    f.train(msg._spam, msg)
                yield None
            self.reclassify()

        return coiterate(go())
Example #11
0
def _viewSelectionToMailboxSelector(store, viewSelection):
    """
    Convert a 'view selection' object, sent from the client, into a MailboxSelector
    object which will be used to view the mailbox.

    @param store: an L{axiom.store.Store} that contains some messages.

    @param viewSelection: a dictionary with 4 keys: 'view', 'tag', 'person',
    'account'.  This dictionary represents the selections that users have
    made in the 4-section 'complexity 3' filtering UI.  Each key may have a
    string value, or None.  If the value is None, the user has selected
    'All' for that key in the UI; if the value is a string, the user has
    selected that string.

    @return: a L{MailboxSelector} object.
    """
    view, tag, personWebID, account = map(viewSelection.__getitem__, [u"view", u"tag", u"person", u"account"])

    sq = MailboxSelector(store)
    sq.setLimit(None)
    if view in TOUCH_ONCE_VIEWS:
        sq.setOldestFirst()
    else:
        sq.setNewestFirst()
    if view == u"all":
        view = CLEAN_STATUS

    sq.refineByStatus(view)  # 'view' is really a status!  and the names
    # even line up!
    if tag is not None:
        sq.refineByTag(tag)
    if account is not None:
        sq.refineBySource(account)
    if personWebID is not None:
        person = ixmantissa.IWebTranslator(store).fromWebID(personWebID)
        sq.refineByPerson(person)
    return sq
Example #12
0
def _viewSelectionToMailboxSelector(store, viewSelection):
    """
    Convert a 'view selection' object, sent from the client, into a MailboxSelector
    object which will be used to view the mailbox.

    @param store: an L{axiom.store.Store} that contains some messages.

    @param viewSelection: a dictionary with 4 keys: 'view', 'tag', 'person',
    'account'.  This dictionary represents the selections that users have
    made in the 4-section 'complexity 3' filtering UI.  Each key may have a
    string value, or None.  If the value is None, the user has selected
    'All' for that key in the UI; if the value is a string, the user has
    selected that string.

    @return: a L{MailboxSelector} object.
    """
    view, tag, personWebID, account = map(
        viewSelection.__getitem__,
        [u"view", u"tag", u"person", u"account"])

    sq = MailboxSelector(store)
    sq.setLimit(None)
    if view in TOUCH_ONCE_VIEWS:
        sq.setOldestFirst()
    else:
        sq.setNewestFirst()
    if view == u'all':
        view = CLEAN_STATUS

    sq.refineByStatus(view) # 'view' is really a status!  and the names
                            # even line up!
    if tag is not None:
        sq.refineByTag(tag)
    if account is not None:
        sq.refineBySource(account)
    if personWebID is not None:
        person = ixmantissa.IWebTranslator(store).fromWebID(personWebID)
        sq.refineByPerson(person)
    return sq