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')
|