defl/defl/smtpy_.py
2024-09-11 11:14:03 -04:00

79 lines
2.3 KiB
Python

#!/usr/bin/env python
import os
from dataclasses import dataclass, field
import smtplib
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import COMMASPACE, formatdate
import os
import atexit
import itertools
import select
import toml
from dataclasses import dataclass, field
import defl
from defl import log, cl, Path, Null, Undefined
from defl._typing_ import *
@dataclass(slots=True, kw_only=True, frozen=False)
class SMTPer:
host: str
port: str
user: str
password: str = field(repr=False)
lazy: bool = False
_server: smtplib.SMTP | None = field(repr=False, default=None)
def __post_init__(_):
if not _.lazy:
_.login()
def login(_):
log.info('SMTP login', _.host, _.port)
_._server = smtplib.SMTP(_.host, _.port)
_._server.ehlo()
_._server.starttls()
_._server.login(_.user, _.password)
def send(_,
toEmail: list | str,
subject: str,
text: str,
files: list = None,
):
if _._server is None:
_.login()
toEmail = toEmail if isinstance(toEmail, list) else [toEmail]
files = files if files is not None else []
msg = MIMEMultipart()
msg['From'] = _.user
msg['To'] = COMMASPACE.join(toEmail)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach(MIMEText(text))
files = [files] if isinstance(files, str) else files
for f in files:
with open(f, "rb") as fp:
basename = os.path.basename(f)
part = MIMEApplication(fp.read(), Name=basename)
part['Content-Disposition'] = f'attachment; filename="{basename}"'
msg.attach(part)
log.info("SMTP", f'sending from "{cl.cyn}{_.user}{cl.r}" to {cl.yel}{toEmail}{cl.r} with subject "{cl.red}{subject}{cl.r}" and {cl.org}{len(files)}{cl.r} file(s)')
_._server.sendmail(_.user, toEmail, msg.as_string())
def close(_):
if _._server:
_._server.close()
def __del__(_):
_.close()
@staticmethod
def parseArgs(parser):
parser.add_argument('--smtpHost', type=str, required=True)
parser.add_argument('--smtpPort', type=str, required=True)