|
@@ -5,7 +5,7 @@ import time
|
5
|
5
|
import imaplib
|
6
|
6
|
import datetime
|
7
|
7
|
import json
|
8
|
|
-from typing import Union
|
|
8
|
+import typing
|
9
|
9
|
from email.message import Message
|
10
|
10
|
from email.header import Header, decode_header, make_header
|
11
|
11
|
from email.utils import parseaddr, parsedate_tz, mktime_tz
|
|
@@ -50,22 +50,22 @@ def decode_mail(msg: Message)-> dict:
|
50
|
50
|
)
|
51
|
51
|
|
52
|
52
|
except Exception:
|
53
|
|
- # TODO: exception -> mail not correctly formatted
|
|
53
|
+ # FIXME - G.M - 2017-15-11 - handle exceptions correctly
|
54
|
54
|
return {}
|
55
|
|
- # TODO : msg.get_body look like the best way to get body
|
56
|
|
- # but it's a new feature now (08112017).
|
|
55
|
+ # FIXME - G.M - 2017-15-11 - get the best body candidate in MIME
|
|
56
|
+ # msg.get_body() look like the best way to get body but it's a py3.6 feature
|
57
|
57
|
for part in msg.walk():
|
58
|
58
|
if not part.get_content_type() == "text/plain":
|
59
|
59
|
continue
|
60
|
60
|
else:
|
61
|
|
- # TODO: check if decoding is working correctly
|
|
61
|
+ # FIXME: check if decoding is working correctly
|
62
|
62
|
charset = part.get_content_charset('iso-8859-1')
|
63
|
63
|
mail_data['body'] = part.get_payload(decode=True).decode(charset)
|
64
|
64
|
break
|
65
|
65
|
return mail_data
|
66
|
66
|
|
67
|
67
|
|
68
|
|
-def get_tracim_content_key(mail_data: dict) -> Union[str, None]:
|
|
68
|
+def get_tracim_content_key(mail_data: dict) -> typing.Optional[str]:
|
69
|
69
|
|
70
|
70
|
""" Link mail_data dict to tracim content
|
71
|
71
|
First try checking special header, them check 'to' header
|
|
@@ -82,7 +82,7 @@ def get_tracim_content_key(mail_data: dict) -> Union[str, None]:
|
82
|
82
|
return key
|
83
|
83
|
|
84
|
84
|
|
85
|
|
-def find_key_from_mail_adress(mail_address: str) -> Union[str, None]:
|
|
85
|
+def find_key_from_mail_adress(mail_address: str) -> typing.Optional[str]:
|
86
|
86
|
""" Parse mail_adress-like string
|
87
|
87
|
to retrieve key.
|
88
|
88
|
|
|
@@ -100,7 +100,8 @@ def find_key_from_mail_adress(mail_address: str) -> Union[str, None]:
|
100
|
100
|
|
101
|
101
|
class MailFetcher(object):
|
102
|
102
|
|
103
|
|
- def __init__(self, host, port, user, password, folder, delay, endpoint):
|
|
103
|
+ def __init__(self, host, port, user, password, folder, delay, endpoint) \
|
|
104
|
+ -> None:
|
104
|
105
|
self._connection = None
|
105
|
106
|
self._mails = []
|
106
|
107
|
self.host = host
|
|
@@ -125,11 +126,12 @@ class MailFetcher(object):
|
125
|
126
|
self._is_active = False
|
126
|
127
|
|
127
|
128
|
def _connect(self) -> None:
|
128
|
|
- # verify if connected ?
|
|
129
|
+ # FIXME - G.M - 2017-11-15 Verify connection/disconnection
|
|
130
|
+ # Are old connexion properly close this way ?
|
129
|
131
|
if self._connection:
|
130
|
132
|
self._disconnect()
|
131
|
|
- # TODO: Support unencrypted connection ?
|
132
|
|
- # TODO: Support keyfile,certfile ?
|
|
133
|
+ # TODO - G.M - 2017-11-15 Support unencrypted connection ?
|
|
134
|
+ # TODO - G.M - 2017-11-15 Support for keyfile,certfile ?
|
133
|
135
|
self._connection = imaplib.IMAP4_SSL(self.host, self.port)
|
134
|
136
|
try:
|
135
|
137
|
self._connection.login(self.user, self.password)
|
|
@@ -152,7 +154,9 @@ class MailFetcher(object):
|
152
|
154
|
rv, data = self._connection.select(self.folder)
|
153
|
155
|
if rv == 'OK':
|
154
|
156
|
# get mails
|
155
|
|
- # TODO: search only new mail or drop/moved the added one ?
|
|
157
|
+ # FIXME - G.M - 2017-11-15 Which files to select as new file ?
|
|
158
|
+ # Unseen file or All file from a directory (old one should be moved/
|
|
159
|
+ # deleted from mailbox during this process) ?
|
156
|
160
|
rv, data = self._connection.search(None, "(UNSEEN)")
|
157
|
161
|
if rv == 'OK':
|
158
|
162
|
# get mail content
|
|
@@ -162,14 +166,12 @@ class MailFetcher(object):
|
162
|
166
|
msg = message_from_bytes(data[0][1])
|
163
|
167
|
self._mails.append(msg)
|
164
|
168
|
else:
|
165
|
|
- # TODO : Check best debug value
|
166
|
169
|
log = 'IMAP : Unable to get mail : {}'
|
167
|
170
|
logger.debug(self, log.format(str(rv)))
|
168
|
171
|
else:
|
169
|
|
- # TODO : Distinct error from empty mailbox ?
|
|
172
|
+ # FIXME : Distinct error from empty mailbox ?
|
170
|
173
|
pass
|
171
|
174
|
else:
|
172
|
|
- # TODO : Check best debug value
|
173
|
175
|
log = 'IMAP : Unable to open mailbox : {}'
|
174
|
176
|
logger.debug(self, log.format(str(rv)))
|
175
|
177
|
|
|
@@ -183,6 +185,6 @@ class MailFetcher(object):
|
183
|
185
|
"payload": {
|
184
|
186
|
"content": decoded_mail['body'],
|
185
|
187
|
}}
|
186
|
|
-
|
|
188
|
+ # FIXME - G.M - 2017-11-15 - Catch exception from http request
|
187
|
189
|
requests.post(self.endpoint, json=msg)
|
188
|
190
|
pass
|