Polished mail integration

This commit is contained in:
Fabio Manganiello 2020-09-02 01:34:18 +02:00
parent ca168828de
commit d7806757c5
3 changed files with 50 additions and 17 deletions

View file

@ -227,16 +227,16 @@ class MailBackend(Backend):
for msg in unread: for msg in unread:
if msg.date and last_checked_date and msg.date < last_checked_date: if msg.date and last_checked_date and msg.date < last_checked_date:
continue continue
self.bus.post(MailReceivedEvent(mailbox=self.mailboxes[mailbox_id].name, msg=msg)) self.bus.post(MailReceivedEvent(mailbox=self.mailboxes[mailbox_id].name, message=msg))
for msg in seen: for msg in seen:
self.bus.post(MailSeenEvent(mailbox=self.mailboxes[mailbox_id].name, msg=msg)) self.bus.post(MailSeenEvent(mailbox=self.mailboxes[mailbox_id].name, message=msg))
for msg in flagged: for msg in flagged:
self.bus.post(MailFlaggedEvent(mailbox=self.mailboxes[mailbox_id].name, msg=msg)) self.bus.post(MailFlaggedEvent(mailbox=self.mailboxes[mailbox_id].name, message=msg))
for msg in unflagged: for msg in unflagged:
self.bus.post(MailUnflaggedEvent(mailbox=self.mailboxes[mailbox_id].name, msg=msg)) self.bus.post(MailUnflaggedEvent(mailbox=self.mailboxes[mailbox_id].name, message=msg))
def _check_mailboxes(self) -> List[Tuple[Dict[int, Mail], Dict[int, Mail]]]: def _check_mailboxes(self) -> List[Tuple[Dict[int, Mail], Dict[int, Mail]]]:
workers = [] workers = []

View file

@ -1,10 +1,11 @@
from typing import Optional, Dict from typing import Optional, Dict
from platypush.message.event import Event from platypush.message.event import Event
from platypush.plugins.mail import Mail
class MailEvent(Event): class MailEvent(Event):
def __init__(self, mailbox: str, message: Optional[Dict] = None, *args, **kwargs): def __init__(self, mailbox: str, message: Optional[Mail] = None, *args, **kwargs):
super().__init__(*args, mailbox=mailbox, message=message or {}, **kwargs) super().__init__(*args, mailbox=mailbox, message=message or {}, **kwargs)

View file

