Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions askbot/mail/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@

DEBUG_EMAIL = django_settings.ASKBOT_DEBUG_INCOMING_EMAIL

def _log_email_sent(subject, recipient_list):
"""Append a line to the email log for monitoring/daily summaries."""
log_path = getattr(django_settings, 'EMAIL_LOG_FILE', None)
if not log_path:
return
try:
import datetime
ts = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
recipients = ','.join(str(r) for r in recipient_list)
with open(log_path, 'a') as f:
f.write(f'[{ts}] to={recipients} subject={subject}\n')
except Exception:
pass # never break email sending over logging

#or the future API
def prefix_the_subject_line(subject):
"""prefixes the subject line with the
Expand Down Expand Up @@ -110,6 +124,8 @@ def send_mail( # pylint: disable=too-many-arguments
attachments=attachments
)
logging.debug('sent update to %s' % ','.join(map(str, recipient_list)))
# Log email activity for monitoring
_log_email_sent(subject_line, recipient_list)
except Exception as error: # pylint: disable=broad-except
sys.stderr.write('\n' + str(error) + '\n')
if raise_on_failure:
Expand Down
53 changes: 53 additions & 0 deletions askbot/tests/test_email_logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""Tests for email send logging."""
import os
import tempfile
from unittest.mock import patch

from django.test import TestCase, override_settings

from askbot.mail import _log_email_sent


class EmailLoggingTests(TestCase):
"""Tests for _log_email_sent()."""

def test_no_setting_noop(self):
"""No EMAIL_LOG_FILE setting means no file I/O."""
with override_settings(**{'EMAIL_LOG_FILE': None}):
# Should not raise and not create any files
_log_email_sent('Test subject', ['user@example.com'])

def test_writes_log_entry(self):
"""Log file should contain subject and recipient."""
with tempfile.NamedTemporaryFile(mode='w', suffix='.log',
delete=False) as f:
log_path = f.name
try:
with self.settings(EMAIL_LOG_FILE=log_path):
_log_email_sent('Hello world', ['alice@example.com'])
with open(log_path) as f:
contents = f.read()
self.assertIn('subject=Hello world', contents)
self.assertIn('to=alice@example.com', contents)
finally:
os.unlink(log_path)

def test_multiple_recipients(self):
"""Multiple recipients should be comma-separated."""
with tempfile.NamedTemporaryFile(mode='w', suffix='.log',
delete=False) as f:
log_path = f.name
try:
with self.settings(EMAIL_LOG_FILE=log_path):
_log_email_sent('Multi', ['a@example.com', 'b@example.com'])
with open(log_path) as f:
contents = f.read()
self.assertIn('to=a@example.com,b@example.com', contents)
finally:
os.unlink(log_path)

def test_file_error_silenced(self):
"""IOError when writing log should not propagate."""
with self.settings(EMAIL_LOG_FILE='/nonexistent/dir/email.log'):
# Should not raise
_log_email_sent('Test', ['user@example.com'])