use proxy while reading gmx mails
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user