@ -356,11 +356,11 @@ class MailImapPlugin(MailInPlugin):
return msg_ids return msg_ids
@action @action
def get_message(self, id: int, folder: str = 'INBOX', **connect_args) -> Mail: def get_message(self, message: int, folder: str = 'INBOX', **connect_args) -> Mail:
""" """
Get the full content of a message given the ID returned by :meth:`.search`. Get the full content of a message given the ID returned by :meth:`.search`.
:param id: Message ID. :param message: Message ID.
:param folder: Folder name (default: ``INBOX``). :param folder: Folder name (default: ``INBOX``).
:param connect_args: Arguments to pass to :meth:`._get_server_info` for server configuration override. :param connect_args: Arguments to pass to :meth:`._get_server_info` for server configuration override.
:return: A message in the same format as :meth:`.search`, with an added ``payload`` attribute containing the :return: A message in the same format as :meth:`.search`, with an added ``payload`` attribute containing the
@ -368,11 +368,11 @@ class MailImapPlugin(MailInPlugin):
""" """
with self.connect(**connect_args) as client: with self.connect(**connect_args) as client:
client.select_folder(folder, readonly=True) client.select_folder(folder, readonly=True)
data = client.fetch(id, ['ALL', 'RFC822']) data = client.fetch(message, ['ALL', 'RFC822'])
assert id in data, 'No such message ID: {}'.format(id) assert message in data, 'No such message ID: {}'.format(message)
data = data[id] data = data[message]
ret = self._parse_message(id, data) ret = self._parse_message(message, data)
msg = email.message_from_bytes(data[b'RFC822']) msg = email.message_from_bytes(data[b'RFC822'])
ret.payload = msg.get_payload() ret.payload = msg.get_payload()
@ -413,8 +413,14 @@ class MailImapPlugin(MailInPlugin):
with self.connect(**connect_args) as client: with self.connect(**connect_args) as client:
client.delete_folder(folder) client.delete_folder(folder)
@staticmethod
def _convert_flags(flags: Union[str, List[str]]) -> List[bytes]:
if isinstance(flags, str):
flags = [flag.strip() for flag in flags.split(',')]
return [('\\' + flag).encode() for flag in flags]
@action @action
def add_flags(self, messages: List[int], flags: List[str], folder: str = 'INBOX', **connect_args): def add_flags(self, messages: List[int], flags: Union[str, List[str]], folder: str = 'INBOX', **connect_args):
""" """
Add a set of flags to the specified set of message IDs. Add a set of flags to the specified set of message IDs.
@ -432,10 +438,10 @@ class MailImapPlugin(MailInPlugin):
""" """
with self.connect(**connect_args) as client: with self.connect(**connect_args) as client:
client.select_folder(folder) client.select_folder(folder)
client.add_flags(messages, flags) client.add_flags(messages, self._convert_flags(flags))
@action @action
def set_flags(self, messages: List[int], flags: List[str], folder: str = 'INBOX', **connect_args): def set_flags(self, messages: List[int], flags: Union[str, List[str]], folder: str = 'INBOX', **connect_args):
""" """
Set a set of flags to the specified set of message IDs. Set a set of flags to the specified set of message IDs.
@ -453,10 +459,10 @@ class MailImapPlugin(MailInPlugin):
""" """
with self.connect(**connect_args) as client: with self.connect(**connect_args) as client:
client.select_folder(folder) client.select_folder(folder)
client.set_flags(messages, flags) client.set_flags(messages, self._convert_flags(flags))
@action @action
def remove_flags(self, messages: List[int], flags: List[str], folder: str = 'INBOX', **connect_args): def remove_flags(self, messages: List[int], flags: Union[str, List[str]], folder: str = 'INBOX', **connect_args):
""" """
Remove a set of flags to the specified set of message IDs. Remove a set of flags to the specified set of message IDs.
@ -474,7 +480,7 @@ class MailImapPlugin(MailInPlugin):
""" """
with self.connect(**connect_args) as client: with self.connect(**connect_args) as client:
client.select_folder(folder) client.select_folder(folder)
client.remove_flags(messages, flags) client.remove_flags(messages, self._convert_flags(flags))
@action @action
def flag_messages(self, messages: List[int], folder: str = 'INBOX', **connect_args): def flag_messages(self, messages: List[int], folder: str = 'INBOX', **connect_args):
@ -520,6 +526,32 @@ class MailImapPlugin(MailInPlugin):
""" """
return self.unflag_messages([message], folder=folder, **connect_args) return self.unflag_messages([message], folder=folder, **connect_args)
@action
def delete_messages(self, messages: List[int], folder: str = 'INBOX', expunge: bool = True, **connect_args):
"""
Set a specified set of message IDs as deleted.
:param messages: List of message IDs.
:param folder: IMAP folder (default: ``INBOX``).
:param expunge: If set then the messages will also be expunged from the folder, otherwise they will only be
marked as deleted (default: ``True``).
:param connect_args: Arguments to pass to :meth:`._get_server_info` for server configuration override.
"""
self.add_flags(messages, ['Deleted'], folder=folder, **connect_args)
if expunge:
self.expunge_messages(folder=folder, messages=messages, **connect_args)
@action
def undelete_messages(self, messages: List[int], folder: str = 'INBOX', **connect_args):
"""
Remove the ``Deleted`` flag from the specified set of message IDs.
:param messages: List of message IDs.
:param folder: IMAP folder (default: ``INBOX``).
:param connect_args: Arguments to pass to :meth:`._get_server_info` for server configuration override.
"""
return self.remove_flags(messages, ['Deleted'], folder=folder, **connect_args)
@action @action
def copy_messages(self, messages: List[int], dest_folder: str, source_folder: str = 'INBOX', **connect_args): def copy_messages(self, messages: List[int], dest_folder: str, source_folder: str = 'INBOX', **connect_args):
""" """