def login(self): try: if self.source.use_ssl: mailbox = IMAP4_SSL(host=self.source.host.encode('utf-8'), port=self.source.port) else: mailbox = IMAP4(host=self.source.host.encode('utf-8'), port=self.source.port) if 'STARTTLS' in mailbox.capabilities: #Always use starttls if server supports it res = mailbox.starttls() if not is_ok(res): # TODO: Require bad login from client error raise ReaderError(res) if 'IDLE' in mailbox.capabilities: self.can_push = True res = mailbox.login(self.source.username, self.source.password) if not is_ok(res): # TODO: Require bad login from client error raise ClientError(res) res = mailbox.select(self.source.folder) if not is_ok(res): # TODO: Require bad login from client error raise ClientError(res) self.selected_folder = True self.mailbox = mailbox except IMAP4.abort as e: raise IrrecoverableError(e) except IMAP4.error as e: raise ClientError(e)
def _check_connection(self, do_login=True): if not self.imap_client or (self.imap_client.state == 'LOGOUT'): if self.use_ssl: self._values['imap'] = IMAP4_SSL(self.hostname) else: self._values['imap'] = IMAP4(self.hostname) if do_login: if self.imap_client.state == 'NONAUTH': (typ, data) = self.imap_client.login(self._values['login'], self._values['password']) if typ != 'OK': _err_msg = 'Invalid IMAP response from server "%s" when trying to login: %r' % (self.hostname, data) if self.use_exceptions: raise MailMigError(_err_msg) else: # TODO: Add logger here print >>sys.stderr, _err_msg return None return self.imap_client
pass if len(removed) == len(files): print(f"STARTUP : {len(files)} file(s) removed !") else: print(f"STARTUP : {len(removed)} file(s) removed !") print( f"STARTUP : {len(files)-len(removed)} file(s) remaining..." ) print(f for f in removed) else: print("STARTUP : No files have been found") print("STARTUP : Trying to start application...") # Create IMAP_SSL instance M = IMAP4_SSL(IMAP_SERVER) # every 28 min and 59 seconds, reboot to prevent the bot to get out of his idle state while True: M.login(EMAIL, PASSWORD) # needed to get rid of the Auth state M.select("INBOX") # start Idler idler = Idler(M) idler.start() print( f"[{datetime.now(timezone(TIMEZONE)).strftime('%d/%m/%Y %H:%M:%S')}] : App online !" ) sleep(1739) # IMAP4_SSL.Idle_timout - 1s
def do_import_content(mbox, only_new=True): mbox = mbox.db.merge(mbox) session = mbox.db session.add(mbox) if mbox.use_ssl: mailbox = IMAP4_SSL(host=mbox.host.encode('utf-8'), port=mbox.port) else: mailbox = IMAP4(host=mbox.host.encode('utf-8'), port=mbox.port) if 'STARTTLS' in mailbox.capabilities: # Always use starttls if server supports it mailbox.starttls() mailbox.login(mbox.username, mbox.password) mailbox.select(mbox.folder) command = "ALL" search_status = None email_ids = None if only_new and mbox.last_imported_email_uid: command = "(UID %s:*)" % mbox.last_imported_email_uid search_status, search_result = mailbox.uid('search', None, command) # print "UID searched with: "+ command + ", got result "+repr(search_status)+" and found "+repr(search_result) email_ids = search_result[0].split() # print email_ids if (only_new and search_status == 'OK' and email_ids and email_ids[0] == mbox.last_imported_email_uid): # Note: the email_ids[0]==mbox.last_imported_email_uid test is # necessary beacuse according to https://tools.ietf.org/html/rfc3501 # seq-range like "3291:* includes the UID of the last message in # the mailbox, even if that value is less than 3291." # discard the first message, it should be the last imported email. del email_ids[0] else: # Either: # a) we don't import only new messages or # b) the message with mbox.last_imported_email_uid hasn't been found # (may have been deleted) # In this case we request all messages and rely on duplicate # detection command = "ALL" search_status, search_result = mailbox.uid('search', None, command) # print "UID searched with: "+ command + ", got result "+repr(search_status)+" and found "+repr(search_result) assert search_status == 'OK' email_ids = search_result[0].split() def import_email(mailbox_obj, email_id): session = mailbox_obj.db # print "running fetch for message: "+email_id status, message_data = mailbox.uid('fetch', email_id, "(RFC822)") assert status == 'OK' # print repr(message_data) for response_part in message_data: if isinstance(response_part, tuple): message_string = response_part[1] assert message_string if mailbox_obj.message_ok_to_import(message_string): (email_object, dummy, error) = mailbox_obj.parse_email(message_string) if error: raise Exception(error) session.add(email_object) translate_content(email_object) # should delay else: print( "Skipped message with imap id %s (bounce or vacation message)" % (email_id)) # print "Setting mailbox_obj.last_imported_email_uid to "+email_id mailbox_obj.last_imported_email_uid = email_id if len(email_ids): print("Processing messages from IMAP: %d " % (len(email_ids))) for email_id in email_ids: with transaction.manager: import_email(mbox, email_id) else: print("No IMAP messages to process") discussion_id = mbox.discussion_id mailbox.close() mailbox.logout() with transaction.manager: if len(email_ids): # We imported mails, we need to re-thread emails = session.query(Email).filter( Email.discussion_id == discussion_id, ).options( joinedload_all(Email.parent)) AbstractMailbox.thread_mails(emails)