浏览代码

IDLE mode

Guénaël Muller 7 年前
父节点
当前提交
b1c4767274
共有 1 个文件被更改,包括 34 次插入19 次删除
  1. 34 19
      tracim/tracim/lib/email_fetcher.py

+ 34 - 19
tracim/tracim/lib/email_fetcher.py 查看文件

26
 IMAP_SEEN_FLAG = SEEN
26
 IMAP_SEEN_FLAG = SEEN
27
 IMAP_CHECKED_FLAG = FLAGGED
27
 IMAP_CHECKED_FLAG = FLAGGED
28
 MAIL_FETCHER_FILELOCK_TIMEOUT = 10
28
 MAIL_FETCHER_FILELOCK_TIMEOUT = 10
29
-
29
+MAIL_FETCHER_CONNECTION_TIMEOUT = 60*9
30
+IDLE_MODE = True
30
 
31
 
31
 class MessageContainer(object):
32
 class MessageContainer(object):
32
     def __init__(self, message: Message, uid: int) -> None:
33
     def __init__(self, message: Message, uid: int) -> None:
196
         while self._is_active:
197
         while self._is_active:
197
             try:
198
             try:
198
                 imapc = IMAPClient(self.host, ssl=self.use_ssl)
199
                 imapc = IMAPClient(self.host, ssl=self.use_ssl)
199
-                logger.debug(self, 'sleep for {}'.format(self.delay))
200
-                time.sleep(self.delay)
201
                 imapc.login(self.user, self.password)
200
                 imapc.login(self.user, self.password)
202
-                with self.lock.acquire(
203
-                        timeout=MAIL_FETCHER_FILELOCK_TIMEOUT
204
-                ):
205
-                    messages = self._fetch(imapc)
206
-                    cleaned_mails = [DecodedMail(m.message, m.uid)
207
-                                     for m in messages]
208
-                    self._notify_tracim(cleaned_mails, imapc)
201
+                # select mailbox
202
+                logger.debug(self, 'Select folder {}'.format(
203
+                    self.folder,
204
+                ))
205
+                deadline = time.time() + MAIL_FETCHER_CONNECTION_TIMEOUT
206
+                while time.time() < deadline:
207
+                    self._check_mail(imapc)
208
+
209
+                    if IDLE_MODE and imapc.has_capability('IDLE'):
210
+                        logger.debug(self, 'wail for event(IDLE)')
211
+                        imapc.idle()
212
+                        imapc.idle_check(
213
+                            timeout=MAIL_FETCHER_CONNECTION_TIMEOUT
214
+                        )
215
+                        imapc.idle_done()
216
+                    else:
217
+                        logger.debug(self, 'sleep for {}'.format(self.delay))
218
+                        time.sleep(self.delay)
209
             except filelock.Timeout as e:
219
             except filelock.Timeout as e:
210
                 log = 'Mail Fetcher Lock Timeout {}'
220
                 log = 'Mail Fetcher Lock Timeout {}'
211
                 logger.warning(self, log.format(e.__str__()))
221
                 logger.warning(self, log.format(e.__str__()))
215
             finally:
225
             finally:
216
                 imapc.logout()
226
                 imapc.logout()
217
 
227
 
228
+    def _check_mail(self, imapc: IMAPClient) -> None:
229
+        with self.lock.acquire(
230
+                timeout=MAIL_FETCHER_FILELOCK_TIMEOUT
231
+        ):
232
+            messages = self._fetch(imapc)
233
+            cleaned_mails = [DecodedMail(m.message, m.uid)
234
+                             for m in messages]
235
+            self._notify_tracim(cleaned_mails, imapc)
236
+
218
     def stop(self) -> None:
237
     def stop(self) -> None:
219
         self._is_active = False
238
         self._is_active = False
220
 
239
 
221
-    def _fetch(self, imapclient: IMAPClient) -> typing.List[MessageContainer]:
240
+    def _fetch(self, imapc: IMAPClient) -> typing.List[MessageContainer]:
222
         """
241
         """
223
         Get news message from mailbox
242
         Get news message from mailbox
224
         :return: list of new mails
243
         :return: list of new mails
225
         """
244
         """
226
         messages = []
245
         messages = []
227
-        # select mailbox
228
-        logger.debug(self, 'Fetch messages from folder {}'.format(
229
-            self.folder,
230
-        ))
231
 
246
 
232
-        imapclient.select_folder(self.folder)
247
+        imapc.select_folder(self.folder)
233
         logger.debug(self, 'Fetch unseen messages')
248
         logger.debug(self, 'Fetch unseen messages')
234
-        uids = imapclient.search(['UNSEEN'])
249
+        uids = imapc.search(['UNSEEN'])
235
         logger.debug(self, 'Found {} unseen mails'.format(
250
         logger.debug(self, 'Found {} unseen mails'.format(
236
             len(uids),
251
             len(uids),
237
         ))
252
         ))
238
-        imapclient.add_flags(uids, IMAP_SEEN_FLAG)
253
+        imapc.add_flags(uids, IMAP_SEEN_FLAG)
239
         logger.debug(self, 'Temporary Flag {} mails as seen'.format(
254
         logger.debug(self, 'Temporary Flag {} mails as seen'.format(
240
             len(uids),
255
             len(uids),
241
         ))
256
         ))
242
-        for msgid, data in imapclient.fetch(uids, ['BODY.PEEK[]']).items():
257
+        for msgid, data in imapc.fetch(uids, ['BODY.PEEK[]']).items():
243
             # INFO - G.M - 2017-12-08 - Fetch BODY.PEEK[]
258
             # INFO - G.M - 2017-12-08 - Fetch BODY.PEEK[]
244
             # Retrieve all mail(body and header) but don't set mail
259
             # Retrieve all mail(body and header) but don't set mail
245
             # as seen because of PEEK
260
             # as seen because of PEEK