浏览代码

fix merge with master

Bastien Sevajol 7 年前
父节点
当前提交
32b896ebfb
共有 1 个文件被更改,包括 58 次插入11 次删除
  1. 58 11
      tracim/tracim/lib/email_fetcher.py

+ 58 - 11
tracim/tracim/lib/email_fetcher.py 查看文件

1
 # -*- coding: utf-8 -*-
1
 # -*- coding: utf-8 -*-
2
 
2
 
3
-import imaplib
4
 import time
3
 import time
4
+import imaplib
5
+import json
5
 import typing
6
 import typing
6
 from email import message_from_bytes
7
 from email import message_from_bytes
7
-from email.header import decode_header, make_header
8
+from email.header import decode_header
9
+from email.header import make_header
8
 from email.message import Message
10
 from email.message import Message
9
 from email.utils import parseaddr
11
 from email.utils import parseaddr
10
 
12
 
177
         self._is_active = True
179
         self._is_active = True
178
 
180
 
179
     def run(self) -> None:
181
     def run(self) -> None:
182
+        logger.info(self, 'Starting MailFetcher')
180
         while self._is_active:
183
         while self._is_active:
184
+            logger.debug(self, 'sleep for {}'.format(self.delay))
181
             time.sleep(self.delay)
185
             time.sleep(self.delay)
182
             try:
186
             try:
183
                 self._connect()
187
                 self._connect()
200
         # TODO - G.M - 2017-11-15 Verify connection/disconnection
204
         # TODO - G.M - 2017-11-15 Verify connection/disconnection
201
         # Are old connexion properly close this way ?
205
         # Are old connexion properly close this way ?
202
         if self._connection:
206
         if self._connection:
207
+            logger.debug(self, 'Disconnect from IMAP')
203
             self._disconnect()
208
             self._disconnect()
204
         # TODO - G.M - 2017-11-23 Support for predefined SSLContext ?
209
         # TODO - G.M - 2017-11-23 Support for predefined SSLContext ?
205
         # without ssl_context param, tracim use default security configuration
210
         # without ssl_context param, tracim use default security configuration
206
         # which is great in most case.
211
         # which is great in most case.
207
         if self.use_ssl:
212
         if self.use_ssl:
213
+            logger.debug(self, 'Connect IMAP {}:{} using SSL'.format(
214
+                self.host,
215
+                self.port,
216
+            ))
208
             self._connection = imaplib.IMAP4_SSL(self.host, self.port)
217
             self._connection = imaplib.IMAP4_SSL(self.host, self.port)
209
         else:
218
         else:
219
+            logger.debug(self, 'Connect IMAP {}:{}'.format(
220
+                self.host,
221
+                self.port,
222
+            ))
210
             self._connection = imaplib.IMAP4(self.host, self.port)
223
             self._connection = imaplib.IMAP4(self.host, self.port)
211
 
224
 
212
         try:
225
         try:
226
+            logger.debug(self, 'Login IMAP with login {}'.format(
227
+                self.user,
228
+            ))
213
             self._connection.login(self.user, self.password)
229
             self._connection.login(self.user, self.password)
214
         except Exception as e:
230
         except Exception as e:
215
             log = 'IMAP login error: {}'
231
             log = 'IMAP login error: {}'
216
-            logger.warning(self, log.format(e.__str__()))
232
+            logger.error(self, log.format(e.__str__()))
217
 
233
 
218
     def _disconnect(self) -> None:
234
     def _disconnect(self) -> None:
219
         if self._connection:
235
         if self._connection:
228
         """
244
         """
229
         messages = []
245
         messages = []
230
         # select mailbox
246
         # select mailbox
247
+        logger.debug(self, 'Fetch messages from folder {}'.format(
248
+            self.folder,
249
+        ))
231
         rv, data = self._connection.select(self.folder)
250
         rv, data = self._connection.select(self.folder)
251
+        logger.debug(self, 'Response status {}'.format(
252
+            rv,
253
+        ))
232
         if rv == 'OK':
254
         if rv == 'OK':
233
             # get mails
255
             # get mails
234
             # TODO - G.M -  2017-11-15 Which files to select as new file ?
256
             # TODO - G.M -  2017-11-15 Which files to select as new file ?
235
             # Unseen file or All file from a directory (old one should be
257
             # Unseen file or All file from a directory (old one should be
236
             #  moved/ deleted from mailbox during this process) ?
258
             #  moved/ deleted from mailbox during this process) ?
259
+            logger.debug(self, 'Fetch unseen messages')
237
             rv, data = self._connection.search(None, "(UNSEEN)")
260
             rv, data = self._connection.search(None, "(UNSEEN)")
261
+            logger.debug(self, 'Response status {}'.format(
262
+                rv,
263
+            ))
238
             if rv == 'OK':
264
             if rv == 'OK':
239
                 # get mail content
265
                 # get mail content
266
+                logger.debug(self, 'Found {} unseen mails'.format(
267
+                    len(data[0].split()),
268
+                ))
240
                 for num in data[0].split():
