Commit 66c14d7f by Calen Pennington

Add a recurring nudge management command and templates

parent fb9244b7
from __future__ import print_function
import datetime
from dateutil.tz import tzutc, gettz
from django.core.management.base import BaseCommand
from django.test.utils import CaptureQueriesContext
from django.db.models import Prefetch
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import DEFAULT_DB_ALIAS, connections
from openedx.core.djangoapps.schedules.models import Schedule
from openedx.core.djangoapps.user_api.models import UserPreference
from edx_ace.message import MessageType
from edx_ace.recipient_resolver import RecipientResolver
from edx_ace import ace
from edx_ace.recipient import Recipient
from course_modes.models import CourseMode, format_course_price
from lms.djangoapps.experiments.utils import check_and_get_upgrade_link
class RecurringNudge(MessageType):
def __init__(self, week):
self.name = "RecurringNudge_Week{}".format(week)
class ScheduleStartResolver(RecipientResolver):
def __init__(self, target_start_date):
self.target_start_date = target_start_date
def send(self, msg_type):
for (user, language, context) in self.build_email_context():
msg = msg_type.personalize(
Recipient(
user.username,
user.email,
),
language,
context
)
ace.send(msg)
def build_email_context(self):
schedules = Schedule.objects.select_related(
'enrollment__user__profile',
'enrollment__course',
).prefetch_related(
Prefetch(
'enrollment__course__modes',
queryset=CourseMode.objects.filter(mode_slug=CourseMode.VERIFIED),
to_attr='verified_modes'
),
Prefetch(
'enrollment__user__preferences',
queryset=UserPreference.objects.filter(key='time_zone'),
to_attr='tzprefs'
),
).filter(
start__year=self.target_start_date.year,
start__month=self.target_start_date.month,
start__day=self.target_start_date.day,
)
for schedule in schedules:
enrollment = schedule.enrollment
user = enrollment.user
user_time_zone = tzutc()
for preference in user.tzprefs:
user_time_zone = gettz(preference.value)
course_id_str = str(enrollment.course_id)
course = enrollment.course
course_root = reverse('course_root', kwargs={'course_id': course_id_str})
def absolute_url(relative_path):
return u'{}{}'.format(settings.LMS_ROOT_URL, relative_path)
template_context = {
'student_name': user.profile.name,
'course_name': course.display_name,
'course_url': absolute_url(course_root),
}
yield (user, course.language, template_context)
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('--date', default=datetime.datetime.utcnow().date().isoformat())
def handle(self, *args, **options):
current_date = datetime.date(*[int(x) for x in options['date'].split('-')])
for week in (1, 2, 3, 4):
msg_t = RecurringNudge(week)
target_date = current_date + datetime.timedelta(days=offset)
ScheduleStartResolver(target_date).send(msg_t)
\ No newline at end of file
...@@ -32,7 +32,7 @@ class VerifiedDeadlineResolver(RecipientResolver): ...@@ -32,7 +32,7 @@ class VerifiedDeadlineResolver(RecipientResolver):
self.target_deadline = target_deadline self.target_deadline = target_deadline
def send(self, msg_type): def send(self, msg_type):
for (user, language, context) in build_email_context(self.target_deadline): for (user, language, context) in self.build_email_context():
msg = msg_type.personalize( msg = msg_type.personalize(
Recipient( Recipient(
user.username, user.username,
...@@ -43,6 +43,61 @@ class VerifiedDeadlineResolver(RecipientResolver): ...@@ -43,6 +43,61 @@ class VerifiedDeadlineResolver(RecipientResolver):
) )
ace.send(msg) ace.send(msg)
def build_email_context(self):
schedules = Schedule.objects.select_related(
'enrollment__user__profile',
'enrollment__course',
).prefetch_related(
Prefetch(
'enrollment__course__modes',
queryset=CourseMode.objects.filter(mode_slug=CourseMode.VERIFIED),
to_attr='verified_modes'
),
Prefetch(
'enrollment__user__preferences',
queryset=UserPreference.objects.filter(key='time_zone'),
to_attr='tzprefs'
),
).filter(
upgrade_deadline__year=self.schedule_deadline.year,
upgrade_deadline__month=self.schedule_deadline.month,
upgrade_deadline__day=self.schedule_deadline.day,
)
for schedule in schedules:
enrollment = schedule.enrollment
user = enrollment.user
user_time_zone = tzutc()
for preference in user.tzprefs:
user_time_zone = gettz(preference.value)
course_id_str = str(enrollment.course_id)
course = enrollment.course
course_root = reverse('course_root', kwargs={'course_id': course_id_str})
def absolute_url(relative_path):
return u'{}{}'.format(settings.LMS_ROOT_URL, relative_path)
template_context = {
'user_full_name': user.profile.name,
'user_personal_address': user.profile.name if user.profile.name else user.username,
'user_username': user.username,
'user_time_zone': user_time_zone,
'user_schedule_start_time': schedule.start,
'user_schedule_verified_upgrade_deadline_time': schedule.upgrade_deadline,
'course_id': course_id_str,
'course_title': course.display_name,
'course_url': absolute_url(course_root),
'course_image_url': absolute_url(course.course_image_url),
'course_end_time': course.end,
'course_verified_upgrade_url': check_and_get_upgrade_link(course, user),
'course_verified_upgrade_price': format_course_price(course.verified_modes[0].min_price),
}
yield (user, course.language, template_context)
class Command(BaseCommand): class Command(BaseCommand):
...@@ -57,59 +112,3 @@ class Command(BaseCommand): ...@@ -57,59 +112,3 @@ class Command(BaseCommand):
for offset in (2, 9, 16): for offset in (2, 9, 16):
target_date = current_date + datetime.timedelta(days=offset) target_date = current_date + datetime.timedelta(days=offset)
VerifiedDeadlineResolver(target_date).send(msg_t) VerifiedDeadlineResolver(target_date).send(msg_t)
def build_email_context(schedule_deadline):
schedules = Schedule.objects.select_related(
'enrollment__user__profile',
'enrollment__course',
).prefetch_related(
Prefetch(
'enrollment__course__modes',
queryset=CourseMode.objects.filter(mode_slug=CourseMode.VERIFIED),
to_attr='verified_modes'
),
Prefetch(
'enrollment__user__preferences',
queryset=UserPreference.objects.filter(key='time_zone'),
to_attr='tzprefs'
),
).filter(
upgrade_deadline__year=schedule_deadline.year,
upgrade_deadline__month=schedule_deadline.month,
upgrade_deadline__day=schedule_deadline.day,
)
for schedule in schedules:
enrollment = schedule.enrollment
user = enrollment.user
user_time_zone = tzutc()
for preference in user.tzprefs:
user_time_zone = gettz(preference.value)
course_id_str = str(enrollment.course_id)
course = enrollment.course
course_root = reverse('course_root', kwargs={'course_id': course_id_str})
def absolute_url(relative_path):
return u'{}{}'.format(settings.LMS_ROOT_URL, relative_path)
template_context = {
'user_full_name': user.profile.name,
'user_personal_address': user.profile.name if user.profile.name else user.username,
'user_username': user.username,
'user_time_zone': user_time_zone,
'user_schedule_start_time': schedule.start,
'user_schedule_verified_upgrade_deadline_time': schedule.upgrade_deadline,
'course_id': course_id_str,
'course_title': course.display_name,
'course_url': absolute_url(course_root),
'course_image_url': absolute_url(course.course_image_url),
'course_end_time': course.end,
'course_verified_upgrade_url': check_and_get_upgrade_link(course, user),
'course_verified_upgrade_price': format_course_price(course.verified_modes[0].min_price),
}
yield (user, course.language, template_context)
Dear {{student_name}},
<br><br>
Remember when you enrolled in <strong>{{course_name}}</strong> on edX.org? We do! We are excited to let you know the course has started. Come see what everyone is learning.
\ No newline at end of file
Dear {{student_name}},
Remember when you enrolled in {{course_name}} on edX.org?
We do! We are excited to let you know the course has started. Come see
what everyone is learning.
\ No newline at end of file
Dear {{student_name}},
<br><br>
Numerous edX learners in <strong>{{course_name}}</strong> are completing more problems every week. What do you want to do to keep learning?
\ No newline at end of file
Dear {{student_name}},
<br><br>
Numerous edX learners in {{course_name}} are completing more problems every week.
What do you want to do to keep learning?
\ No newline at end of file
Dear {{student_name}},
<br><br>
Many edX.org learners use their commutes to engage with courses. Want to
learn on the go? Learn on your preferred device. Remember, when you participate
in <strong>{{course_name}}</strong>, you learn more things.
\ No newline at end of file
Dear {{student_name}},
Many edX.org learners use their commutes to engage with courses.
Want to learn on the go? Learn on your preferred device. Remember,
when you participate in {{course_name}}, you learn
more things.
\ No newline at end of file
Dear {{student_name}},
<br><br>
Many successful edX learners in <strong>{{course_name}}</strong>
are watching videos every week. What do you want to do to keep learning?
\ No newline at end of file
Dear {{student_name}},
Many successful edX learners in {{course_name}}
are watching videos every week. What do you want
to do to keep learning?
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment