diff options
author | Jason Gunthorpe <jgg@mellanox.com> | 2020-01-31 16:10:52 -0400 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2020-01-31 16:48:07 -0400 |
commit | 184b8f4bc8a820c43e40dbc205974f196d6bf234 (patch) | |
tree | 6989858a8ed63b7be4dfd068493bd4cdb128b422 | |
parent | 5a8e0e554679223319d03a242e7985602fe66bcb (diff) | |
download | cloud_mdir_sync-184b8f4bc8a820c43e40dbc205974f196d6bf234.tar.gz cloud_mdir_sync-184b8f4bc8a820c43e40dbc205974f196d6bf234.tar.bz2 cloud_mdir_sync-184b8f4bc8a820c43e40dbc205974f196d6bf234.zip |
Support FLAG_DELETED in Office365
When a local message is tagged deleted then update the cloud flags and
delete the message.
Using the Trash flag in a mail dir allows the cloud upload step to see the
original message and then upload the local flags before deleting it. For
instance, this will allow the Replied flag to be set upon deletion.
Once deleted in the cloud the next sync iteration will delete the message
locally.
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
-rw-r--r-- | cloud_mdir_sync/office365.py | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/cloud_mdir_sync/office365.py b/cloud_mdir_sync/office365.py index 5742fea..1400ced 100644 --- a/cloud_mdir_sync/office365.py +++ b/cloud_mdir_sync/office365.py @@ -535,12 +535,14 @@ class O365Mailbox(mailbox.Mailbox): def _update_msg_flags(self, cmsg: messages.Message, old_cmsg_flags: int, lmsg: messages.Message): - if lmsg.flags == old_cmsg_flags or lmsg.flags == cmsg.flags: + lflags = lmsg.flags & (messages.Message.ALL_FLAGS + ^ messages.Message.FLAG_DELETED) + if lflags == old_cmsg_flags or lflags == cmsg.flags: return None cloud_flags = cmsg.flags ^ old_cmsg_flags flag_mask = messages.Message.ALL_FLAGS ^ cloud_flags - nflags = (lmsg.flags & flag_mask) | (cmsg.flags & cloud_flags) + nflags = (lflags & flag_mask) | (cmsg.flags & cloud_flags) modified_flags = nflags ^ cmsg.flags # FIXME: https://docs.microsoft.com/en-us/graph/best-practices-concept#getting-minimal-responses @@ -607,7 +609,8 @@ class O365Mailbox(mailbox.Mailbox): # There is a batching API for this kind of stuff as well: # https://docs.microsoft.com/en-us/graph/json-batching self.last_merge_len = 0 - todo = [] + todo_flags = [] + todo_del = [] if self.cfg.trace_file is not None: pickle.dump(["merge_content", self.name, self.messages, msgs], self.cfg.trace_file) @@ -617,26 +620,33 @@ class O365Mailbox(mailbox.Mailbox): # old_cmsg is the original cloud message from the last sync lmsg, old_cmsg = mpair cmsg = self.messages.get(ch) + assert old_cmsg is not None - # Cloud message was deleted, cloud takes priority - if cmsg is None: - continue - if lmsg is None: - # Debugging that the message really is to be deleted + # Update flags + if cmsg is not None and old_cmsg is not None and lmsg is not None: + patch = self._update_msg_flags(cmsg, old_cmsg.flags, lmsg) + if patch: + todo_flags.append(patch) + + # Debugging that the message really is to be deleted + if cmsg is not None and lmsg is None: assert os.stat(os.path.join(self.cfg.msgdb.hashes_dir, ch)).st_nlink == 1 + + # This only happens if the user is not using DeletedMailDir and + # the delete_msgs path below + if cmsg is not None and (lmsg is None or lmsg.flags + & messages.Message.FLAG_DELETED): # Delete cloud message - todo.append( + todo_del.append( self.graph.post_json( "v1.0", f"/me/mailFolders/{self.mailbox}/messages/{cmsg.storage_id}/move", body={"destinationId": "deleteditems"})) del self.messages[ch] - continue - patch = self._update_msg_flags(cmsg, old_cmsg.flags, lmsg) - if patch: - todo.append(patch) - - await asyncio.gather(*todo) - self.last_merge_len = len(todo) + await asyncio.gather(*todo_flags) + # Delete must be temporally after move as move will change the mailbox + # id. + await asyncio.gather(*todo_del) + self.last_merge_len = len(todo_flags) + len(todo_del) |