Beispiel #1
0
 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)