diff --git a/mail/imap_proxy_reader.py b/mail/imap_proxy_reader.py new file mode 100644 index 0000000..c1a94da --- /dev/null +++ b/mail/imap_proxy_reader.py @@ -0,0 +1,534 @@ +""" +imap_proxy_reader.py +==================== +Lire des emails via IMAPClient en passant par un proxy SOCKS5/SOCKS4/HTTP. + +Fonctionnement : + - ProxyIMAP4_TLS : sous-classe de imaplib.IMAP4 qui ouvre la socket + à travers un proxy SOCKS via PySocks. + - ProxyIMAPClient : sous-classe de IMAPClient qui injecte ProxyIMAP4_TLS + au lieu de la connexion directe habituelle. + +Dépendances : + pip install imapclient PySocks +""" + +import datetime +import email +import imaplib +import io +import logging +import os +import re +import ssl +import socket +from dataclasses import dataclass, field +from email.message import Message +from typing import List, Optional, Tuple + +import socks +from dotenv import load_dotenv +from imapclient import IMAPClient + +load_dotenv() + +# ────────────────────────────────────────────────────────────── +# Constantes +# ────────────────────────────────────────────────────────────── + +VALIDATION_URL_SUBJECT_FR = "Validation de votre demande de rendez-vous" +VALIDATION_URL_SUBJECT_EN = "Please confirm your appointment request" +VALIDATION_URL_REGEX = ( + r"https:\/\/rendezvousparis\.hermes\.com" + r"\/client\/register\/[A-Z0-9]+\/validate\.code=[A-Z0-9]+" +) + +DATE_FORMAT = "%d-%b-%Y" + +# Correspondance domaine → serveur IMAP (identique à mail_constants.py) +IMAP_SERVER_MAP: List[Tuple[str, str]] = [ + ("163.com", "imap.163.com"), + ("yahoo.com", "imap.mail.yahoo.com"), + ("firemail.de", "imap.firemail.de"), + ("gmail.com", "imap.gmail.com"), + ("sina.com", "imap.sina.com"), + ("hotmail.com", "outlook.office365.com"), + ("outlook.com", "outlook.office365.com"), + ("rambler.ru", "imap.rambler.ru"), + ("btvm.ne.jp", "imap.btvm.ne.jp"), + ("mars.dti.ne.jp", "imap.cm.dream.jp"), + ("aurora.dti.ne.jp", "imap.cm.dream.jp"), + ("naver.com", "imap.naver.com"), + ("onet.pl", "imap.poczta.onet.pl"), + ("gazeta.pl", "imap.gazeta.pl"), + ("tim.it", "imap.tim.it"), + ("alice.it", "in.alice.it"), + ("gmx.com", "imap.gmx.com"), + ("gmx.fr", "imap.gmx.com"), + ("gmx.us", "imap.gmx.com"), + ("gmx.ch", "imap.gmx.com"), + ("gmx.pt", "imap.gmx.com"), + ("gmx.sg", "imap.gmx.com"), + ("gmx.net", "imap.gmx.net"), + ("gmx.de", "imap.gmx.net"), + ("gmx.at", "imap.gmx.at"), + ("web.de", "imap.web.de"), + ("inbox.lv", "mail.inbox.lv"), + ("pissmail.com", "mail.pissmail.com"), + ("incel.email", "mail.pissmail.com"), + ("shitposting.expert","mail.pissmail.com"), + ("hatesje.ws", "mail.pissmail.com"), + ("child.pizza", "mail.pissmail.com"), + ("genocide.fun", "mail.pissmail.com"), + ("dmc.chat", "mail.pissmail.com"), + ("aol.com", "imap.aol.com"), # fallback AOL +] + +PROXY_TYPE_MAP = { + "SOCKS5": socks.SOCKS5, + "SOCKS4": socks.SOCKS4, + "HTTP": socks.HTTP, +} + +logger = logging.getLogger(__name__) + + +# ────────────────────────────────────────────────────────────── +# Modèles de données +# ────────────────────────────────────────────────────────────── + +@dataclass +class ProxyConfig: + """Configuration du proxy.""" + host: str + port: int + proxy_type: str = "SOCKS5" # "SOCKS5" | "SOCKS4" | "HTTP" + username: Optional[str] = None + password: Optional[str] = None + + @property + def socks_type(self) -> int: + t = self.proxy_type.upper() + if t not in PROXY_TYPE_MAP: + raise ValueError(f"proxy_type invalide : {self.proxy_type!r}. " + f"Valeurs autorisées : {list(PROXY_TYPE_MAP)}") + return PROXY_TYPE_MAP[t] + + def __repr__(self) -> str: + auth = f"{self.username}:***@" if self.username else "" + return f"{self.proxy_type}://{auth}{self.host}:{self.port}" + + +@dataclass +class MailAccount: + """Compte email à lire.""" + login: str + password: str + + +@dataclass +class MailResult: + """Résultat d'une lecture d'email.""" + account: str + subject: str + from_address: str + to_address: str + body: str + validation_urls: List[str] = field(default_factory=list) + + +# ────────────────────────────────────────────────────────────── +# Connexion IMAP via proxy (bas niveau) +# ────────────────────────────────────────────────────────────── + +class ProxyIMAP4_TLS(imaplib.IMAP4): + """ + Variante TLS de imaplib.IMAP4 qui route la connexion + à travers un proxy SOCKS5/SOCKS4/HTTP grâce à PySocks. + """ + + def __init__( + self, + host: str, + port: int, + ssl_context: Optional[ssl.SSLContext], + proxy: ProxyConfig, + timeout: Optional[float] = None, + ): + self._ssl_context = ssl_context + self._proxy = proxy + self._timeout = timeout + # imaplib.IMAP4.__init__ appelle self.open() + imaplib.IMAP4.__init__(self, host, port) + self.file: io.BufferedReader + + def open(self, host: str = "", port: int = 993, timeout: Optional[float] = None) -> None: + self.host = host + self.port = port + effective_timeout = timeout if timeout is not None else self._timeout + + # ── Créer la socket SOCKS ──────────────────────────── + sock = socks.socksocket(socket.AF_INET, socket.SOCK_STREAM) + sock.set_proxy( + proxy_type=self._proxy.socks_type, + addr=self._proxy.host, + port=self._proxy.port, + username=self._proxy.username, + password=self._proxy.password, + ) + if effective_timeout: + sock.settimeout(effective_timeout) + sock.connect((host, port)) + + # ── Envelopper avec SSL/TLS ────────────────────────── + ctx = self._ssl_context or ssl.create_default_context() + self.sock = ctx.wrap_socket(sock, server_hostname=host) + self.file = self.sock.makefile("rb") + + # ── Méthodes requises par imaplib.IMAP4 ───────────────── + def read(self, size: int) -> bytes: + return self.file.read(size) # type: ignore[return-value] + + def readline(self) -> bytes: + return self.file.readline() # type: ignore[return-value] + + def send(self, data) -> None: + self.sock.sendall(data) + + def shutdown(self) -> None: + imaplib.IMAP4.shutdown(self) + + +# ────────────────────────────────────────────────────────────── +# IMAPClient avec proxy +# ────────────────────────────────────────────────────────────── + +class ProxyIMAPClient(IMAPClient): + """ + Sous-classe d'IMAPClient qui utilise un proxy SOCKS/HTTP. + + Usage : + proxy = ProxyConfig(host="127.0.0.1", port=1080, proxy_type="SOCKS5") + client = ProxyIMAPClient("imap.gmail.com", proxy=proxy, use_uid=True) + client.login("user@gmail.com", "password") + """ + + def __init__(self, host: str, proxy: ProxyConfig, **kwargs): + self._proxy = proxy + super().__init__(host, **kwargs) + + def _create_IMAP4(self): + """Remplace la méthode d'IMAPClient pour injecter ProxyIMAP4_TLS.""" + if self.ssl: + return ProxyIMAP4_TLS( + host=self.host, + port=self.port, + ssl_context=self.ssl_context, + proxy=self._proxy, + timeout=getattr(self._timeout, "connect", None), + ) + # Connexion non-SSL à travers le proxy (rare, mais supporté) + # On monkey-patch juste la connexion TCP + raise NotImplementedError( + "Connexion IMAP non-SSL via proxy non implémentée. " + "Utilisez ssl=True (port 993)." + ) + + +# ────────────────────────────────────────────────────────────── +# Fonctions utilitaires +# ────────────────────────────────────────────────────────────── + +def get_imap_server(login: str) -> str: + """Retourne le serveur IMAP correspondant au domaine du login.""" + login_lower = login.lower() + for domain, server in IMAP_SERVER_MAP: + if domain in login_lower: + return server + return "imap.aol.com" # fallback + + +def extract_body(email_message: Message) -> str: + """Extrait le corps HTML ou texte d'un email.""" + body = "" + for part in email_message.walk(): + content_type = part.get_content_type() + try: + if content_type == "text/html": + payload = part.get_payload(decode=True) + if payload: + body += payload.decode("utf-8", errors="ignore") + elif content_type == "text/plain": + payload = part.get_payload() + if payload: + body += str(payload) + except Exception as exc: + logger.warning("Erreur extraction body : %s", exc) + return body + + +def find_validation_urls(text: str) -> List[str]: + """Recherche toutes les URLs de validation Hermes dans un texte.""" + return re.findall(VALIDATION_URL_REGEX, text) + + +# ────────────────────────────────────────────────────────────── +# Lecteur principal +# ────────────────────────────────────────────────────────────── + +class ProxyMailReader: + """ + Lit les emails d'un compte via IMAPClient en passant par un proxy. + + Paramètres + ---------- + account : MailAccount + Identifiants du compte email. + proxy : ProxyConfig + Configuration du proxy. + timeout : float, optional + Timeout de connexion en secondes (défaut : 30 s). + """ + + def __init__( + self, + account: MailAccount, + proxy: ProxyConfig, + timeout: float = 30.0, + ): + self.account = account + self.proxy = proxy + self.timeout = timeout + + # ── Connexion ──────────────────────────────────────────── + + def _connect(self) -> ProxyIMAPClient: + imap_server = get_imap_server(self.account.login) + logger.info( + "[%s] Connexion via %s → %s:993", + self.account.login, self.proxy, imap_server, + ) + client = ProxyIMAPClient( + host=imap_server, + proxy=self.proxy, + use_uid=True, + ssl=True, + timeout=self.timeout, + ) + client.login(self.account.login, self.account.password) + logger.info("[%s] Connecté.", self.account.login) + return client + + # ── Lecture des dossiers ───────────────────────────────── + + def _list_folders(self, client: ProxyIMAPClient) -> List[str]: + return [info[-1] for info in client.list_folders()] + + # ── Lecture des messages ───────────────────────────────── + + def _read_folder( + self, + client: ProxyIMAPClient, + folder: str, + since: Optional[datetime.datetime] = None, + ) -> List[MailResult]: + results: List[MailResult] = [] + since = since or datetime.datetime.today() + + try: + client.select_folder(folder, readonly=True) + except Exception as exc: + logger.warning("[%s] Impossible d'ouvrir '%s' : %s", + self.account.login, folder, exc) + return results + + try: + uids = 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: + return results + + logger.info("[%s] %d message(s) dans '%s'", + self.account.login, len(uids), folder) + + for uid, msg_data in client.fetch(uids, "RFC822").items(): + try: + 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) + + # Filtrer : on ne garde que les emails de validation Hermes + is_validation = ( + VALIDATION_URL_SUBJECT_FR in subject + or VALIDATION_URL_SUBJECT_EN in subject + or "no-reply@hermes.com" in from_addr.lower() + ) + if not is_validation: + continue + + body = extract_body(em) + urls = find_validation_urls(body) + + result = MailResult( + account=self.account.login, + subject=subject, + from_address=from_addr, + to_address=to_addr, + body=body, + validation_urls=urls, + ) + results.append(result) + logger.info( + "[%s] Email de validation trouvé (uid=%s) — URLs : %s", + self.account.login, uid, urls or "aucune", + ) + except Exception as exc: + logger.warning( + "[%s] Erreur traitement uid=%s : %s", + self.account.login, uid, exc, + ) + + return results + + # ── Point d'entrée public ──────────────────────────────── + + def read( + self, + since: Optional[datetime.datetime] = None, + skip_folders: Optional[List[str]] = None, + ) -> List[MailResult]: + """ + Se connecte au serveur IMAP via le proxy et retourne la liste + des emails de validation trouvés depuis `since` (aujourd'hui par défaut). + + Paramètres + ---------- + since : datetime, optional — date de début de recherche + skip_folders : list[str], optional — dossiers à ignorer + (défaut : ["Sent", "Drafts", "Trash", "Junk", "Spam"]) + """ + if skip_folders is None: + skip_folders = ["Sent", "Drafts", "Trash", "Junk", "Spam"] + + all_results: List[MailResult] = [] + client = self._connect() + + try: + folders = self._list_folders(client) + logger.info("[%s] Dossiers : %s", self.account.login, folders) + + for folder in folders: + if folder in skip_folders: + logger.debug("[%s] Dossier ignoré : %s", + self.account.login, folder) + continue + all_results.extend(self._read_folder(client, folder, since)) + finally: + try: + client.logout() + except Exception: + pass + + return all_results + + +# ────────────────────────────────────────────────────────────── +# Lecture parallèle de plusieurs comptes +# ────────────────────────────────────────────────────────────── + +from concurrent.futures import ThreadPoolExecutor, as_completed + + +def read_multiple_accounts( + accounts: List[MailAccount], + proxy: ProxyConfig, + since: Optional[datetime.datetime] = None, + max_workers: int = 10, + timeout: float = 30.0, +) -> List[MailResult]: + """ + Lit plusieurs comptes email en parallèle via le même proxy. + + Retourne la liste consolidée de tous les MailResult trouvés. + """ + all_results: List[MailResult] = [] + + with ThreadPoolExecutor(max_workers=max_workers) as executor: + future_map = { + executor.submit( + ProxyMailReader(acc, proxy, timeout).read, since + ): acc.login + for acc in accounts + } + for future in as_completed(future_map): + login = future_map[future] + try: + results = future.result() + logger.info("[%s] %d email(s) de validation récupéré(s).", + login, len(results)) + all_results.extend(results) + except Exception as exc: + logger.error("[%s] Erreur : %s", login, exc) + + return all_results + + +# ────────────────────────────────────────────────────────────── +# Point d'entrée — exemple d'utilisation +# ────────────────────────────────────────────────────────────── + +if __name__ == "__main__": + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s %(levelname)-8s %(message)s", + datefmt="%H:%M:%S", + ) + + # ── 1. Configurer le proxy ─────────────────────────────── + proxy = ProxyConfig( + host=os.environ.get("GMX_PROXY_HOST", ""), + port=int(os.environ.get("GMX_PROXY_PORT", "443")), + proxy_type=os.environ.get("GMX_PROXY_TYPE", "SOCKS5"), + username=os.environ.get("GMX_PROXY_USERNAME"), + password=os.environ.get("GMX_PROXY_PASSWORD"), + ) + + # ── 2. Définir les comptes à lire ──────────────────────── + accounts = [ + MailAccount(login="birgitnaya@gmx.net", password="XEeUF3Y1yaO"), + # MailAccount(login="user@gmail.com", password="apppassword"), + # MailAccount(login="user@outlook.com", password="password"), + ] + + # ── 3. Lancer la lecture ───────────────────────────────── + results = read_multiple_accounts( + accounts=accounts, + proxy=proxy, + since=datetime.datetime.today(), + max_workers=5, + timeout=30.0, + ) + + # ── 4. Afficher les résultats ──────────────────────────── + print(f"\n{'='*60}") + print(f" {len(results)} email(s) de validation trouvé(s)") + print(f"{'='*60}\n") + + for r in results: + print(f" Compte : {r.account}") + print(f" De : {r.from_address}") + print(f" Sujet : {r.subject}") + print(f" URLs : {r.validation_urls or 'aucune'}") + print(f" {'-'*56}") + + + diff --git a/mail/mail_reader_all_contacts.py b/mail/mail_reader_all_contacts.py index 291c0a7..960e179 100644 --- a/mail/mail_reader_all_contacts.py +++ b/mail/mail_reader_all_contacts.py @@ -1,19 +1,25 @@ import datetime import email import logging +import os import re from concurrent.futures import ThreadPoolExecutor from email.header import decode_header from email.message import Message -from typing import Union, List +from typing import Union, List, Optional +from dotenv import load_dotenv from imapclient import IMAPClient from db.mongo_manager import MONGO_STORE_MANAGER from excel_reader import read_contacts from mail.mail_constants import DOMAIN_HOTMAIL, create_imap +from mail.imap_proxy_reader import ProxyIMAPClient, ProxyConfig, get_imap_server from models.ReserveResultPojo import ReserveResultPojo from models.mail_pojo import MailPojo, MailAddress +# Charger les variables d'environnement depuis .env +load_dotenv() + # 定义常量 VALIDATION_URL_SUBJECT_FR = 'Validation de votre demande de rendez-vous' VALIDATION_URL_SUBJECT_EN = 'Please confirm your appointment request' @@ -25,6 +31,17 @@ EMAIL_ADDRESS_REGEX = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b' # 日期格式 DATE_FORMAT = "%d-%b-%Y" +# GMX域名列表(用于判断是否需要使用代理) +GMX_DOMAINS = ( + "gmx.com", "gmx.net", "gmx.de", "gmx.at", + "gmx.fr", "gmx.us", "gmx.sg", "gmx.ch", "gmx.pt", +) + + +def is_gmx_account(login: str) -> bool: + """判断邮箱是否属于GMX域名""" + return any(d in login.lower() for d in GMX_DOMAINS) + # 邮箱列表(简化为常量) REDIRECTION_MAILS = "appointment2022@aol.com, chenpeijun@aol.com,hongjiang176@aol.com,ciyuexie@aol.com,rutger.62@aol.com,ciccidaniel@aol.com,armasgoodman@aol.com,wknd.gemerine@aol.com,rafmail1981@aol.com,tonovichivanenaki@aol.com,hetland.ari@aol.com,mateusiversen@aol.com,lacerdaraffaello@aol.com,anasida76@aol.com,liamolinari@aol.com,sen70zib@aol.com,mezeiderrick@aol.com,stanisl49avchic@aol.com,damcvrobaneuron@aol.com,suyzanna_fleona@aol.com,dxealing.dissa@aol.com,hogg.karen@aol.com,obocharovamarina@aol.com,buchholzjohann@aol.com,orn.cecchini@aol.com,percivaltorgersen@aol.com,candalgudrun@aol.com,filimonis.76@aol.com,bengann_100@aol.com,axelhanne@aol.com,tiffanylarochelle@aol.com,nicoleta.r@aol.com,eichenbaum.1963@aol.com,kotensasharev@aol.com,samognat32@aol.com,edem_headshot@aol.com,kozmakuzmich1960@aol.com,damonsvensson@aol.com,anders.riva@aol.com,caiminwei123@gmail.com,yulingguo086@gmail.com,yingxiaolu086@gmail.com,lijiazhen0035@gmail.com,fangp370@gmail.com,huangyayu10086@gmail.com,fuziyuan110@gmail.com,xinyingdu886@gmail.com,yasiaforever.1971@aol.com,lukaszfidalgo@aol.com,zaichi29@aol.com,prostotakitak.1974@aol.com,mo90nroe@aol.com,blonde.87@aol.com,dimidrol.1969@aol.com" @@ -64,9 +81,10 @@ def find_from_mail(param) -> str: class MailReader: """邮件读取器类""" - def __init__(self, login: str, password: str): + def __init__(self, login: str, password: str, proxy: Optional[ProxyConfig] = None): self.login = login self.password = password + self.proxy = proxy @staticmethod def show_folders(imap) -> List[str]: @@ -90,7 +108,43 @@ class MailReader: def read_emails(self, mails_messages: List[MailPojo]) -> List[MailPojo]: """读取邮件""" - imap = create_imap(self.login) + # ── GMX账户 → 使用代理连接(失败自动重试最多3次)── + if is_gmx_account(self.login) and self.proxy is not None: + return self._read_emails_with_proxy_retry(mails_messages) + else: + return self._read_emails_internal(create_imap(self.login), mails_messages) + + def _read_emails_with_proxy_retry( + self, + mails_messages: List[MailPojo], + max_retries: int = 3, + ) -> List[MailPojo]: + """通过 ProxyIMAPClient 读取 GMX 邮件,失败时最多重试 max_retries 次。""" + imap_server = get_imap_server(self.login) + last_error: Optional[Exception] = None + + for attempt in range(1, max_retries + 1): + try: + print("[GMX-Proxy] {} → {} via {} (tentative {}/{})".format( + self.login, imap_server, self.proxy, attempt, max_retries)) + imap = ProxyIMAPClient( + host=imap_server, + proxy=self.proxy, + use_uid=True, + ssl=True, + ) + return self._read_emails_internal(imap, mails_messages) + except Exception as exc: + last_error = exc + print("[GMX-Proxy] Échec tentative {}/{} pour {} : {}".format( + attempt, max_retries, self.login, exc)) + + print("[GMX-Proxy] Toutes les tentatives ont échoué pour {} : {}".format( + self.login, last_error)) + return [] + + def _read_emails_internal(self, imap, mails_messages: List[MailPojo]) -> List[MailPojo]: + """Logique commune de lecture des emails (IMAPClient ou imaplib).""" is_imap_client = isinstance(imap, IMAPClient) # 登录邮箱 @@ -351,7 +405,11 @@ def need_to_check_email(mail: str, successful_items) -> bool: return len(validated_items) == 0 -def find_links_to_validate_from_mail_list(mail_list: List[MailAddress], logger) -> None: +def find_links_to_validate_from_mail_list( + mail_list: List[MailAddress], + logger, + proxy: Optional[ProxyConfig] = None, +) -> None: """从邮件列表中查找需要验证的链接""" if not mail_list: return @@ -369,7 +427,7 @@ def find_links_to_validate_from_mail_list(mail_list: List[MailAddress], logger) for mail in mail_list: # 检查是否需要读取邮件 if need_to_check_email(mail.mail, successful_items): - mail_reader = MailReader(mail.mail, mail.password) + mail_reader = MailReader(mail.mail, mail.password, proxy=proxy) future = executor.submit(mail_reader.read_emails, mails_messages) futures.append(future) @@ -411,8 +469,8 @@ def find_links_to_validate_from_mail_list(mail_list: List[MailAddress], logger) if __name__ == '__main__': # 读取联系人列表 contact_to_book_list = read_contacts( - file_name="~/Desktop/contact_list_2025-11-28.xlsx") - # file_name="~/Desktop/contact_list_all.xlsx") + file_name="~/Desktop/contact_list_2026-03-05.xlsx") + # file_name="~/Desktop/contact_list_2025-11-28.xlsx") # file_name="~/Desktop/contact_list_2025-11-06.xlsx") # 获取目标邮箱列表 @@ -427,7 +485,6 @@ if __name__ == '__main__': # 设置日志记录器 logger = logging.getLogger() - # 获取已验证的链接列表 _all_links = MONGO_STORE_MANAGER.get_links_to_validate() @@ -440,6 +497,14 @@ if __name__ == '__main__': _to_add = False if _to_add: filter_mail.append(mail_pojo) - # filter_mail = [MailAddress("utatapi@gmx.net", "RSAzHAFek8s")] + # filter_mail = [MailAddress("birgitnaya@gmx.net", "XEeUF3Y1yaO")] + # 配置代理(GMX账号必须通过代理读取) + gmx_proxy = ProxyConfig( + host=os.environ.get("GMX_PROXY_HOST", ""), + port=int(os.environ.get("GMX_PROXY_PORT", "443")), + proxy_type=os.environ.get("GMX_PROXY_TYPE", "SOCKS5"), + username=os.environ.get("GMX_PROXY_USERNAME"), + password=os.environ.get("GMX_PROXY_PASSWORD"), + ) # 处理邮件 - find_links_to_validate_from_mail_list(filter_mail, logger) + find_links_to_validate_from_mail_list(filter_mail, logger, proxy=gmx_proxy) diff --git a/migrate_cached_request_data.py b/migrate_cached_request_data.py index 5882901..2784cc6 100644 --- a/migrate_cached_request_data.py +++ b/migrate_cached_request_data.py @@ -1,12 +1,13 @@ from multiprocessing import Process -from queue_message.CookiesPublisher import MORNING_DATA_CACHE_2, MORNING_DATA_CACHE, MORNING_DATA_CACHE_BAK +from queue_message.CookiesPublisher import MORNING_DATA_CACHE_2, MORNING_DATA_CACHE, MORNING_DATA_CACHE_BAK, \ + REGISTER_QUEUE from workers.MessagerTransporter import migrate_message_to_queue if __name__ == '__main__': - p1 = Process(target=migrate_message_to_queue, args=(MORNING_DATA_CACHE_2, MORNING_DATA_CACHE_BAK)) - p1.start() - p2 = Process(target=migrate_message_to_queue, args=(MORNING_DATA_CACHE, MORNING_DATA_CACHE_BAK)) + # p1 = Process(target=migrate_message_to_queue, args=(MORNING_DATA_CACHE_2, MORNING_DATA_CACHE_BAK)) + # p1.start() + p2 = Process(target=migrate_message_to_queue, args=(MORNING_DATA_CACHE_BAK, REGISTER_QUEUE)) p2.start() p2.join() # migrate_message_to_queue(from_queue=MORNING_DATA_CACHE_2) diff --git a/request_sender_test.py b/request_sender_test.py index 42a7690..180738d 100644 --- a/request_sender_test.py +++ b/request_sender_test.py @@ -103,5 +103,5 @@ if __name__ == '__main__': file_list = ['~/Desktop/contact_list_2025-11-28.xlsx'] # file_list = ['~/Desktop/contact_list_2025-11-06.xlsx'] # file_list = ['~/Desktop/contact_list_all.xlsx'] - send_request_for_file_list(file_list=file_list, thread_number=20, - data_queue_name=MORNING_DATA_CACHE_2, stop_at_hour=19, stop_at_mins=50) + send_request_for_file_list(file_list=file_list, thread_number=40, + data_queue_name=MORNING_DATA_CACHE, stop_at_hour=19, stop_at_mins=50) diff --git a/requirements.txt b/requirements.txt index 429d896..917c543 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ APScheduler==3.10.4 curl_cffi==0.7.1 openpyxl pika -schedule \ No newline at end of file +schedule +python-dotenv