Files
2026-09-06 17:32:29 +03:00

210 lines
6.9 KiB
Python

import os
import smtplib
import ssl
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.utils import formataddr
from threading import Thread
from flask import render_template_string, render_template
from dotenv import load_dotenv
load_dotenv()
class Mailer:
def __init__(self):
self.enabled = os.environ.get('MAIL_ENABLED', 'false').lower() == 'true'
self.smtp_server = os.environ.get('MAIL_SERVER', 'smtp.gmail.com')
self.smtp_port = int(os.environ.get('MAIL_PORT', 587))
self.use_tls = os.environ.get('MAIL_USE_TLS', 'true').lower() == 'true'
self.use_ssl = os.environ.get('MAIL_USE_SSL', 'false').lower() == 'true'
self.username = os.environ.get('MAIL_USERNAME', '')
self.password = os.environ.get('MAIL_PASSWORD', '')
self.default_sender = os.environ.get('MAIL_DEFAULT_SENDER', self.username)
def is_enabled(self) -> bool:
if not self.enabled:
return False
if not self.username or not self.password:
print("Mail: Отсутствуют логин или пароль")
return False
return True
def _get_connection(self):
if self.use_ssl:
context = ssl.create_default_context()
return smtplib.SMTP_SSL(self.smtp_server, self.smtp_port, context=context)
else:
server = smtplib.SMTP(self.smtp_server, self.smtp_port)
if self.use_tls:
server.starttls()
return server
def _send(self, to_emails, subject, body, html_body=None, from_email=None, from_name='SecretText'):
if not self.is_enabled():
print(f"Mail: Пропущено письмо (отключено)")
return False
if not to_emails:
print("Mail: Не указаны получатели")
return False
if isinstance(to_emails, str):
to_emails = [to_emails]
from_email = from_email or self.default_sender
try:
msg = MIMEMultipart('alternative')
msg['Subject'] = subject
msg['From'] = formataddr((from_name, from_email))
msg['To'] = ', '.join(to_emails)
msg.attach(MIMEText(body, 'plain', 'utf-8'))
if html_body:
msg.attach(MIMEText(html_body, 'html', 'utf-8'))
with self._get_connection() as server:
if self.username and self.password:
server.login(self.username, self.password)
server.send_message(msg)
print(f"Mail: Письмо отправлено на {', '.join(to_emails)}")
return True
except Exception as e:
print(f"Mail: Ошибка отправки: {e}")
return False
def send_email(self, to_emails, subject, body, html_body=None, from_email=None, from_name='SecretText'):
if not self.is_enabled():
print(f"Mail: Письмо не отправлено (отключено)")
return None
thread = Thread(
target=self._send,
args=(to_emails, subject, body, html_body, from_email, from_name),
daemon=True
)
thread.start()
return thread
def send_email_with_template(self, to_emails, subject, template_name, context=None, from_email=None,
from_name='SecretText'):
from main import app
context = context or {}
with app.app_context():
html_body = render_template(template_name, **context)
body = f"Письмо от SecretText. Пожалуйста, используйте почтовый клиент с поддержкой HTML."
return self.send_email(to_emails, subject, body, html_body, from_email, from_name)
def send_user_created_email(self, to_email, username, view_url):
subject = f"Ваш аккаунт в SecretText создан!"
context = {
'username': username,
'view_url': view_url,
'base_url': self._get_base_url()
}
return self.send_email_with_template(
to_email,
subject,
'emails/user_created.html',
context
)
def _get_base_url(self):
from main import app
return app.config.get('APP_URL', 'http://localhost:5000')
def send_welcome_email(self, to_email, username):
subject = f"Добро пожаловать в SecretText, {username}!"
context = {
'username': username,
'base_url': self._get_base_url()
}
return self.send_email_with_template(
to_email,
subject,
'emails/welcome.html',
context
)
def send_secret_notification(self, to_email, username, secret_id=None):
subject = f"Новый секрет для вас!"
context = {
'username': username,
'base_url': self._get_base_url()
}
return self.send_email_with_template(
to_email,
subject,
'emails/secret_notification.html',
context
)
def send_secret_viewed_notification(self, to_email, username):
subject = f"Ваш секрет просмотрен!"
context = {
'username': username,
'base_url': self._get_base_url()
}
return self.send_email_with_template(
to_email,
subject,
'emails/secret_viewed.html',
context
)
# mailer.py
def send_secret_received_email(self, to_email, username, note=None):
subject = f"Вам отправили секрет по запросу!"
context = {
'username': username,
'note': note,
'base_url': self._get_base_url()
}
return self.send_email_with_template(
to_email,
subject,
'emails/secret_received.html',
context
)
mailer = Mailer()
def send_mail(to_emails, subject, body, html_body=None):
return mailer.send_email(to_emails, subject, body, html_body)
def send_mail_template(to_emails, subject, template_name, context=None):
return mailer.send_email_with_template(to_emails, subject, template_name, context)
def send_user_created_email(to_email, username, view_url):
return mailer.send_user_created_email(to_email, username, view_url)
def send_welcome_email(to_email, username):
return mailer.send_welcome_email(to_email, username)
def send_secret_notification(to_email, username, secret_id=None):
return mailer.send_secret_notification(to_email, username, secret_id)
def send_secret_viewed_notification(to_email, username):
return mailer.send_secret_viewed_notification(to_email, username)
def send_secret_received_email(to_email, username, note=None):
return mailer.send_secret_received_email(to_email, username, note)