summaryrefslogtreecommitdiff
path: root/py-fake-service/app/adapter/mail_service.py
blob: 66c0d74e17f9b0b60eb8c5420f78541c6fc3a1c4 (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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import os
import mailbox

from tagsset import TagsSet
from mailset import MailSet
from contacts import Contacts
from mail import Mail


class MailService:
    MAILSET_PATH = os.path.join(os.environ['HOME'], 'mailsets', 'mediumtagged')

    def __init__(self):
        self.mailset = MailSet()
        self.tagsset = TagsSet()
        self.contacts = Contacts()

    def reset(self):
        self.mailset = MailSet()
        self.tagsset = TagsSet()
        self.contacts = Contacts()

    def _read_file(self, filename):
        with open(filename, 'r') as fd:
            return fd.read()

    def _create_message_from_file(self, filename):
        data = self._read_file(filename)
        if data.startswith('From '):
            msg = mailbox.mbox(filename).popitem()[1]
            msg.from_addr = msg.get_from()
        else:
            msg = mailbox.Message(data)
            msg.from_addr = msg.get('From')
        return msg

    def load_mailset(self):
        mbox_filenames = [
            filename
            for filename in os.listdir
            (self.MAILSET_PATH) if filename.startswith('mbox')]
        messages = (self._create_message_from_file(os.path.join(self.MAILSET_PATH, mbox))
                 for mbox in mbox_filenames)

        for message in messages:
            self.mailset.add(message)
            self.tagsset.add(message)
            self.contacts.add(message)

    def mails(self, query, page, window_size):
        mails = self.mailset.values()
        mails = [mail for mail in mails if query.test(mail)]
        return sorted(mails, key=lambda mail: mail.date, reverse=True)

    def mail(self, mail_id):
        return self.mailset.get(mail_id)

    def search_contacts(self, query):
        return self.contacts.search(query)

    def mark_as_read(self, mail_id):
        self.mailset.mark_as_read(mail_id)
        self.tagsset.mark_as_read(self.mail(mail_id).tags)

    def delete_mail(self, mail_id):
        purged = self.mailset.delete(mail_id)
        if not purged:
            self.tagsset.increment_tag_total_count('trash')

    def update_tags_for(self, mail_id, new_tags):
        mail = self.mail(mail_id)

        new_tags_set = set(new_tags)
        old_tags_set = set(mail.tags)

        increment_set = new_tags_set - old_tags_set
        decrement_set = old_tags_set - new_tags_set

        map(lambda x: self.tagsset.increment_tag_total_count(x), increment_set)
        map(lambda x: self.tagsset.decrement_tag_total_count(x), decrement_set)

        mail.tags = new_tags

    def send(self, mail):
        mail = Mail.from_json(mail)
        self.mailset.update(mail)
        self.tagsset.increment_tag_total_count('sent')
        self.tagsset.decrement_tag_total_count('drafts')
        return mail.ident

    def save_draft(self, mail):
        mail = self.mailset.add_draft(Mail.from_json(mail))
        return mail.ident

    def update_draft(self, mail):
        mail = Mail.from_json(mail)
        self.mailset.update(mail)
        return mail.ident

    def draft_reply_for(self, mail_id):
        return self.mailset.find(draft_reply_for=mail_id)