aboutsummaryrefslogtreecommitdiff
path: root/mu.py
blob: 93816f4c69f98a6d96c389a0645508b7a9499e74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import email.message
import email.policy
from email.parser import BytesParser
import subprocess
from subprocess import PIPE
import xml.dom.minidom
import xml.dom


parser = BytesParser(policy=email.policy.default)


def get_mail(id: str) -> email.message.Message:
    cmd = subprocess.run(['mu', 'find', '-u', f'i:{id}',
                          '--fields', 'l'],
                         stdout=PIPE)
    filename = cmd.stdout.decode('UTF-8').strip()

    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 mu_search(query, sortfield='subject', reverse=False):
    if not query:
        raise ValueError('Query required for mu_search')
    cmdline = ['mu', 'find',
               '--format=xml',
               query,
               '--sortfield', sortfield]
    if reverse:
        cmdline.append('--reverse')
    cmd = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
    dom = xml.dom.minidom.parse(cmd.stdout)
    if returncode := cmd.wait():
        raise MuError(returncode)

    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