def email_loop(self, imap: imaplib.IMAP4_SSL, really_get_new: bool = True) -> bytes: """SEARCHes the server, checking for (maybe) new email. Put this in a wait-until loop.""" imap.noop() # Returns a tuple. (Result_code, Actual_results). Actual_results is also a list. # Containing a single bytestring of space-separated return values. # And IMAP requires that imput values be comma separated. Because why not. return b','.join( imap.search( # Search from all addresses, it could be any of them. None, ' OR FROM '.join(['', *self.froms[:-1]]).strip(), 'FROM', self.froms[-1], 'TO', self.email, 'UNSEEN' if really_get_new else 'SEEN')[1][0].split(b' '))
def find_timepie_attachments( imap: imaplib.IMAP4_SSL, should_ignore_msg: t.Callable[[MsgId], bool], sender: str, is_gmail: bool = False, ) -> t.Mapping[MsgId, t.Sequence[Ping]]: status: t.Any details: t.Any status, details = imap.select('INBOX') if status != 'OK': raise RuntimeError(f'select failed: {details}') query = (_build_gmail_query(sender) if is_gmail else f'HEADER FROM {json.dumps(sender)}') status, details = imap.search(None, query) if status != 'OK': raise RuntimeError(f'bad status on search: {status}') msg_ids = set(details[0].decode('utf-8').split(' ')) logger.debug(f'pre-filter msg_ids = {msg_ids}') msg_ids = {m for m in msg_ids if not should_ignore_msg(m)} logger.debug(f'post-filter msg_ids = {msg_ids}') result = {} for msg_id in sorted(msg_ids): logger.info(f'fetching msg {msg_ids}') msg_info: t.Any status, msg_info = imap.fetch(msg_id, '(RFC822)') if status != 'OK': raise RuntimeError(f'bad status on fetch: {status}') msg = email.message_from_bytes(msg_info[0][1]) try: result[msg_id] = _find_timepie_part(msg) except ValueError: logger.info(f'msg {msg_id} has no timepie part') continue return result
def searchFolder(imapServer: imaplib.IMAP4_SSL, searchQuery, type, folder): imapServer.select(folder) searchResult = imapServer.search(searchQuery, type) ids = searchResult[1][0].decode("utf-8").split() foundMessages = [] for i in ids: emailData = imapServer.fetch(str(i), '(RFC822)') print("=======================================") for response_content in emailData: arr = response_content[0] if isinstance(arr, tuple): msg = email.message_from_string(str(arr[1], 'utf-8')) foundMessages.append({ "From": msg['From'], "Subject": msg['Subject'], "Date": msg["Date"], "Message-ID": msg["Message-ID"] }) imapServer.store(str(i), '-FLAGS', '\Flagged') return foundMessages
def gen_unseen_mbank_emails( database: KsiemgowyDB, mail: imaplib.IMAP4_SSL, imap_filter: str ) -> T.Iterator[Message]: """Connects to imap_server using login and password from the arguments, then yields a pair (mail_id_as_str, email_as_eml_string) for each of e-mails coming from mBank.""" mail.select("inbox") _, data = mail.search(None, imap_filter) mail_ids = data[0] id_list = mail_ids.split() for mail_id in reversed(id_list): _, data = mail.fetch(mail_id, "(RFC822)") for mail_number, response_part in enumerate(data): if not isinstance(response_part, tuple): continue msg = email.message_from_string(response_part[1].decode()) mail_key = f'{msg["Date"]}_{mail_number}' if database.was_imap_id_already_handled(mail_key): continue LOGGER.info("Handling e-mail id: %r", mail_id) yield msg database.mark_imap_id_already_handled(mail_key)