-
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathenroll_command.py
More file actions
136 lines (119 loc) · 4.66 KB
/
Copy pathenroll_command.py
File metadata and controls
136 lines (119 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
from django_email_learning.services.command_models.abstract_command import (
AbstractCommand,
)
from django_email_learning.services.command_models.exceptions.invalid_course_slug_error import (
InvalidCourseSlugError,
)
from django_email_learning.models import (
BlockedEmail,
Learner,
Enrollment,
Course,
EnrollmentStatus,
)
from django_email_learning.services.utils import mask_email
from django_email_learning.services.email_sender_service import EmailSenderService
from django_email_learning.services import jwt_service
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from django.utils.translation import gettext as _
from django.conf import settings
from django.urls import reverse
from typing import Literal
class EnrollCommand(AbstractCommand):
command_name: Literal["enroll"] = "enroll"
email: str
course_slug: str
organization_id: int
def execute(self) -> None:
# Check if the email is blocked
if BlockedEmail.objects.filter(email=self.email).exists():
self.logger.info(
f"Enrollment Rejected: {mask_email(self.email)} is blocked"
)
return
# Check if Learner with the email exists, if not create one
learner, created = Learner.objects.get_or_create(
email=self.email, organization_id=self.organization_id
)
if created:
self.logger.info(
f"Created new Learner for email: {mask_email(self.email)}. Learner ID: {learner.id}"
)
try:
course = Course.objects.get(
slug=self.course_slug,
organization_id=self.organization_id,
enabled=True,
)
except Course.DoesNotExist:
self.logger.error(
f"Enrollment Failed: Invalid course slug '{self.course_slug}' for organization ID {self.organization_id}"
)
raise InvalidCourseSlugError(
f"Course with slug '{self.course_slug}' does not exist or is not enabled for organization ID {self.organization_id}"
)
# Check if an enrollment already exists
if (
Enrollment.objects.filter(learner=learner, course=course)
.exclude(status=EnrollmentStatus.DEACTIVATED)
.exists()
):
self.logger.info(
f"Enrollment Skipped: Learner ID {learner.id} is already enrolled in course '{self.course_slug}'"
)
return
# Create the enrollment
enrollment = Enrollment.objects.create(
learner=learner, course=course, status=EnrollmentStatus.UNVERIFIED
)
self.logger.info(
f"Enrollment Successful: Learner ID {learner.id} enrolled in course '{self.course_slug}'. Enrollment ID: {enrollment.id}"
)
# Send verification email
token = jwt_service.generate_jwt(
{
"verification_code": enrollment.activation_code,
"enrollment_id": enrollment.id,
}
)
verification_relative_path = (
reverse("django_email_learning:personalised:verify_enrollment")
+ f"?token={token}"
)
verification_link = (
settings.DJANGO_EMAIL_LEARNING["SITE_BASE_URL"] + verification_relative_path
)
template_context = {
"course_title": course.title,
"verification_link": verification_link,
"verification_code": enrollment.activation_code,
"organization_name": course.organization.name,
"support_imap_interface": course.imap_connection is not None,
"imap_email_address": course.imap_connection.email
if course.imap_connection
else None,
}
email_service = EmailSenderService()
subject = _("Verify your enrollment")
body = render_to_string(
"emails/enrolment_verification.txt",
template_context,
)
to_emails = [self.email]
html_content = render_to_string(
"emails/enrolment_verification.html",
template_context,
)
# TODO: Add AMP content/type to activate directly in email clients that support it
email = EmailMultiAlternatives(
subject=subject,
body=body,
from_email=email_service.from_email,
to=to_emails,
)
email.attach_alternative(html_content, "text/html")
email_service.send(email)
self.logger.info(
f"Verification email sent to {mask_email(self.email)} for Enrollment ID: {enrollment.id}"
)