示例#1
0
def api_Email_changes(request, accountId, sinceState, maxChanges=None):
    account = request.get_account(accountId)
    newState = account.db.highModSeqEmail

    if sinceState <= str(account.db.lowModSeq):
        raise errors.cannotCalculateChanges({'new_state': newState})
    
    rows = account.db.dget('jmessages', {'jmodseq': ('>', sinceState)},
                        'msgid,deleted,jcreated,jmodseq')
    if maxChanges and len(rows) > maxChanges:
        raise errors.cannotCalculateChanges({'new_state': newState})

    created = []
    updated = []
    removed = []
    for msgid, deleted, jcreated in rows:
        if not deleted:
            if jcreated <= sinceState:
                updated.append(msgid)
            else:
                created.append(msgid)
        elif jcreated <= sinceState:
            removed.append(msgid)
        # else never seen
    
    return {
        'accountId': accountId,
        'oldState': sinceState,
        'newState': newState,
        'created': created,
        'updated': updated,
        'removed': removed,
    }
示例#2
0
    async def mailbox_changes(self, sinceState, maxChanges=None):
        """https://jmap.io/spec-mail.html#mailboxchanges"""
        new_state = await self.mailbox_state()
        if sinceState <= await self.mailbox_state_low():
            raise errors.cannotCalculateChanges({'new_state': new_state})

        removed = []
        created = []
        updated = []
        only_counts = True
        for mbox in self.mailboxes:
            if mbox['updated'] > sinceState:
                if mbox['deleted']:
                    # don't append created and deleted
                    if mbox['created'] <= sinceState:
                        removed.append(mbox['id'])
                elif mbox['created'] > sinceState:
                    created.append(mbox['id'])
                else:
                    if mbox['updatedNonCounts'] > sinceState:
                        only_counts = False
                    updated.append(mbox['id'])

        if len(removed) + len(created) + len(updated) > maxChanges:
            raise errors.cannotCalculateChanges({'new_state': new_state})

        return {
            'accountId':
            self.id,
            'oldState':
            sinceState,
            'newState':
            new_state,
            'hasMoreChanges':
            False,
            'created':
            created,
            'updated':
            updated,
            'removed':
            removed,
            'changedProperties':
            ["totalEmails", "unreadEmails", "totalThreads", "unreadThreads"]
            if only_counts else None,
        }
示例#3
0
    async def email_changes(self, sinceState, maxChanges=None):
        newState = await self.email_state()
        if sinceState <= await self.email_state_low():
            raise errors.cannotCalculateChanges({'new_state': newState})

        state = EmailState.from_string(sinceState)
        ok, lines = await self.imap.uid_fetch(
            '%d:*' % state.uid, "(UID)",
            '(CHANGEDSINCE %s VANISHED)' % state.modseq)
        if lines[0].startswith('(EARLIER) '):
            removed = [
                self.format_email_id(uid)
                for uid in iter_messageset(lines[0][10:])
            ]
            lines = lines[1:]
        else:
            removed = []

        created = []
        updated = []
        for seq, data in parse_fetch(lines[:-1]):
            uid = int(data['UID'])
            id = self.format_email_id(uid)
            if uid > state.uid:
                created.append(id)
            else:
                updated.append(id)

        # TODO: create intermediate state
        if maxChanges and len(removed) + len(created) + len(
                updated) > maxChanges:
            raise errors.cannotCalculateChanges({'new_state': newState})

        return {
            'accountId': self.id,
            'oldState': sinceState,
            'newState': newState,
            'hasMoreChanges': False,
            'created': created,
            'updated': updated,
            'removed': removed,
        }
示例#4
0
def api_Mailbox_changes(request, accountId, sinceState, maxChanges=None, **kwargs):
    """
    https://jmap.io/spec-mail.html#mailboxquerychanges
    https://jmap.io/spec-core.html#querychanges
    """
    account = request.get_account(accountId)
    new_state = account.db.highModSeqMailbox
    if sinceState <= str(account.db.lowModSeq):
        raise errors.cannotCalculateChanges({'new_state': new_state})
    rows = account.db.get_mailboxes(modseq__gt=sinceState)

    if maxChanges and len(rows) > maxChanges:
        raise errors.cannotCalculateChanges({'new_state': new_state})

    created = []
    updated = []
    removed = []
    only_counts = 0
    for mbox in rows:
        if not mbox['deleted']:
            if mbox['created'] <= sinceState:
                updated.append(mbox['id'])
                if mbox['jnoncountsmodseq'] > sinceState:
                    only_counts = 0
            else:
                created.append(mbox['id'])
        else:
            if mbox['created'] <= sinceState:
                removed.append(mbox['id'])
            # otherwise never seen

    return {
        'accountId': accountId,
        'oldState': sinceState,
        'newState': new_state,
        'created': created,
        'updated': updated,
        'removed': removed,
        'changedProperties': ["totalEmails", "unreadEmails", "totalThreads", "unreadThreads"] if only_counts else None,
    }
示例#5
0
 async def identity_changes(self, sinceState, maxChanges=None):
     raise errors.cannotCalculateChanges()