Commit 5e176bea by Waheed Ahmed

Preview available email.

ECOM-6084
parent 862dd472
...@@ -87,6 +87,7 @@ class CourseRunSerializer(serializers.ModelSerializer): ...@@ -87,6 +87,7 @@ class CourseRunSerializer(serializers.ModelSerializer):
return validated_values return validated_values
@transaction.atomic
def update(self, instance, validated_data): def update(self, instance, validated_data):
instance = super(CourseRunSerializer, self).update(instance, validated_data) instance = super(CourseRunSerializer, self).update(instance, validated_data)
preview_url = validated_data.get('preview_url') preview_url = validated_data.get('preview_url')
......
...@@ -107,9 +107,13 @@ class CourseRunSerializerTests(TestCase): ...@@ -107,9 +107,13 @@ class CourseRunSerializerTests(TestCase):
""" Verify that course 'owner_role' will be changed to course_team after updating """ Verify that course 'owner_role' will be changed to course_team after updating
course run with preview url. course run with preview url.
""" """
self.course_run.preview_url = ''
self.course_run.save()
serializer = self.serializer_class(self.course_run) serializer = self.serializer_class(self.course_run)
serializer.update(self.course_run, serializer.data) serializer.update(self.course_run, {'preview_url': 'https://example.com/abc/course'})
self.assertEqual(self.course_state.owner_role, PublisherUserRole.CourseTeam) self.assertEqual(self.course_state.owner_role, PublisherUserRole.CourseTeam)
self.assertEqual(self.course_run.preview_url, serializer.data['preview_url'])
def test_update_lms_course_id(self): def test_update_lms_course_id(self):
""" Verify that 'changed_by' also updated after updating course_run's lms_course_id.""" """ Verify that 'changed_by' also updated after updating course_run's lms_course_id."""
...@@ -122,6 +126,36 @@ class CourseRunSerializerTests(TestCase): ...@@ -122,6 +126,36 @@ class CourseRunSerializerTests(TestCase):
self.assertEqual(self.course_run.lms_course_id, serializer.data['lms_course_id']) self.assertEqual(self.course_run.lms_course_id, serializer.data['lms_course_id'])
self.assertEqual(self.course_run.changed_by, self.user) self.assertEqual(self.course_run.changed_by, self.user)
def test_update_with_transaction_rollback(self):
"""
Verify that transaction roll backed if an error occurred.
"""
self.course_run.preview_url = ''
self.course_run.save()
serializer = self.serializer_class(self.course_run)
with self.assertRaises(Exception):
serializer.update(self.course_run, {'preview_url': 'invalid_url'})
self.assertFalse(self.course_run.preview_url)
def test_transaction_roll_back_with_error_on_email(self):
"""
Verify that transaction is roll backed if error occurred during email sending.
"""
toggle_switch('enable_publisher_email_notifications', True)
self.course_run.preview_url = ''
self.course_run.save()
serializer = self.serializer_class(self.course_run)
self.assertEqual(self.course_run.course_run_state.owner_role, PublisherUserRole.Publisher)
with self.assertRaises(Exception):
serializer.update(self.course_run, {'preview_url': 'https://example.com/abc/course'})
self.course_run = CourseRun.objects.get(id=self.course_run.id)
self.assertFalse(self.course_run.preview_url)
# Verify that owner role not changed.
self.assertEqual(self.course_run.course_run_state.owner_role, PublisherUserRole.Publisher)
class CourseRevisionSerializerTests(TestCase): class CourseRevisionSerializerTests(TestCase):
def test_course_revision_serializer(self): def test_course_revision_serializer(self):
......
...@@ -305,14 +305,31 @@ class UpdateCourseRunViewTests(TestCase): ...@@ -305,14 +305,31 @@ class UpdateCourseRunViewTests(TestCase):
def test_update_preview_url(self): def test_update_preview_url(self):
"""Verify the user can update course preview url.""" """Verify the user can update course preview url."""
self.course_run.lms_course_id = 'course-v1:testX+TC167+2018T1'
self.course_run.save()
preview_url = 'https://example.com/abc/course' preview_url = 'https://example.com/abc/course'
factories.CourseRunStateFactory.create(course_run=self.course_run, owner_role=PublisherUserRole.Publisher) factories.CourseRunStateFactory.create(course_run=self.course_run, owner_role=PublisherUserRole.Publisher)
factories.CourseUserRoleFactory(
course=self.course_run.course, role=PublisherUserRole.Publisher
)
course_team_role = factories.CourseUserRoleFactory(
course=self.course_run.course, role=PublisherUserRole.CourseTeam
)
response = self._make_request(preview_url) response = self._make_request(preview_url)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
course_run = CourseRun.objects.get(id=self.course_run.id) course_run = CourseRun.objects.get(id=self.course_run.id)
self.assertEqual(course_run.preview_url, preview_url) self.assertEqual(course_run.preview_url, preview_url)
course_key = CourseKey.from_string(course_run.lms_course_id)
subject = 'Review requested: Preview for {course_name} {run_number}'.format(
course_name=self.course_run.course.title,
run_number=course_key.run
)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual([course_team_role.user.email], mail.outbox[0].to)
self.assertEqual(str(mail.outbox[0].subject), subject)
def test_update_with_invalid_preview_url(self): def test_update_with_invalid_preview_url(self):
"""Verify the user can't update course preview url if url has invalid format.""" """Verify the user can't update course preview url if url has invalid format."""
preview_url = 'invalid_url_format' preview_url = 'invalid_url_format'
...@@ -327,6 +344,25 @@ class UpdateCourseRunViewTests(TestCase): ...@@ -327,6 +344,25 @@ class UpdateCourseRunViewTests(TestCase):
content_type=JSON_CONTENT_TYPE content_type=JSON_CONTENT_TYPE
) )
def test_update_preview_url_with_notification_disabled(self):
"""
Verify that no email sent on update course preview url if
notification disabled by user.
"""
preview_url = 'https://example.com/abc/course'
factories.CourseRunStateFactory.create(course_run=self.course_run, owner_role=PublisherUserRole.Publisher)
course_team_role = factories.CourseUserRoleFactory(
course=self.course_run.course, role=PublisherUserRole.CourseTeam
)
factories.UserAttributeFactory(user=course_team_role.user, enable_email_notification=False)
response = self._make_request(preview_url)
self.assertEqual(response.status_code, 200)
course_run = CourseRun.objects.get(id=self.course_run.id)
self.assertEqual(course_run.preview_url, preview_url)
self.assertEqual(len(mail.outbox), 0)
class CourseRevisionDetailViewTests(TestCase): class CourseRevisionDetailViewTests(TestCase):
......
...@@ -58,7 +58,9 @@ def send_email_for_studio_instance_created(course_run, updated_text=_('created') ...@@ -58,7 +58,9 @@ def send_email_for_studio_instance_created(course_run, updated_text=_('created')
email_msg.attach_alternative(html_content, 'text/html') email_msg.attach_alternative(html_content, 'text/html')
email_msg.send() email_msg.send()
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
logger.exception('Failed to send email notifications for course_run [%s]', course_run.id) error_message = 'Failed to send email notifications for course_run [{run_id}]'.format(run_id=course_run.id)
logger.exception(error_message)
raise Exception(error_message)
def send_email_for_course_creation(course, course_run): def send_email_for_course_creation(course, course_run):
...@@ -292,16 +294,15 @@ def send_email_preview_accepted(course_run): ...@@ -292,16 +294,15 @@ def send_email_preview_accepted(course_run):
html_template = 'publisher/email/course_run/preview_accepted.html' html_template = 'publisher/email/course_run/preview_accepted.html'
course = course_run.course course = course_run.course
course_key = CourseKey.from_string(course_run.lms_course_id) publisher_user = course.publisher
subject = _('Publication requested: {course_name} {run_number}').format( # pylint: disable=no-member
course_name=course.title,
run_number=course_key.run)
publisher_user = course_run.course.publisher
try: try:
if is_email_notification_enabled(publisher_user): if is_email_notification_enabled(publisher_user):
project_coordinator = course_run.course.project_coordinator course_key = CourseKey.from_string(course_run.lms_course_id)
subject = _('Publication requested: {course_name} {run_number}').format( # pylint: disable=no-member
course_name=course.title,
run_number=course_key.run)
project_coordinator = course.project_coordinator
to_addresses = [publisher_user.email] to_addresses = [publisher_user.email]
if is_email_notification_enabled(project_coordinator): if is_email_notification_enabled(project_coordinator):
to_addresses.append(project_coordinator.email) to_addresses.append(project_coordinator.email)
...@@ -344,26 +345,30 @@ def send_email_preview_page_is_available(course_run): ...@@ -344,26 +345,30 @@ def send_email_preview_page_is_available(course_run):
""" """
txt_template = 'publisher/email/course_run/preview_available.txt' txt_template = 'publisher/email/course_run/preview_available.txt'
html_template = 'publisher/email/course_run/preview_available.html' html_template = 'publisher/email/course_run/preview_available.html'
run_name = '{pacing_type}: {start_date}'.format(
pacing_type=course_run.get_pacing_type_display(),
start_date=course_run.start.strftime("%B %d, %Y")
)
subject = _('Preview for {run_name} is available').format(run_name=run_name) # pylint: disable=no-member
course_team_user = course_run.course.course_team_admin course_team_user = course_run.course.course_team_admin
try: try:
if is_email_notification_enabled(course_team_user): if is_email_notification_enabled(course_team_user):
course_key = CourseKey.from_string(course_run.lms_course_id)
subject = _('Review requested: Preview for {course_name} {run_number}').format( # pylint: disable=no-member
course_name=course_run.course.title,
run_number=course_key.run
)
to_addresses = [course_team_user.email] to_addresses = [course_team_user.email]
from_address = settings.PUBLISHER_FROM_EMAIL from_address = settings.PUBLISHER_FROM_EMAIL
project_coordinator = course_run.course.project_coordinator project_coordinator = course_run.course.project_coordinator
page_path = reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run.id}) page_path = reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run.id})
context = { context = {
'course_name': run_name, 'sender_role': PublisherUserRole.Publisher,
'recipient_name': course_team_user.get_full_name() or course_team_user.username,
'course_name': course_run.course.title,
'course_run_number': course_key.run,
'preview_link': course_run.preview_url,
'contact_us_email': project_coordinator.email if project_coordinator else '', 'contact_us_email': project_coordinator.email if project_coordinator else '',
'page_url': 'https://{host}{path}'.format( 'page_url': 'https://{host}{path}'.format(
host=Site.objects.get_current().domain.strip('/'), path=page_path host=Site.objects.get_current().domain.strip('/'), path=page_path
) ),
'platform_name': settings.PLATFORM_NAME
} }
template = get_template(txt_template) template = get_template(txt_template)
plain_content = template.render(context) plain_content = template.render(context)
...@@ -371,13 +376,17 @@ def send_email_preview_page_is_available(course_run): ...@@ -371,13 +376,17 @@ def send_email_preview_page_is_available(course_run):
html_content = template.render(context) html_content = template.render(context)
email_msg = EmailMultiAlternatives( email_msg = EmailMultiAlternatives(
subject, plain_content, from_address, to=[from_address], bcc=to_addresses subject, plain_content, from_address, to=to_addresses
) )
email_msg.attach_alternative(html_content, 'text/html') email_msg.attach_alternative(html_content, 'text/html')
email_msg.send() email_msg.send()
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
logger.exception('Failed to send email notifications for preview available of course-run %s', course_run.id) error_message = 'Failed to send email notifications for preview available of course-run {run_id}'.format(
run_id=course_run.id
)
logger.exception(error_message)
raise Exception(error_message)
def send_course_run_published_email(course_run): def send_course_run_published_email(course_run):
......
...@@ -14,6 +14,7 @@ from course_discovery.apps.course_metadata.tests import toggle_switch ...@@ -14,6 +14,7 @@ from course_discovery.apps.course_metadata.tests import toggle_switch
from course_discovery.apps.course_metadata.tests.factories import OrganizationFactory from course_discovery.apps.course_metadata.tests.factories import OrganizationFactory
from course_discovery.apps.publisher import emails from course_discovery.apps.publisher import emails
from course_discovery.apps.publisher.choices import PublisherUserRole from course_discovery.apps.publisher.choices import PublisherUserRole
from course_discovery.apps.publisher.models import UserAttributes
from course_discovery.apps.publisher.tests import factories from course_discovery.apps.publisher.tests import factories
from course_discovery.apps.publisher.tests.factories import UserAttributeFactory from course_discovery.apps.publisher.tests.factories import UserAttributeFactory
...@@ -42,17 +43,12 @@ class StudioInstanceCreatedEmailTests(TestCase): ...@@ -42,17 +43,12 @@ class StudioInstanceCreatedEmailTests(TestCase):
@mock.patch('django.core.mail.message.EmailMessage.send', mock.Mock(side_effect=TypeError)) @mock.patch('django.core.mail.message.EmailMessage.send', mock.Mock(side_effect=TypeError))
def test_email_with_error(self): def test_email_with_error(self):
""" Verify that emails for studio instance created.""" """ Verify that emails failure raise exception."""
with LogCapture(emails.logger.name) as l: with self.assertRaises(Exception) as ex:
emails.send_email_for_studio_instance_created(self.course_run) emails.send_email_for_studio_instance_created(self.course_run)
l.check( error_message = 'Failed to send email notifications for course_run [{}]'.format(self.course_run.id)
( self.assertEqual(ex.message, error_message)
emails.logger.name,
'ERROR',
'Failed to send email notifications for course_run [{}]'.format(self.course_run.id)
)
)
def test_email_sent_successfully(self): def test_email_sent_successfully(self):
""" Verify that emails sent successfully for studio instance created.""" """ Verify that emails sent successfully for studio instance created."""
...@@ -143,6 +139,15 @@ class CourseCreatedEmailTests(TestCase): ...@@ -143,6 +139,15 @@ class CourseCreatedEmailTests(TestCase):
self.assertIn('Please create a Studio instance for this course', body) self.assertIn('Please create a Studio instance for this course', body)
self.assertIn('Thanks', body) self.assertIn('Thanks', body)
def test_email_not_sent_with_notification_disabled(self):
""" Verify that emails not sent if notification disabled by user."""
user_attribute = UserAttributes.objects.get(user=self.user)
user_attribute.enable_email_notification = False
user_attribute.save()
emails.send_email_for_course_creation(self.course_run.course, self.course_run)
self.assertEqual(len(mail.outbox), 0)
class SendForReviewEmailTests(TestCase): class SendForReviewEmailTests(TestCase):
""" Tests for the email functionality for send for review. """ """ Tests for the email functionality for send for review. """
...@@ -429,38 +434,49 @@ class CourseRunPreviewEmailTests(TestCase): ...@@ -429,38 +434,49 @@ class CourseRunPreviewEmailTests(TestCase):
""" """
Verify that preview available email functionality works fine. Verify that preview available email functionality works fine.
""" """
emails.send_email_preview_page_is_available(self.run_state.course_run) course_run = self.run_state.course_run
run_name = '{pacing_type}: {start_date}'.format( course_run.lms_course_id = 'course-v1:testX+testX1.0+2017T1'
pacing_type=self.run_state.course_run.get_pacing_type_display(), course_run.save()
start_date=self.run_state.course_run.start.strftime("%B %d, %Y")
) emails.send_email_preview_page_is_available(course_run)
subject = 'Preview for {run_name} is available'.format(
run_name=run_name course_key = CourseKey.from_string(course_run.lms_course_id)
subject = 'Review requested: Preview for {course_name} {run_number}'.format(
course_name=self.course.title,
run_number=course_key.run
) )
self.assertEqual(len(mail.outbox), 1) self.assertEqual(len(mail.outbox), 1)
self.assertEqual([self.course.course_team_admin.email], mail.outbox[0].bcc) self.assertEqual([self.course.course_team_admin.email], mail.outbox[0].to)
self.assertEqual(str(mail.outbox[0].subject), subject) self.assertEqual(str(mail.outbox[0].subject), subject)
body = mail.outbox[0].body.strip() body = mail.outbox[0].body.strip()
page_path = reverse('publisher:publisher_course_run_detail', kwargs={'pk': self.run_state.course_run.id}) page_path = reverse('publisher:publisher_course_run_detail', kwargs={'pk': course_run.id})
page_url = 'https://{host}{path}'.format(host=Site.objects.get_current().domain.strip('/'), path=page_path) page_url = 'https://{host}{path}'.format(host=Site.objects.get_current().domain.strip('/'), path=page_path)
self.assertIn(page_url, body) self.assertIn(page_url, body)
self.assertIn('is available for review.', body) self.assertIn('A preview is now available for the', body)
def test_preview_available_email_with_error(self): def test_preview_available_email_with_error(self):
""" Verify that email failure log error message.""" """ Verify that exception raised on email failure."""
with mock.patch('django.core.mail.message.EmailMessage.send', side_effect=TypeError): with self.assertRaises(Exception) as ex:
with LogCapture(emails.logger.name) as l: emails.send_email_preview_page_is_available(self.run_state.course_run)
emails.send_email_preview_page_is_available(self.run_state.course_run) error_message = 'Failed to send email notifications for preview available of course-run {}'.format(
l.check( self.run_state.course_run.id
( )
emails.logger.name, self.assertEqual(ex.message, error_message)
'ERROR',
'Failed to send email notifications for preview available of course-run {}'.format( def test_preview_available_email_with_notification_disabled(self):
self.run_state.course_run.id """ Verify that email not sent if notification disabled by user."""
) factories.UserAttributeFactory(user=self.course.course_team_admin, enable_email_notification=False)
) emails.send_email_preview_page_is_available(self.run_state.course_run)
)
self.assertEqual(len(mail.outbox), 0)
def test_preview_accepted_email_with_notification_disabled(self):
""" Verify that preview accepted email not sent if notification disabled by user."""
factories.UserAttributeFactory(user=self.course.publisher, enable_email_notification=False)
emails.send_email_preview_accepted(self.run_state.course_run)
self.assertEqual(len(mail.outbox), 0)
class CourseRunPublishedEmailTests(TestCase): class CourseRunPublishedEmailTests(TestCase):
......
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-07 15:35+0500\n" "POT-Creation-Date: 2017-03-07 18:14+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: apps/api/filters.py #: apps/api/filters.py
#, python-brace-format #, python-brace-format
...@@ -508,7 +508,7 @@ msgstr "" ...@@ -508,7 +508,7 @@ msgstr ""
#: apps/publisher/emails.py #: apps/publisher/emails.py
#, python-brace-format #, python-brace-format
msgid "Preview for {run_name} is available" msgid "Review requested: Preview for {course_name} {run_number}"
msgstr "" msgstr ""
#: apps/publisher/emails.py #: apps/publisher/emails.py
...@@ -2422,8 +2422,6 @@ msgstr "" ...@@ -2422,8 +2422,6 @@ msgstr ""
#: templates/publisher/email/comment.txt #: templates/publisher/email/comment.txt
#: templates/publisher/email/course_created.html #: templates/publisher/email/course_created.html
#: templates/publisher/email/course_created.txt #: templates/publisher/email/course_created.txt
#: templates/publisher/email/course_run/preview_available.html
#: templates/publisher/email/course_run/preview_available.txt
#: templates/publisher/email/decline_preview.html #: templates/publisher/email/decline_preview.html
#: templates/publisher/email/decline_preview.txt #: templates/publisher/email/decline_preview.txt
msgid "The edX team" msgid "The edX team"
...@@ -2457,6 +2455,8 @@ msgstr "" ...@@ -2457,6 +2455,8 @@ msgstr ""
#: templates/publisher/email/course/send_for_review.txt #: templates/publisher/email/course/send_for_review.txt
#: templates/publisher/email/course_run/mark_as_reviewed.html #: templates/publisher/email/course_run/mark_as_reviewed.html
#: templates/publisher/email/course_run/mark_as_reviewed.txt #: templates/publisher/email/course_run/mark_as_reviewed.txt
#: templates/publisher/email/course_run/preview_available.html
#: templates/publisher/email/course_run/preview_available.txt
#: templates/publisher/email/course_run/published.html #: templates/publisher/email/course_run/published.html
#: templates/publisher/email/course_run/published.txt #: templates/publisher/email/course_run/published.txt
#: templates/publisher/email/course_run/send_for_review.html #: templates/publisher/email/course_run/send_for_review.html
...@@ -2618,20 +2618,20 @@ msgid "" ...@@ -2618,20 +2618,20 @@ msgid ""
msgstr "" msgstr ""
#: templates/publisher/email/course_run/preview_available.html #: templates/publisher/email/course_run/preview_available.html
#: templates/publisher/email/course_run/preview_available.txt
msgid "Dear member,"
msgstr ""
#: templates/publisher/email/course_run/preview_available.html
#, python-format #, python-format
msgid "" msgid ""
"Preview for %(link_start)s%(page_url)s%(link_middle)s %(course_name)s " "A preview is now available for the %(link_start)s%(page_url)s%(link_middle)s"
"%(link_end)s is available for review." " %(course_run_number)s course run %(link_end)s of %(course_name)s. Visit "
"%(link_start)s%(preview_link)s%(link_middle)s link to preview %(link_end)s "
"to approve or decline the preview for this course run."
msgstr "" msgstr ""
#: templates/publisher/email/course_run/preview_available.txt #: templates/publisher/email/course_run/preview_available.txt
#, python-format #, python-format
msgid "Preview for %(course_name)s is available for review. %(page_url)s" msgid ""
"A preview is now available for the %(course_run_number)s course run of "
"%(course_name)s. Visit %(page_url)s to approve or decline the preview for "
"this course run."
msgstr "" msgstr ""
#: templates/publisher/email/course_run/published.html #: templates/publisher/email/course_run/published.html
......
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-07 15:35+0500\n" "POT-Creation-Date: 2017-03-07 18:14+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
#: static/js/catalogs-change-form.js #: static/js/catalogs-change-form.js
msgid "Preview" msgid "Preview"
......
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-07 15:35+0500\n" "POT-Creation-Date: 2017-03-07 18:14+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: apps/api/filters.py #: apps/api/filters.py
...@@ -629,9 +629,10 @@ msgstr "" ...@@ -629,9 +629,10 @@ msgstr ""
#: apps/publisher/emails.py #: apps/publisher/emails.py
#, python-brace-format #, python-brace-format
msgid "Preview for {run_name} is available" msgid "Review requested: Preview for {course_name} {run_number}"
msgstr "" msgstr ""
"Prévïéw för {run_name} ïs äväïläßlé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢#" "Révïéw réqüéstéd: Prévïéw för {course_name} {run_number} Ⱡ'σяєм ιρѕυм ∂σłσя "
"ѕιт αмєт, ¢σηѕє¢тєтυ#"
#: apps/publisher/emails.py #: apps/publisher/emails.py
#, python-brace-format #, python-brace-format
...@@ -2844,8 +2845,6 @@ msgstr "Vïéw Çöürsé Ⱡ'σяєм ιρѕυм ∂σłσя #" ...@@ -2844,8 +2845,6 @@ msgstr "Vïéw Çöürsé Ⱡ'σяєм ιρѕυм ∂σłσя #"
#: templates/publisher/email/comment.txt #: templates/publisher/email/comment.txt
#: templates/publisher/email/course_created.html #: templates/publisher/email/course_created.html
#: templates/publisher/email/course_created.txt #: templates/publisher/email/course_created.txt
#: templates/publisher/email/course_run/preview_available.html
#: templates/publisher/email/course_run/preview_available.txt
#: templates/publisher/email/decline_preview.html #: templates/publisher/email/decline_preview.html
#: templates/publisher/email/decline_preview.txt #: templates/publisher/email/decline_preview.txt
msgid "The edX team" msgid "The edX team"
...@@ -2881,6 +2880,8 @@ msgstr "Vïéw çömmént: Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#" ...@@ -2881,6 +2880,8 @@ msgstr "Vïéw çömmént: Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
#: templates/publisher/email/course/send_for_review.txt #: templates/publisher/email/course/send_for_review.txt
#: templates/publisher/email/course_run/mark_as_reviewed.html #: templates/publisher/email/course_run/mark_as_reviewed.html
#: templates/publisher/email/course_run/mark_as_reviewed.txt #: templates/publisher/email/course_run/mark_as_reviewed.txt
#: templates/publisher/email/course_run/preview_available.html
#: templates/publisher/email/course_run/preview_available.txt
#: templates/publisher/email/course_run/published.html #: templates/publisher/email/course_run/published.html
#: templates/publisher/email/course_run/published.txt #: templates/publisher/email/course_run/published.txt
#: templates/publisher/email/course_run/send_for_review.html #: templates/publisher/email/course_run/send_for_review.html
...@@ -3084,26 +3085,34 @@ msgstr "" ...@@ -3084,26 +3085,34 @@ msgstr ""
" för püßlïçätïön. Ⱡ'σяєм ιρѕυм ∂σ#" " för püßlïçätïön. Ⱡ'σяєм ιρѕυм ∂σ#"
#: templates/publisher/email/course_run/preview_available.html #: templates/publisher/email/course_run/preview_available.html
#: templates/publisher/email/course_run/preview_available.txt
msgid "Dear member,"
msgstr "Déär mémßér, Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
#: templates/publisher/email/course_run/preview_available.html
#, python-format #, python-format
msgid "" msgid ""
"Preview for %(link_start)s%(page_url)s%(link_middle)s %(course_name)s " "A preview is now available for the %(link_start)s%(page_url)s%(link_middle)s"
"%(link_end)s is available for review." " %(course_run_number)s course run %(link_end)s of %(course_name)s. Visit "
"%(link_start)s%(preview_link)s%(link_middle)s link to preview %(link_end)s "
"to approve or decline the preview for this course run."
msgstr "" msgstr ""
"Prévïéw för %(link_start)s%(page_url)s%(link_middle)s %(course_name)s " "À prévïéw ïs nöw äväïläßlé för thé %(link_start)s%(page_url)s%(link_middle)s"
"%(link_end)s ïs äväïläßlé för révïéw. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, " " %(course_run_number)s çöürsé rün %(link_end)s öf %(course_name)s. Vïsït "
"¢σηѕє¢тєтυя α#" "%(link_start)s%(preview_link)s%(link_middle)s lïnk tö prévïéw %(link_end)s "
"tö äpprövé ör déçlïné thé prévïéw för thïs çöürsé rün. Ⱡ'σяєм ιρѕυм ∂σłσя "
"ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя ιη¢ι∂ι∂υηт υт "
"łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ ησѕтяυ∂ "
"єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ ¢σηѕєqυαт. ∂υιѕ "
"αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє ¢ιłłυм ∂σłσяє єυ "
"ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт ηση ρяσι∂єηт, ѕυηт "
"ιη ¢υłρα qυι σƒƒι¢ια ∂єѕ#"
#: templates/publisher/email/course_run/preview_available.txt #: templates/publisher/email/course_run/preview_available.txt
#, python-format #, python-format
msgid "Preview for %(course_name)s is available for review. %(page_url)s" msgid ""
"A preview is now available for the %(course_run_number)s course run of "
"%(course_name)s. Visit %(page_url)s to approve or decline the preview for "
"this course run."
msgstr "" msgstr ""
"Prévïéw för %(course_name)s ïs äväïläßlé för révïéw. %(page_url)s Ⱡ'σяєм " "À prévïéw ïs nöw äväïläßlé för thé %(course_run_number)s çöürsé rün öf "
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя #" "%(course_name)s. Vïsït %(page_url)s tö äpprövé ör déçlïné thé prévïéw för "
"thïs çöürsé rün. Ⱡ'σяєм ιρѕ#"
#: templates/publisher/email/course_run/published.html #: templates/publisher/email/course_run/published.html
#, python-format #, python-format
......
...@@ -7,14 +7,14 @@ msgid "" ...@@ -7,14 +7,14 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-07 15:35+0500\n" "POT-Creation-Date: 2017-03-07 18:14+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/js/catalogs-change-form.js #: static/js/catalogs-change-form.js
......
...@@ -4,17 +4,17 @@ ...@@ -4,17 +4,17 @@
<!-- Message Body --> <!-- Message Body -->
<p> <p>
{% blocktrans trimmed %} {% blocktrans trimmed %}
Dear member, Dear {{ recipient_name }},
{% endblocktrans %} {% endblocktrans %}
<p> <p>
{% blocktrans with link_start='<a href="' link_middle='">' link_end='</a>' trimmed %} {% blocktrans with link_start='<a href="' link_middle='">' link_end='</a>' trimmed %}
Preview for {{ link_start }}{{ page_url }}{{ link_middle }} {{ course_name }} {{ link_end }} is available for review. A preview is now available for the {{ link_start }}{{ page_url }}{{ link_middle }} {{ course_run_number }} course run {{ link_end }} of {{ course_name }}. Visit {{ link_start }}{{ preview_link }}{{ link_middle }} link to preview {{ link_end }} to approve or decline the preview for this course run.
{% endblocktrans %} {% endblocktrans %}
</p> </p>
{% comment %}Translators: It's closing of mail.{% endcomment %} {% comment %}Translators: It's closing of mail.{% endcomment %}
{% trans "Thanks," %}<br> {% trans "Thanks," %}<br>
{% trans "The edX team" %} {{ platform_name }} {{ sender_role }}
{% blocktrans trimmed %} {% blocktrans trimmed %}
......
{% load i18n %} {% load i18n %}
{% blocktrans trimmed %} {% blocktrans trimmed %}
Dear member, Dear {{ recipient_name }},
{% endblocktrans %} {% endblocktrans %}
{% blocktrans trimmed %} {% blocktrans trimmed %}
Preview for {{ course_name }} is available for review. {{ page_url }} A preview is now available for the {{ course_run_number }} course run of {{ course_name }}. Visit {{ page_url }} to approve or decline the preview for this course run.
{% endblocktrans %} {% endblocktrans %}
{% trans "Thanks," %} {% trans "Thanks," %}
{% trans "The edX team" %} {{ platform_name }} {{ sender_role }}
{% blocktrans trimmed %} {% blocktrans trimmed %}
Note: This email address is unable to receive replies. For questions or comments, contact {{ contact_us_email }}. Note: This email address is unable to receive replies. For questions or comments, contact {{ contact_us_email }}.
......
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