-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmbox.py
More file actions
143 lines (110 loc) · 3.92 KB
/
mbox.py
File metadata and controls
143 lines (110 loc) · 3.92 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import mailbox
from dataclasses import dataclass, asdict
import email
__version__ = "1.0.0"
@dataclass
class Message:
frm: str = 'Unknown sender'
to: str = 'Unknown recipient'
subj: str = 'Default subj'
content: str = 'This is default text'
state: str = 'Unread'
id: str = 'None'
@staticmethod
def __version__():
return __version__
def __post_init__(self):
for (name, field_type) in self.__annotations__.items():
if not isinstance(self.__dict__[name], field_type):
current_type = type(self.__dict__[name])
raise TypeError(f"The field `{name}` has `{current_type}` type instead of `{field_type}`")
@classmethod
def from_dict(cls, d):
return Message(**d)
def to_dict(self):
return asdict(self)
def to_string(self):
raise NotImplementedError('Method must be implemented in 2.0.0 version')
class MessageHeader:
ID = 'ID'
FROM = 'From'
TO = 'To'
SUBJECT = 'Subject'
STATE = 'State'
class MessageState:
UNREAD = 'Unread'
READ = 'Read'
ANSWERED = 'Answered'
FORWARDED = 'Forwarded'
DELETED = 'Deleted'
class InvalidIdError(Exception):
pass
class MBox:
def __init__(self, path):
self._path = f"{path}/smartiqa.mbox"
self.mbox = mailbox.mbox(path=self._path)
def path(self):
return self._path
def add_message(self, message: Message):
msg = self._message_to_struct(message)
id = self.mbox.add(msg)
msg['ID'] = str(id)
self.mbox.update({id: msg})
self._flush()
return id
def update_message(self, id: str, message: Message):
self.mbox.update({id: self._message_to_struct(message)})
def get_message(self, id: str):
msg = self.mbox.get(id)
if not msg:
raise InvalidIdError(f"Error with {id} does not exist")
return Message(frm=msg.get(MessageHeader.FROM),
to=msg.get(MessageHeader.TO),
subj=msg.get(MessageHeader.SUBJECT),
content=msg.get_payload().replace('\n', ''),
state=msg.get(MessageHeader.STATE),
id=str(id))
def answer_message(self, id: str):
message = self.get_message(id)
message.state = MessageState.ANSWERED
self.update_message(id, message)
def read_message(self, id: str):
message = self.get_message(id)
message.state = MessageState.READ
self.update_message(id, message)
def list_messages(self):
return [self._struct_to_message(msg) for msg in self.mbox.values()]
def count(self):
return self.mbox.__len__()
def remove_message(self, id: str):
self.mbox.remove(id)
def clear(self):
self.mbox.clear()
def clear_and_close(self):
self.mbox.clear()
self.mbox.close()
def close(self):
self.mbox.close()
def unused_method(self):
print('This method is unused')
print('We added it to the module in order to check Code coverage')
print('These three lines are missed from testing')
@staticmethod
def _message_to_struct(message: Message) -> email.message:
msg = mailbox.mboxMessage()
msg['From'] = message.frm
msg['To'] = message.to
msg['Subject'] = message.subj
msg['State'] = message.state
msg.set_payload(message.content)
return msg
@staticmethod
def _struct_to_message(struct: email.message) -> Message:
return Message(frm=struct.get(MessageHeader.FROM),
to=struct.get(MessageHeader.TO),
subj=struct.get(MessageHeader.SUBJECT),
content=struct.get_payload().replace('\n', ''),
state=struct.get(MessageHeader.STATE),
id=struct.get(MessageHeader.ID))
def _flush(self):
return self.mbox.flush()