aboutsummaryrefslogtreecommitdiff
path: root/ctec/logic.py
blob: 57b553c0fb0f93915c52c30a440e150d6a7271aa (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
import imaplib
import mailbox
import pathlib
import pprint
import re
from typing import List, Union, Tuple

from . import import_or_install, imap_response

mailbox.Maildir.colon = '!'

FLAGS = re.compile(rb'FLAGS \(([^)]+?)\)')

def clean_folder_name(folder_name: str, separator: str) -> str:
    return folder_name.replace('.', '-').replace(separator, '.').replace('/', '-')

class Account:
    def __init__(self, address: str, info: dict):
        appdirs = import_or_install('appdirs')
        data_dir = pathlib.Path(appdirs.user_data_dir(appname='ctec', appauthor=False))
        self.address = address
        self.mailbox = mailbox.Maildir(data_dir / address)
        self.info = info

    def fetch_folders(self):
        with imaplib.IMAP4_SSL(self.info['imap host']) as M:
            M.login(self.address, self.info['password'])
            folder_list: List[bytes]
            typ, folder_list = M.list()
            for folder in folder_list:
                folder_info = imap_response.List.parse(folder)
                self.mailbox.add_folder(clean_folder_name(folder_info.name, folder_info.delimiter))

    def fetch_inbox(self):
        with imaplib.IMAP4_SSL(self.info['imap host']) as M:
            M.login(self.address, self.info['password'])
            inbox = self.mailbox.add_folder('Inbox')
            M.select()
            typ, data = M.search(None, 'ALL')
            for num in data[0].split():
                typ, data = M.fetch(num, '(FLAGS RFC822)')
                for prefix, message in data[:-1]:
                    flags = FLAGS.search(prefix).group(1).split()
                    message = mailbox.MaildirMessage(message)
                    print(message['Subject'], flags)
                    if rb'\Seen' in flags:
                        message.add_flag('S')
                        message.set_subdir('cur')
                    if 'Message-ID' in message:
                        message_id = message['Message-ID'].strip()
                    else:
                        print(message)
                        raise KeyError('No message ID header')
                    if not any(x['Message-ID'].strip() == message_id for x in inbox):
                        inbox.add(message)
            M.close()

    def folders(self) -> List[Tuple[str, mailbox.Maildir]]:
        return [(folder, self.mailbox.get_folder(folder)) for folder in self.mailbox.list_folders()]

    def inbox(self) -> mailbox.Maildir:
        return self.mailbox.add_folder('Inbox')