diff options
Diffstat (limited to 'cloud_mdir_sync/mailbox.py')
-rw-r--r-- | cloud_mdir_sync/mailbox.py | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/cloud_mdir_sync/mailbox.py b/cloud_mdir_sync/mailbox.py new file mode 100644 index 0000000..24c64cd --- /dev/null +++ b/cloud_mdir_sync/mailbox.py @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: GPL-2.0+ +import asyncio +import functools +import inspect +from abc import abstractmethod +from typing import TYPE_CHECKING, Dict + +if TYPE_CHECKING: + from . import config + from messages import MessageDB + from messages import CHMsgDict_Type + from messages import CHMsgMappingDict_Type + + +def update_on_failure(func): + """Decorator for mailbox class methods that cause the mailbox to need a full + update if the method throws an exception.""" + @functools.wraps(func) + def wrapper(self, *args, **kwargs): + try: + return func(self, *args, **kwargs) + except: + self.need_update = True + Mailbox.changed_event.set() + raise + + @functools.wraps(func) + async def async_wrapper(self, *args, **kwargs): + try: + return await func(self, *args, **kwargs) + except: + self.need_update = True + Mailbox.changed_event.set() + raise + + if inspect.iscoroutinefunction(func): + return async_wrapper + return wrapper + + +class Mailbox(object): + messages: "CHMsgDict_Type" = {} + changed_event = asyncio.Event() + need_update = True + + @abstractmethod + async def setup_mbox(self, cfg: "config.Config") -> None: + pass + + @abstractmethod + def force_content(self, msgdb: "MessageDB", + msgs: "CHMsgDict_Type") -> None: + pass + + @abstractmethod + async def merge_content(self, msgs: "CHMsgMappingDict_Type") -> None: + pass + + def same_messages(self, + mdict: "CHMsgMappingDict_Type", + tuple_form=False) -> bool: + """Return true if mdict is the same as the local messages""" + if len(self.messages) != len(mdict): + return False + + for ch, mmsg in self.messages.items(): + omsg = mdict.get(ch) + if omsg is None: + return False + + # update_cloud_from_local use a different dict format + if tuple_form: + omsg = omsg[0] # Check the local mbox + if omsg is None: + return False + + if (mmsg.content_hash != omsg.content_hash + or mmsg.flags != omsg.flags): + return False + return True |