From 75002d677f58376a0bdc829e1fb27086653f3e04 Mon Sep 17 00:00:00 2001 From: PAN Lei Date: Thu, 2 Apr 2026 23:22:33 +0200 Subject: [PATCH] can read only one mail --- read_confirmation_emails.py | 2 +- src/db/mongo_manager.py | 19 ++++++++ src/mail/imap_proxy_reader.py | 85 +++++++++++++++-------------------- 3 files changed, 57 insertions(+), 49 deletions(-) diff --git a/read_confirmation_emails.py b/read_confirmation_emails.py index ad887c8..f11892c 100755 --- a/read_confirmation_emails.py +++ b/read_confirmation_emails.py @@ -15,7 +15,7 @@ def create_message_from_item(item: ReserveResultPojo): def main(): # initialize discord print("init discord done") - _accepted_appointments = read_mails_and_find_confirmation_contacts(mode='gmx_only') + _accepted_appointments = read_mails_and_find_confirmation_contacts(mode='default') # for item in _accepted_appointments: # send_message(create_message_from_item(item)) diff --git a/src/db/mongo_manager.py b/src/db/mongo_manager.py index 95c07f1..8ac1d44 100755 --- a/src/db/mongo_manager.py +++ b/src/db/mongo_manager.py @@ -391,6 +391,25 @@ class MongoDbManager: def list_collection_names(self): return self.db.list_collection_names() + def get_unused_yahoo_emails(self) -> list: + """ + 比较 DESTINATION_EMAIL_LIST 中的 Yahoo 邮箱与 CONTACT_LIST_TO_BOOK 中的联系人邮箱, + 返回未被任何联系人使用的 Yahoo 邮箱列表。 + """ + destination_emails: list = self.get_destination_emails() + contacts: list = self.get_all_contacts_to_book() + + contact_mail_set = {contact.mail.lower() for contact in contacts} + + unused_yahoo_emails = [ + mail_address + for mail_address in destination_emails + if "yahoo" in mail_address.mail.lower() + and mail_address.mail.lower() not in contact_mail_set + ] + + return unused_yahoo_emails + MONGO_STORE_MANAGER = MongoDbManager() diff --git a/src/mail/imap_proxy_reader.py b/src/mail/imap_proxy_reader.py index dd567e1..802028e 100644 --- a/src/mail/imap_proxy_reader.py +++ b/src/mail/imap_proxy_reader.py @@ -441,77 +441,66 @@ class ProxyMailReader: ) -> List[MailResult]: results: List[MailResult] = [] since = since or datetime.datetime.today() - # 用于去重:同一主题+发信人只读第一封 - seen_subject_from: set = set() try: - client.select_folder(folder, readonly=True) + client.select_folder(folder) except Exception as exc: logger.warning("[%s] Impossible d'ouvrir '%s' : %s", self.account.login, folder, exc) return results try: - # Utilise les sujets injectés dans client pour filtrer dès la requête IMAP - uids = client.search_by_subjects(since=since) + messages = client.search(['SINCE', since]) except Exception as exc: logger.warning("[%s] Recherche échouée dans '%s' : %s", self.account.login, folder, exc) return results - if not uids: + if not messages: return results - print("uids {}".format(uids)) + print("uids {}".format(messages)) logger.info("[%s] %d message(s) dans '%s'", - self.account.login, len(uids), folder) + self.account.login, len(messages), folder) - for uid, msg_data in client.fetch(uids, "RFC822").items(): + for uid, msg_data in client.fetch(messages, 'RFC822').items(): try: - raw = msg_data.get(b"RFC822") or msg_data.get("RFC822") + raw = msg_data.get(b'RFC822') or msg_data.get('RFC822') if raw is None: continue em = email.message_from_bytes(raw) - subject = em.get("Subject", "") - from_addr = em.get("From", "") - to_addr = em.get("To", self.account.login) - message_id = em.get("Message-ID", "").strip() - print("subject {}".format(subject)) - print("message_id {}".format(message_id)) + from_address = em.get('FROM', '') + subject = em.get('subject', '') + to_addr = em.get('To', self.account.login) + message_id = em.get('Message-ID', '').strip() + body = "" - # 去重:同一主题+发信人只读第一封 - dedup_key = (subject, from_addr) - if dedup_key in seen_subject_from: - logger.debug( - "[%s] Doublon ignoré (même sujet et expéditeur) dans '%s': %s", - self.account.login, folder, subject[:50] + for part in em.walk(): + print(part.get_content_type()) + if part.get_content_type() == "text/html": + payload = part.get_payload(decode=True) + if payload: + body = body + payload.decode("utf-8", errors="ignore") + elif part.get_content_type() == "text/plain": + body = body + str(part.get_payload()) + + logger.info("mail is {} and subject is {}, body is {}".format( + self.account.login, subject, body)) + + # Filtrer selon les sujets configurés + if not self._subjects or any(s in subject for s in self._subjects): + result = MailResult( + account=self.account.login, + subject=subject, + from_address=from_address, + to_address=to_addr, + body=body, + message_id=message_id, ) - continue - seen_subject_from.add(dedup_key) - - # Filtrer : on ne garde que les emails correspondant aux sujets/expéditeurs configurés - is_validation = ( - any(s in subject for s in self._subjects) - ) - if not is_validation: - continue - - body = extract_body(em) - - result = MailResult( - account=self.account.login, - subject=subject, - from_address=from_addr, - to_address=to_addr, - body=body, - message_id=message_id - ) - results.append(result) - except Exception as exc: - logger.warning( - "[%s] Erreur traitement uid=%s : %s", - self.account.login, uid, exc, - ) + results.append(result) + except Exception as error: + print(error) + print("error trying to read email_message for {}".format(self.account.login)) return results