Improve encapsulation in IMAP classes

Make all attributes private (_host, _imap, etc.) and remove redundant
public connect/disconnect methods. Connection management is now handled
internally by the orchestrator calling private _connect/_disconnect.

Changes:
- Privatize ImapClient attributes and methods
- Update EmailForwarder to call private connection methods
- Enhance encapsulation without changing functionality
This commit is contained in:
Jeena 2026-01-04 16:48:57 +09:00
parent f70f1853f0
commit f2bc700939

40
main.py
View file

@ -15,34 +15,26 @@ class ImapClient:
"""Base class for IMAP operations."""
def __init__(self, host: str, port: int, user: str, password: str):
self.host = host
self.port = port
self.user = user
self.password = password
self.imap = None
def connect(self):
"""Establish IMAP connection."""
self._connect()
def disconnect(self):
"""Close IMAP connection."""
self._disconnect()
self._host = host
self._port = port
self._user = user
self._password = password
self._imap = None
def _connect(self):
"""Private: Connect and login to IMAP."""
self.imap = imaplib.IMAP4_SSL(self.host, self.port)
self.imap.login(self.user, self.password)
self._imap = imaplib.IMAP4_SSL(self._host, self._port)
self._imap.login(self._user, self._password)
def _disconnect(self):
"""Private: Logout and close connection."""
if self.imap:
self.imap.logout()
self.imap = None
if self._imap:
self._imap.logout()
self._imap = None
def _list_folders(self):
"""Private: List all folders."""
typ, data = self.imap.list()
typ, data = self._imap.list()
if typ != "OK":
raise Exception("Failed to list folders")
folders = []
@ -56,20 +48,20 @@ class ImapClient:
def _select_folder(self, folder: str):
"""Private: Select a folder."""
typ, _ = self.imap.select(folder)
typ, _ = self._imap.select(folder)
if typ != "OK":
raise Exception(f"Failed to select folder {folder}")
def _search(self, criteria: str):
"""Private: Search emails."""
typ, data = self.imap.search(None, criteria)
typ, data = self._imap.search(None, criteria)
if typ != "OK":
raise Exception(f"Search failed: {criteria}")
return data[0].split()
def _fetch(self, uid: str):
"""Private: Fetch raw email."""
typ, data = self.imap.fetch(uid, "(RFC822)")
typ, data = self._imap.fetch(uid, "(RFC822)")
if typ != "OK":
raise Exception(f"Failed to fetch UID {uid}")
return data[0][1]
@ -120,13 +112,13 @@ class DestImap(ImapClient):
def _create_folder(self, folder: str):
"""Private: Create a folder."""
typ, _ = self.imap.create(folder)
typ, _ = self._imap.create(folder)
if typ != "OK":
raise Exception(f"Failed to create folder {folder}")
def _append(self, folder: str, msg: bytes):
"""Private: Append message to folder."""
self.imap.append(folder, "", None, msg)
self._imap.append(folder, "", None, msg)
class EmailForwarder: