mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2026-01-11 13:06:19 +00:00
refac: Email.py module with bugfix (#1058)
* refac: refactor Email.py module for clarity * chore: rework ready method for dynamic config * chore: implement resolvconf from v4.3.2-dev
This commit is contained in:
@@ -1463,7 +1463,7 @@ def API_Locale_Update():
|
||||
|
||||
@app.get(f'{APP_PREFIX}/api/email/ready')
|
||||
def API_Email_Ready():
|
||||
return ResponseObject(EmailSender.ready())
|
||||
return ResponseObject(EmailSender.is_ready())
|
||||
|
||||
@app.post(f'{APP_PREFIX}/api/email/send')
|
||||
def API_Email_Send():
|
||||
|
||||
@@ -1,76 +1,93 @@
|
||||
import os.path
|
||||
import smtplib
|
||||
|
||||
# Email libaries
|
||||
from email import encoders
|
||||
from email.header import Header
|
||||
from email.mime.base import MIMEBase
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.utils import formataddr
|
||||
from email.utils import formatdate
|
||||
|
||||
class EmailSender:
|
||||
def __init__(self, DashboardConfig):
|
||||
self.smtp = None
|
||||
self.DashboardConfig = DashboardConfig
|
||||
|
||||
if not os.path.exists('./attachments'):
|
||||
os.mkdir('./attachments')
|
||||
|
||||
def Server(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "server")[1]
|
||||
|
||||
def Port(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "port")[1]
|
||||
|
||||
def Encryption(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "encryption")[1]
|
||||
|
||||
def Username(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "username")[1]
|
||||
|
||||
def Password(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "email_password")[1]
|
||||
|
||||
def SendFrom(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "send_from")[1]
|
||||
|
||||
# Thank you, @gdeeble from GitHub
|
||||
def AuthenticationRequired(self):
|
||||
return self.DashboardConfig.GetConfig("Email", "authentication_required")[1]
|
||||
|
||||
def ready(self):
|
||||
if self.AuthenticationRequired():
|
||||
return all([self.Server(), self.Port(), self.Encryption(), self.Username(), self.Password(), self.SendFrom()])
|
||||
return all([self.Server(), self.Port(), self.Encryption(), self.SendFrom()])
|
||||
self.refresh_vals()
|
||||
|
||||
def send(self, receiver, subject, body, includeAttachment = False, attachmentName = "") -> tuple[bool, str] | tuple[bool, None]:
|
||||
if self.ready():
|
||||
try:
|
||||
self.smtp = smtplib.SMTP(self.Server(), port=int(self.Port()))
|
||||
self.smtp.ehlo()
|
||||
if self.Encryption() == "STARTTLS":
|
||||
self.smtp.starttls()
|
||||
if self.AuthenticationRequired():
|
||||
self.smtp.login(self.Username(), self.Password())
|
||||
message = MIMEMultipart()
|
||||
message['Subject'] = subject
|
||||
message['From'] = self.SendFrom()
|
||||
message["To"] = receiver
|
||||
message.attach(MIMEText(body, "plain"))
|
||||
def refresh_vals(self):
|
||||
self.Server = self.DashboardConfig.GetConfig("Email", "server")[1]
|
||||
self.Port = self.DashboardConfig.GetConfig("Email", "port")[1]
|
||||
|
||||
if includeAttachment and len(attachmentName) > 0:
|
||||
attachmentPath = os.path.join('./attachments', attachmentName)
|
||||
if os.path.exists(attachmentPath):
|
||||
attachment = MIMEBase("application", "octet-stream")
|
||||
with open(os.path.join('./attachments', attachmentName), 'rb') as f:
|
||||
attachment.set_payload(f.read())
|
||||
encoders.encode_base64(attachment)
|
||||
attachment.add_header("Content-Disposition", f"attachment; filename= {attachmentName}",)
|
||||
message.attach(attachment)
|
||||
else:
|
||||
self.smtp.close()
|
||||
return False, "Attachment does not exist"
|
||||
self.smtp.sendmail(self.SendFrom(), receiver, message.as_string())
|
||||
self.smtp.close()
|
||||
return True, None
|
||||
except Exception as e:
|
||||
return False, f"Send failed | Reason: {e}"
|
||||
return False, "SMTP not configured"
|
||||
self.Encryption = self.DashboardConfig.GetConfig("Email", "encryption")[1]
|
||||
self.AuthRequired = self.DashboardConfig.GetConfig("Email", "authentication_required")[1]
|
||||
self.Username = self.DashboardConfig.GetConfig("Email", "username")[1]
|
||||
self.Password = self.DashboardConfig.GetConfig("Email", "email_password")[1]
|
||||
|
||||
self.SendFrom = self.DashboardConfig.GetConfig("Email", "send_from")[1]
|
||||
|
||||
def is_ready(self) -> bool:
|
||||
self.refresh_vals()
|
||||
|
||||
if self.AuthRequired:
|
||||
ready = all([
|
||||
self.Server, self.Port, self.Encryption,
|
||||
self.Username, self.Password, self.SendFrom
|
||||
])
|
||||
else:
|
||||
ready = all([
|
||||
self.Server, self.Port, self.Encryption, self.SendFrom
|
||||
])
|
||||
return ready
|
||||
|
||||
def send(self, receiver, subject, body, includeAttachment: bool = False, attachmentName: str = "") -> tuple[bool, str | None]:
|
||||
if not self.is_ready():
|
||||
return False, "SMTP not configured"
|
||||
|
||||
message = MIMEMultipart()
|
||||
message['Subject'] = subject
|
||||
message['From'] = self.SendFrom
|
||||
message["To"] = receiver
|
||||
message["Date"] = formatdate(localtime=True)
|
||||
message.attach(MIMEText(body, "plain"))
|
||||
|
||||
if includeAttachment and len(attachmentName) > 0:
|
||||
attachmentPath = os.path.join('./attachments', attachmentName)
|
||||
|
||||
if not os.path.exists(attachmentPath):
|
||||
return False, "Attachment does not exist"
|
||||
|
||||
attachment = MIMEBase("application", "octet-stream")
|
||||
with open(os.path.join('./attachments', attachmentName), 'rb') as f:
|
||||
attachment.set_payload(f.read())
|
||||
|
||||
encoders.encode_base64(attachment)
|
||||
attachment.add_header("Content-Disposition", f"attachment; filename= {attachmentName}",)
|
||||
message.attach(attachment)
|
||||
|
||||
smtp = None
|
||||
try:
|
||||
smtp = smtplib.SMTP(self.Server, port=int(self.Port))
|
||||
smtp.ehlo()
|
||||
|
||||
# Configure SMTP encryption type
|
||||
if self.Encryption == "STARTTLS":
|
||||
smtp.starttls()
|
||||
smtp.ehlo()
|
||||
|
||||
# Log into the SMTP server if required
|
||||
if self.AuthRequired:
|
||||
smtp.login(self.Username, self.Password)
|
||||
|
||||
# Send the actual email from the SMTP object
|
||||
smtp.sendmail(self.SendFrom, receiver, message.as_string())
|
||||
return True, None
|
||||
|
||||
except Exception as e:
|
||||
return False, f"Send failed | Reason: {e}"
|
||||
|
||||
finally:
|
||||
if smtp:
|
||||
smtp.quit()
|
||||
Reference in New Issue
Block a user