Преглед на файлове

Add logs on email fetcher

Bastien Sevajol преди 6 години
родител
ревизия
3de125040b
променени са 1 файла, в които са добавени 59 реда и са изтрити 14 реда
  1. 59 14
      tracim/tracim/lib/email_fetcher.py

+ 59 - 14
tracim/tracim/lib/email_fetcher.py Целия файл

@@ -1,19 +1,19 @@
1 1
 # -*- coding: utf-8 -*-
2 2
 
3
-import sys
4 3
 import time
5 4
 import imaplib
6
-import datetime
7 5
 import json
8 6
 import typing
9 7
 from email.message import Message
10
-from email.header import Header, decode_header, make_header
11
-from email.utils import parseaddr, parsedate_tz, mktime_tz
8
+from email.header import decode_header
9
+from email.header import make_header
10
+from email.utils import parseaddr
12 11
 from email import message_from_bytes
13 12
 
14 13
 import markdown
15 14
 import requests
16
-from bs4 import BeautifulSoup, Tag
15
+from bs4 import BeautifulSoup
16
+from bs4 import Tag
17 17
 from email_reply_parser import EmailReplyParser
18 18
 
19 19
 from tracim.lib.base import logger
@@ -214,7 +214,9 @@ class MailFetcher(object):
214 214
         self._is_active = True
215 215
 
216 216
     def run(self) -> None:
217
+        logger.info(self, 'Starting MailFetcher')
217 218
         while self._is_active:
219
+            logger.debug(self, 'sleep for {}'.format(self.delay))
218 220
             time.sleep(self.delay)
219 221
             try:
220 222
                 self._connect()
@@ -237,20 +239,32 @@ class MailFetcher(object):
237 239
         # TODO - G.M - 2017-11-15 Verify connection/disconnection
238 240
         # Are old connexion properly close this way ?
239 241
         if self._connection:
242
+            logger.debug(self, 'Disconnect from IMAP')
240 243
             self._disconnect()
241 244
         # TODO - G.M - 2017-11-23 Support for predefined SSLContext ?
242 245
         # without ssl_context param, tracim use default security configuration
243 246
         # which is great in most case.
244 247
         if self.use_ssl:
248
+            logger.debug(self, 'Connect IMAP {}:{} using SSL'.format(
249
+                self.host,
250
+                self.port,
251
+            ))
245 252
             self._connection = imaplib.IMAP4_SSL(self.host, self.port)
246 253
         else:
254
+            logger.debug(self, 'Connect IMAP {}:{}'.format(
255
+                self.host,
256
+                self.port,
257
+            ))
247 258
             self._connection = imaplib.IMAP4(self.host, self.port)
248 259
 
249 260
         try:
261
+            logger.debug(self, 'Login IMAP with login {}'.format(
262
+                self.user,
263
+            ))
250 264
             self._connection.login(self.user, self.password)
251 265
         except Exception as e:
252 266
             log = 'IMAP login error: {}'
253
-            logger.warning(self, log.format(e.__str__()))
267
+            logger.error(self, log.format(e.__str__()))
254 268
 
255 269
     def _disconnect(self) -> None:
256 270
         if self._connection:
