@@ -79,8 +79,8 @@ async def _send_imap_id(imap: aioimaplib.IMAP4 | aioimaplib.IMAP4_SSL) -> None:
7979 logger .warning (f"IMAP ID command failed: { e !s} " )
8080
8181
82- def _create_smtp_ssl_context (verify_ssl : bool ) -> ssl .SSLContext | None :
83- """Create SSL context for SMTP connections.
82+ def _create_ssl_context (verify_ssl : bool ) -> ssl .SSLContext | None :
83+ """Create SSL context for SMTP/IMAP connections.
8484
8585 Returns None for default verification, or permissive context
8686 for self-signed certificates when verify_ssl=False.
@@ -93,20 +93,29 @@ def _create_smtp_ssl_context(verify_ssl: bool) -> ssl.SSLContext | None:
9393 return ctx
9494
9595
96+ # Backwards-compatible alias
97+ _create_smtp_ssl_context = _create_ssl_context
98+
99+
96100class EmailClient :
97101 def __init__ (self , email_server : EmailServer , sender : str | None = None ):
98102 self .email_server = email_server
99103 self .sender = sender or email_server .user_name
100104
101105 self .imap_class = aioimaplib .IMAP4_SSL if self .email_server .use_ssl else aioimaplib .IMAP4
106+ self .imap_ssl_context = _create_ssl_context (self .email_server .verify_ssl )
102107
103108 self .smtp_use_tls = self .email_server .use_ssl
104109 self .smtp_start_tls = self .email_server .start_ssl
105110 self .smtp_verify_ssl = self .email_server .verify_ssl
106111
112+ def _imap_connect (self ) -> aioimaplib .IMAP4_SSL | aioimaplib .IMAP4 :
113+ """Create a new IMAP connection with the configured SSL context."""
114+ return self .imap_class (self .email_server .host , self .email_server .port , ssl_context = self .imap_ssl_context )
115+
107116 def _get_smtp_ssl_context (self ) -> ssl .SSLContext | None :
108117 """Get SSL context for SMTP connections based on verify_ssl setting."""
109- return _create_smtp_ssl_context (self .smtp_verify_ssl )
118+ return _create_ssl_context (self .smtp_verify_ssl )
110119
111120 @staticmethod
112121 def _parse_recipients (email_message ) -> list [str ]:
@@ -403,7 +412,7 @@ async def get_email_count(
403412 flagged : bool | None = None ,
404413 answered : bool | None = None ,
405414 ) -> int :
406- imap = self .imap_class ( self . email_server . host , self . email_server . port )
415+ imap = self ._imap_connect ( )
407416 try :
408417 # Wait for the connection to be established
409418 await imap ._client_task
@@ -449,7 +458,7 @@ async def get_emails_metadata_stream(
449458 flagged : bool | None = None ,
450459 answered : bool | None = None ,
451460 ) -> AsyncGenerator [dict [str , Any ], None ]:
452- imap = self .imap_class ( self . email_server . host , self . email_server . port )
461+ imap = self ._imap_connect ( )
453462 try :
454463 # Wait for the connection to be established
455464 await imap ._client_task
@@ -563,7 +572,7 @@ async def _fetch_email_with_formats(self, imap, email_id: str) -> list | None:
563572 return None
564573
565574 async def get_email_body_by_id (self , email_id : str , mailbox : str = "INBOX" ) -> dict [str , Any ] | None :
566- imap = self .imap_class ( self . email_server . host , self . email_server . port )
575+ imap = self ._imap_connect ( )
567576 try :
568577 # Wait for the connection to be established
569578 await imap ._client_task
@@ -618,7 +627,7 @@ async def download_attachment(
618627 Returns:
619628 A dictionary with download result information.
620629 """
621- imap = self .imap_class ( self . email_server . host , self . email_server . port )
630+ imap = self ._imap_connect ( )
622631 try :
623632 await imap ._client_task
624633 await imap .wait_hello_from_server ()
@@ -854,7 +863,8 @@ async def append_to_sent(
854863 True if successfully saved, False otherwise
855864 """
856865 imap_class = aioimaplib .IMAP4_SSL if incoming_server .use_ssl else aioimaplib .IMAP4
857- imap = imap_class (incoming_server .host , incoming_server .port )
866+ imap_ssl_context = _create_ssl_context (incoming_server .verify_ssl )
867+ imap = imap_class (incoming_server .host , incoming_server .port , ssl_context = imap_ssl_context )
858868
859869 # Common Sent folder names across different providers
860870 sent_folder_candidates = [
@@ -928,7 +938,7 @@ async def append_to_sent(
928938
929939 async def delete_emails (self , email_ids : list [str ], mailbox : str = "INBOX" ) -> tuple [list [str ], list [str ]]:
930940 """Delete emails by their UIDs. Returns (deleted_ids, failed_ids)."""
931- imap = self .imap_class ( self . email_server . host , self . email_server . port )
941+ imap = self ._imap_connect ( )
932942 deleted_ids = []
933943 failed_ids = []
934944
0 commit comments