269
                 for num in data[0].split():
241
                     # INFO - G.M - 2017-11-23 - Fetch (RFC288) to retrieve all
270
                     # INFO - G.M - 2017-11-23 - Fetch (RFC288) to retrieve all
242
                     # complete mails see example : https://docs.python.org/fr/3.5/library/imaplib.html#imap4-example .  # nopep8
271
                     # complete mails see example : https://docs.python.org/fr/3.5/library/imaplib.html#imap4-example .  # nopep8
243
                     # Be careful, This method remove also mails from Unseen
272
                     # Be careful, This method remove also mails from Unseen
244
                     # mails
273
                     # mails
274
+                    logger.debug(self, 'Fetch mail "{}"'.format(
275
+                        num,
276
+                    ))
245
                     rv, data = self._connection.fetch(num, '(RFC822)')
277
                     rv, data = self._connection.fetch(num, '(RFC822)')
278
+                    logger.debug(self, 'Response status {}'.format(
279
+                        rv,
280
+                    ))
246
                     if rv == 'OK':
281
                     if rv == 'OK':
247
                         msg = message_from_bytes(data[0][1])
282
                         msg = message_from_bytes(data[0][1])
248
                         messages.append(msg)
283
                         messages.append(msg)
249
                     else:
284
                     else:
250
                         log = 'IMAP : Unable to get mail : {}'
285
                         log = 'IMAP : Unable to get mail : {}'
251
-                        logger.debug(self, log.format(str(rv)))
286
+                        logger.error(self, log.format(str(rv)))
252
             else:
287
             else:
253
-                # FIXME : Distinct error from empty mailbox ?
254
-                pass
288
+                log = 'IMAP : Unable to get unseen mail : {}'
289
+                logger.error(self, log.format(str(rv)))
255
         else:
290
         else:
256
             log = 'IMAP : Unable to open mailbox : {}'
291
             log = 'IMAP : Unable to open mailbox : {}'
257
-            logger.debug(self, log.format(str(rv)))
292
+            logger.error(self, log.format(str(rv)))
258
         return messages
293
         return messages
259
 
294
 
260
     def _notify_tracim(
295
     def _notify_tracim(
266
         :param mails: list of mails to send
301
         :param mails: list of mails to send
267
         :return: unsended mails
302
         :return: unsended mails
268
         """
303
         """
304
+        logger.debug(self, 'Notify tracim about {} new responses'.format(
305
+            len(mails),
306
+        ))
269
         unsended_mails = []
307
         unsended_mails = []
270
         # TODO BS 20171124: Look around mail.get_from_address(), mail.get_key()
308
         # TODO BS 20171124: Look around mail.get_from_address(), mail.get_key()
271
         # , mail.get_body() etc ... for raise InvalidEmailError if missing
309
         # , mail.get_body() etc ... for raise InvalidEmailError if missing
282
                            use_txt_parsing=self.use_txt_parsing),
320
                            use_txt_parsing=self.use_txt_parsing),
283
                    }}
321
                    }}
284
             try:
322
             try:
323
+                logger.debug(
324
+                    self,
325
+                    'Contact API on {} with body {}'.format(
326
+                        self.endpoint,
327
+                        json.dumps(msg),
328
+                    ),
329
+                )
285
                 r = requests.post(self.endpoint, json=msg)
330
                 r = requests.post(self.endpoint, json=msg)
286
                 if r.status_code not in [200, 204]:
331
                 if r.status_code not in [200, 204]:
287
-                    log = 'bad status code response when sending mail to tracim: {}'  # nopep8
288
-                    logger.error(self, log.format(str(r.status_code)))
332
+                    details = r.json().get('msg')
333
+                    log = 'bad status code {} response when sending mail to tracim: {}'  # nopep8
334
+                    logger.error(self, log.format(
335
+                        str(r.status_code),
336
+                        details,
337
+                    ))
289
             # TODO - G.M - Verify exception correctly works
338
             # TODO - G.M - Verify exception correctly works
290
             except requests.exceptions.Timeout as e:
339
             except requests.exceptions.Timeout as e:
291
                 log = 'Timeout error to transmit fetched mail to tracim : {}'
340
                 log = 'Timeout error to transmit fetched mail to tracim : {}'
292
                 logger.error(self, log.format(str(e)))
341
                 logger.error(self, log.format(str(e)))
293
                 unsended_mails.append(mail)
342
                 unsended_mails.append(mail)
294
-                break
295
             except requests.exceptions.RequestException as e:
343
             except requests.exceptions.RequestException as e:
296
                 log = 'Fail to transmit fetched mail to tracim : {}'
344
                 log = 'Fail to transmit fetched mail to tracim : {}'
297
                 logger.error(self, log.format(str(e)))
345
                 logger.error(self, log.format(str(e)))
298
-                break
299
 
346
 
300
         return unsended_mails
347
         return unsended_mails