2# +==== BEGIN CatFeeder =================+
5# ...............)..(.')
7# ...............\(__)|
8# Inspired by Joan Stark
9# source https://www.asciiart.eu/
13# FILE: mail_management.py
14# CREATION DATE: 11-10-2025
15# LAST Modified: 14:47:48 19-12-2025
17# This is the backend server in charge of making the actual website work.
19# COPYRIGHT: (c) Cat Feeder
20# PURPOSE: The file in charge of managing the emissions of e-mails.
22# +==== END CatFeeder =================+
28from typing
import List
29from email
import encoders
30from email.message
import EmailMessage
31from email.utils
import make_msgid
32from email.mime.base
import MIMEBase
33from display_tty
import Disp, initialise_logger
34from .
import mail_constants
as CONST
35from ..core
import FinalClass
42 disp: Disp = initialise_logger(__qualname__,
False)
44 def __init__(self, error: int = 84, success: int = 0, debug: bool =
False) ->
None:
46 The class in charge of allowing the user to send e-mails.
49 error (int, optional): _description_. Defaults to 84.
50 success (int, optional): _description_. Defaults to 0.
51 debug (bool, optional): _description_. Defaults to False.
54 self.
disp.update_disp_debug(debug)
55 self.
disp.log_debug(
"Initialising...")
63 self.
host = CONST.SENDER_HOST
65 self.
port = CONST.SENDER_PORT
67 self.
disp.log_debug(
"Initialised")
69 def _send(self, em: EmailMessage) -> int:
71 Internal method to handle the actual sending of an email.
74 em (EmailMessage): The email message to be sent.
77 int: The status of the email sending operation.
79 context = ssl.create_default_context()
82 with smtplib.SMTP_SSL(self.
host, self.
port, context=context)
as smtp:
85 self.
disp.log_debug(
"Email sent successfully")
87 except (smtplib.SMTPException, OSError, ssl.SSLError)
as e:
89 self.
disp.log_critical(f
"An error occurred sending email: {e}")
92 def send_email(self, receiver: str, subject: str, body: str, body_type: str =
"html") -> int:
94 Sends a simple email to a single receiver.
97 receiver (str): The recipient's email address.
98 subject (str): The subject of the email.
99 body (str): The content of the email.
100 body_type (str, optional): The MIME type of the email content ('html' or 'plain'). Defaults to 'html'.
103 int: The status of the email sending operation.
108 em[
'Subject'] = subject
110 if body_type.lower() ==
"html":
111 em.add_alternative(body, subtype=
'html')
115 return self.
_send(em)
119 Sends an email with one or more attachments.
122 receiver (str): The recipient's email address.
123 subject (str): The subject of the email.
124 body (str): The content of the email.
125 attachments (List[str]): List of file paths for attachments.
126 body_type (str, optional): The MIME type of the email content ('html' or 'plain'). Defaults to 'html'.
129 int: The status of the email sending operation.
134 em[
'Subject'] = subject
136 if body_type ==
"html":
137 em.add_alternative(body, subtype=
'html')
141 for file
in attachments:
143 with open(file,
'rb')
as f:
145 file_name = file.split(
'/')[-1]
147 part = MIMEBase(
'application',
'octet-stream')
148 part.set_payload(file_data)
149 encoders.encode_base64(part)
151 'Content-Disposition',
152 f
'attachment; filename={file_name}'
155 part.get_payload(decode=
True),
156 maintype=
'application',
157 subtype=
'octet-stream',
163 self.
disp.log_critical(
164 f
"Error reading attachment {file}: {e}",
165 "send_email_with_attachment"
169 return self.
_send(em)
173 Sends an email to multiple recipients (To, Cc, or Bcc).
176 receivers (List[str]): A list of recipients' email addresses.
177 subject (str): The subject of the email.
178 body (str): The content of the email.
179 body_type (str, optional): The MIME type of the email content ('html' or 'plain'). Defaults to 'html'.
182 int: The status of the email sending operation.
186 em[
'To'] =
', '.join(receivers)
187 em[
'Subject'] = subject
189 if body_type ==
"html":
190 em.add_alternative(body, subtype=
'html')
194 return self.
_send(em)
198 Sends an email with an inline image embedded in the body.
201 receiver (str): The recipient's email address.
202 subject (str): The subject of the email.
203 body (str): The content of the email, including a placeholder for the image.
204 image_path (str): The path to the image to be embedded.
205 body_type (str, optional): The MIME type of the email content ('html' or 'plain'). Defaults to 'html'.
208 int: The status of the email sending operation.
213 em[
'Subject'] = subject
215 if body_type ==
"html":
216 em.add_alternative(body, subtype=
'html')
221 with open(image_path,
'rb')
as img:
222 img_data = img.read()
223 img_cid = make_msgid()[1:-1]
232 em.set_content(body.format(img_cid=img_cid))
233 except (OSError, KeyError, ValueError)
as e:
234 self.
disp.log_critical(
235 f
"Error embedding inline image: {e}",
236 "send_email_with_inline_image"
240 return self.
_send(em)
None __init__(self, int error=84, int success=0, bool debug=False)
int send_email(self, str receiver, str subject, str body, str body_type="html")
int _send(self, EmailMessage em)
int send_email_with_attachment(self, str receiver, str subject, str body, List[str] attachments, str body_type="html")
int send_email_with_inline_image(self, str receiver, str subject, str body, str image_path, str body_type="html")
int send_email_to_multiple(self, List[str] receivers, str subject, str body, str body_type="html")