1
0
Fork 0
mirror of https://github.com/ProjectSynthoria/SynthoriaArchive.git synced 2025-03-12 15:26:56 +02:00
SynthoriaArchive/nyaa/email.py
2025-03-02 15:08:58 +02:00

113 lines
3.5 KiB
Python

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from flask import current_app as app
import requests
from nyaa import models
class EmailHolder(object):
''' Holds email subject, recipient and content, so we have a general class for
all mail backends. '''
def __init__(self, subject=None, recipient=None, text=None, html=None):
self.subject = subject
self.recipient = recipient # models.User or string
self.text = text
self.html = html
def format_recipient(self):
if isinstance(self.recipient, models.User):
return '{} <{}>'.format(self.recipient.username, self.recipient.email)
else:
return self.recipient
def recipient_email(self):
if isinstance(self.recipient, models.User):
return self.recipient.email
else:
return self.recipient.email
def as_mimemultipart(self):
msg = MIMEMultipart()
msg['Subject'] = self.subject
msg['From'] = app.config['MAIL_FROM_ADDRESS']
msg['To'] = self.format_recipient()
msg.attach(MIMEText(self.text, 'plain'))
if self.html:
msg.attach(MIMEText(self.html, 'html'))
return msg
def send_email(email_holder):
"""Send an email using the configured mail backend."""
mail_backend = app.config.get('MAIL_BACKEND')
if not mail_backend:
app.logger.warning('No mail backend configured, skipping email send')
return False
try:
if mail_backend == 'mailgun':
success = _send_mailgun(email_holder)
elif mail_backend == 'smtp':
success = _send_smtp(email_holder)
else:
app.logger.error(f'Unknown mail backend: {mail_backend}')
return False
if not success:
app.logger.error(f'Failed to send email using {mail_backend} backend')
return False
app.logger.info(f'Email successfully sent using {mail_backend} backend')
return True
except Exception as e:
app.logger.error(f'Error sending email: {str(e)}')
return False
def _send_mailgun(email_holder):
"""Send an email using Mailgun API with proper error handling."""
try:
mailgun_endpoint = app.config['MAILGUN_API_BASE'] + '/messages'
auth = ('api', app.config['MAILGUN_API_KEY'])
data = {
'from': app.config['MAIL_FROM_ADDRESS'],
'to': email_holder.format_recipient(),
'subject': email_holder.subject,
'text': email_holder.text,
'html': email_holder.html
}
r = requests.post(mailgun_endpoint, data=data, auth=auth)
if r.status_code != 200:
app.logger.error(f'Mailgun API error: {r.status_code} - {r.text}')
return False
return True
except Exception as e:
app.logger.error(f'Error sending email via Mailgun: {str(e)}')
return False
def _send_smtp(email_holder):
# NOTE: Unused, most likely untested! Should work, however.
msg = email_holder.as_mimemultipart()
server = smtplib.SMTP(app.config['SMTP_SERVER'], app.config['SMTP_PORT'])
server.set_debuglevel(1)
server.ehlo()
server.starttls()
server.ehlo()
server.login(app.config['SMTP_USERNAME'], app.config['SMTP_PASSWORD'])
server.sendmail(app.config['SMTP_USERNAME'], email_holder.recipient_email(), msg.as_string())
server.quit()