@@ -265,33 +279,52 @@ class MailFetcher(object):
265 279
         """
266 280
         messages = []
267 281
         # select mailbox
282
+        logger.debug(self, 'Fetch messages from folder {}'.format(
283
+            self.folder,
284
+        ))
268 285
         rv, data = self._connection.select(self.folder)
286
+        logger.debug(self, 'Response status {}'.format(
287
+            rv,
288
+        ))
269 289
         if rv == 'OK':
270 290
             # get mails
271 291
             # TODO - G.M -  2017-11-15 Which files to select as new file ?
272 292
             # Unseen file or All file from a directory (old one should be
273 293
             #  moved/ deleted from mailbox during this process) ?
294
+            logger.debug(self, 'Fetch unseen messages')
274 295
             rv, data = self._connection.search(None, "(UNSEEN)")
296
+            logger.debug(self, 'Response status {}'.format(
297
+                rv,
298
+            ))
275 299
             if rv == 'OK':
276 300
                 # get mail content
301
+                logger.debug(self, 'Found {} unseen mails'.format(
302
+                    len(data[0].split()),
303
+                ))
277 304
                 for num in data[0].split():
278 305
                     # INFO - G.M - 2017-11-23 - Fetch (RFC288) to retrieve all
279 306
                     # complete mails see example : https://docs.python.org/fr/3.5/library/imaplib.html#imap4-example .  # nopep8
280 307
                     # Be careful, This method remove also mails from Unseen
281 308
                     # mails
309
+                    logger.debug(self, 'Fetch mail "{}"'.format(
310
+                        num,
311
+                    ))
282 312
                     rv, data = self._connection.fetch(num, '(RFC822)')
313
+                    logger.debug(self, 'Response status {}'.format(
314
+                        rv,
315
+                    ))
283 316
                     if rv == 'OK':
284 317
                         msg = message_from_bytes(data[0][1])
285 318
                         messages.append(msg)
286 319
                     else:
287 320
                         log = 'IMAP : Unable to get mail : {}'
288
-                        logger.debug(self, log.format(str(rv)))
321
+                        logger.error(self, log.format(str(rv)))
289 322
             else:
290
-                # FIXME : Distinct error from empty mailbox ?
291
-                pass
323
+                log = 'IMAP : Unable to get unseen mail : {}'
324
+                logger.error(self, log.format(str(rv)))
292 325
         else:
293 326
             log = 'IMAP : Unable to open mailbox : {}'
294
-            logger.debug(self, log.format(str(rv)))
327
+            logger.error(self, log.format(str(rv)))
295 328
         return messages
296 329
 
297 330
     def _notify_tracim(
@@ -303,6 +336,9 @@ class MailFetcher(object):
303 336
         :param mails: list of mails to send
304 337
         :return: unsended mails
305 338
         """
339
+        logger.debug(self, 'Notify tracim about {} new responses'.format(
340
+            len(mails),
341
+        ))
306 342
         unsended_mails = []
307 343
         # TODO BS 20171124: Look around mail.get_from_address(), mail.get_key()
308 344
         # , mail.get_body() etc ... for raise InvalidEmailError if missing
@@ -317,19 +353,28 @@ class MailFetcher(object):
317 353
                        'content': mail.get_body(),
318 354
                    }}
319 355
             try:
356
+                logger.debug(
357
+                    self,
358
+                    'Contact API on {} with body {}'.format(
359
+                        self.endpoint,
360
+                        json.dumps(msg),
361
+                    ),
362
+                )
320 363
                 r = requests.post(self.endpoint, json=msg)
321 364
                 if r.status_code not in [200, 204]:
322
-                    log = 'bad status code response when sending mail to tracim: {}'  # nopep8
323
-                    logger.error(self, log.format(str(r.status_code)))
365
+                    details = r.json().get('msg')
366
+                    log = 'bad status code {} response when sending mail to tracim: {}'  # nopep8
367
+                    logger.error(self, log.format(
368
+                        str(r.status_code),
369
+                        details,
370
+                    ))
324 371
             # TODO - G.M - Verify exception correctly works
325 372
             except requests.exceptions.Timeout as e:
326 373
                 log = 'Timeout error to transmit fetched mail to tracim : {}'
327 374
                 logger.error(self, log.format(str(e)))
328 375
                 unsended_mails.append(mail)
329
-                break
330 376
             except requests.exceptions.RequestException as e:
331 377
                 log = 'Fail to transmit fetched mail to tracim : {}'
332 378
                 logger.error(self, log.format(str(e)))
333
-                break
334 379
 
335 380
         return unsended_mails