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, }
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, }
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, }
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, }
async def identity_changes(self, sinceState, maxChanges=None): raise errors.cannotCalculateChanges()