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
10 changes: 8 additions & 2 deletions server/services/canvas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from server.models import Offering
from server.services.canvas.fake_canvas import FakeCanvas, FakeCourse, FakeUser
from server.typings.exception import Redirect

from datetime import datetime

def is_mock_canvas() -> bool:
return app.config['MOCK_CANVAS'] and \
Expand Down Expand Up @@ -91,12 +91,18 @@ def get_user_courses_categorized(user: FakeUser | User) \
student_courses: list[FakeCourse | Course] = list(student_courses)
other: list[FakeCourse | Course] = list(other)

def _safe_to_date(date):
try:
return datetime.strptime(date, '%Y-%m-%dT%H:%M:%S%z')
except:
return date

# sorted by start_at_date DESC and then by name ASC
def _sort_courses(courses: list[FakeCourse | Course]):
# Cannot do courses.sort(key=lambda c: (c.start_at_date, c.name))
# String or Datetime object cannot be negated to reverse the order
courses.sort(key=lambda c: c.name)
courses.sort(key=lambda c: c.start_at_date, reverse=True)
courses.sort(key=lambda c: _safe_to_date(c.start_at_date), reverse=True)

_sort_courses(staff_courses)
_sort_courses(student_courses)
Expand Down
2 changes: 1 addition & 1 deletion server/services/email/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def email_about_assignment(exam, form, to_addrs):
failure_addrs.add(to_addr)
continue
email_message = construct_email(
from_addr=form.from_addr.data,
reply_to=form.from_addr.data,
to_addr=to_addr,
subject=subject,
body=body,
Expand Down
11 changes: 7 additions & 4 deletions server/services/email/smtp.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ def __repr__(self) -> str:
f'use_auth={self.use_auth})')


def construct_email(*, from_addr, to_addr, subject, body, body_html=None, bcc_addr=None, cc_addr=None):
# TODO: Due to email config, we hard code the FROM address
# What _users_ specify is the REPLY-TO address, but is labeled as FROM in the form.
def construct_email(*, reply_to, to_addr, subject, body, body_html=None, bcc_addr=None, cc_addr=None):
msg = EmailMessage()
msg['From'], msg['To'], msg['Subject'] = from_addr, to_addr, subject
msg['From'] = 'seamless-learning@berkeley.edu'
msg['Reply-To'], msg['To'], msg['Subject'] = reply_to, to_addr, subject
if bcc_addr:
if isinstance(bcc_addr, str):
bcc_addr = bcc_addr.split(',')
Expand Down Expand Up @@ -110,9 +113,9 @@ def send_emails(*, smtp: SMTPConfig, messages=list[EmailMessage],
return successful_emails, failed_emails


def send_single_email(*, smtp: SMTPConfig, from_addr, to_addr, subject, body,
def send_single_email(*, smtp: SMTPConfig, reply_to, to_addr, subject, body,
body_html=None, bcc_addr=None, cc_addr=None):
msg = construct_email(from_addr=from_addr, to_addr=to_addr, subject=subject, body=body,
msg = construct_email(reply_to=reply_to, to_addr=to_addr, subject=subject, body=body,
body_html=body_html, bcc_addr=bcc_addr, cc_addr=cc_addr)
successful_emails, failed_emails = send_emails(smtp=smtp, messages=[msg])
if successful_emails:
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/test_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_send_plain_text_email(mock_smtp):
"""

success = send_single_email(smtp=_email_config,
from_addr=TEST_FROM_EMAIL,
reply_to=TEST_FROM_EMAIL,
to_addr=TEST_TO_EMAIL,
subject=TEST_SUBJECT,
body=TEST_BODY)
Expand Down Expand Up @@ -86,7 +86,7 @@ def test_batch_send(mock_smtp):
"""
batch_size = 1000
email_messages = [
construct_email(from_addr=TEST_FROM_EMAIL,
construct_email(reply_to=TEST_FROM_EMAIL,
to_addr=TEST_TO_EMAIL,
subject=TEST_SUBJECT,
body=TEST_BODY)
Expand Down Expand Up @@ -182,7 +182,7 @@ def test_batch_send_with_mock_smtp_server(smtp_server):

batch_size = 1000
email_messages = [
construct_email(from_addr=TEST_FROM_EMAIL,
construct_email(reply_to=TEST_FROM_EMAIL,
to_addr=TEST_TO_EMAIL,
subject=TEST_SUBJECT,
body=TEST_BODY)
Expand Down
Loading