diff options
author | Hugo Hörnquist <hugo@lysator.liu.se> | 2022-11-29 02:51:29 +0100 |
---|---|---|
committer | Hugo Hörnquist <hugo@lysator.liu.se> | 2022-11-29 02:51:29 +0100 |
commit | 4587e5e124afcb13c81dea68e373420670d076b4 (patch) | |
tree | 91416ac5cb53dce9d80b466f66206a05c5a25a40 /mu.py | |
parent | Add makefile for ctags file. (diff) | |
download | mu4web-4587e5e124afcb13c81dea68e373420670d076b4.tar.gz mu4web-4587e5e124afcb13c81dea68e373420670d076b4.tar.xz |
Properly specify version requirements, and add directory layout.
Diffstat (limited to 'mu.py')
-rw-r--r-- | mu.py | 128 |
1 files changed, 0 insertions, 128 deletions
@@ -1,128 +0,0 @@ -""" -Wrapper for the `mu` command line. -""" - -import email.message -import email.policy -from email.parser import BytesParser -import subprocess -from subprocess import PIPE -import xml.dom.minidom -import xml.dom - -from typing import ( - Literal, - Optional, - Union, -) - -parser = BytesParser(policy=email.policy.default) - - -def get_mail(id: str) -> email.message.Message: - """ - Lookup email by Message-ID. - - [Raises] - MuError - """ - cmd = subprocess.run(['mu', 'find', '-u', f'i:{id}', - '--fields', 'l'], - stdout=PIPE) - filename = cmd.stdout.decode('UTF-8').strip() - - if cmd.returncode != 0: - raise MuError(cmd.returncode) - - with open(filename, "rb") as f: - mail = parser.parse(f) - return mail - - -class MuError(Exception): - codes = { - 1: 'General Error', - 2: 'No Matches', - 4: 'Database is corrupted' - } - - def __init__(self, returncode: int): - self.returncode: int = returncode - self.msg: str = MuError.codes.get(returncode, 'Unknown Error') - - def __repr__(self): - return f'MuError({self.returncode}, "{self.msg}")' - - def __str__(self): - return repr(self) - - -Sortfield = Union[Literal['cc'], - Literal['c'], - Literal['bcc'], - Literal['h'], - Literal['date'], - Literal['d'], - Literal['from'], - Literal['f'], - Literal['maildir'], - Literal['m'], - Literal['msgid'], - Literal['i'], - Literal['prio'], - Literal['p'], - Literal['subject'], - Literal['s'], - Literal['to'], - Literal['t'], - Literal['list'], - Literal['v']] - - - -def mu_search(query, sortfield: Optional[Sortfield] = 'subject', reverse: bool = False) -> list[dict[str, str]]: - """ - [Parameters] - query - Search query as per mu-find(1). - sortfield - Field to sort the values by - reverse - If the sort should be reversed - - [Returns] - >>> {'from': 'Hugo Hörnquist <hugo@example.com>', - 'date': '1585678375', - 'size': '377', - 'msgid': 'SAMPLE-ID@localhost', - 'path': '/home/hugo/.local/var/mail/INBOX/cur/filename', - 'maildir': '/INBOX' - } - """ - - if not query: - raise ValueError('Query required for mu_search') - cmdline = ['mu', 'find', - '--format=xml', - query] - if sortfield: - cmdline.extend(['--sortfield', sortfield]) - if reverse: - cmdline.append('--reverse') - print(cmdline) - cmd = subprocess.run(cmdline, capture_output=True) - if cmd.returncode != 0: - raise MuError(cmd.returncode) - dom = xml.dom.minidom.parseString(cmd.stdout.decode('UTF-8')) - - message_list = [] - messages = dom.childNodes[0] - assert messages.localName == 'messages' - for message in messages.childNodes: - msg_dict = {} - if message.nodeType != xml.dom.Node.ELEMENT_NODE: - continue - for kv in message.childNodes: - if kv.nodeType != xml.dom.Node.ELEMENT_NODE: - continue - msg_dict[kv.localName] = kv.childNodes[0].data - message_list.append(msg_dict) - - return message_list |