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 _check_sent(self, verbose: bool, imap: IMAP4_SSL, timeout: int, uid_to_from_address: Dict[uuid.UUID, str]) -> None: handle_response("select INBOX", imap.select()) end = time.time() + timeout while True: if time.time() > end: # We sort the addresses to get a stable output. unresponsive = ", ".join( uid for uid in sorted(uid_to_from_address.values())) raise CommandError("timeout; did not get answers for " f"{unresponsive}") remaining_uids = {} # Sending a noop prompts some IMAP servers to *really* check # whether there have been new emails delivered. Without it, it # takes longer for us to find the emails we are looking for. handle_response("noop", imap.noop()) # It may be possible to reduce the number of queries to the IMAP # server by ORing the SUBJECT queries. However, it complicates the # code quite a bit. for uid, from_address in uid_to_from_address.items(): if verbose: self.stdout.write(f"Searching for: {uid} from " f"{from_address}...") mess_uid = \ handle_response("search", imap.uid( "search", f'SUBJECT "{uid}" ' # type: ignore f'FROM "{from_address}"')) if mess_uid[0] == b"": remaining_uids[uid] = from_address else: if verbose: self.stdout.write(f"Found {uid}!") answer = handle_response( "store", imap.uid( "store", mess_uid[0], "+FLAGS", # type: ignore r"(\Deleted \Seen)" # type: ignore )) if verbose: self.stdout.write(repr(answer)) if len(remaining_uids) == 0: break uid_to_from_address = remaining_uids # Give a bit of respite to the IMAP server. time.sleep(1)