reset self-generation of certs according to course pacing
This commit is contained in:
@@ -54,7 +54,6 @@ from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models, transaction
|
||||
from django.db.utils import IntegrityError
|
||||
from django.db.models import Count
|
||||
from django.dispatch import receiver
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
@@ -891,17 +890,10 @@ class CertificateGenerationCourseSetting(TimeStampedModel):
|
||||
is_enabled (boolean): Whether to enable or disable self-generated certificates.
|
||||
|
||||
"""
|
||||
certificate_generation_course_setting = CertificateGenerationCourseSetting(course_key=course_key,
|
||||
enabled=is_enabled)
|
||||
try:
|
||||
with transaction.atomic():
|
||||
certificate_generation_course_setting.save()
|
||||
except IntegrityError:
|
||||
if is_enabled:
|
||||
LOGGER.exception("Cannot enable self-generated certificates for course %s.", unicode(course_key))
|
||||
else:
|
||||
LOGGER.exception("Cannot disable self-generated certificates for course %s.", unicode(course_key))
|
||||
pass
|
||||
CertificateGenerationCourseSetting.objects.create(
|
||||
course_key=course_key,
|
||||
enabled=is_enabled
|
||||
)
|
||||
|
||||
|
||||
class CertificateGenerationConfiguration(ConfigurationModel):
|
||||
|
||||
@@ -2,26 +2,24 @@
|
||||
Signal handler for enabling/disabling self-generated certificates based on the course-pacing.
|
||||
"""
|
||||
from celery.task import task
|
||||
from django.dispatch.dispatcher import receiver
|
||||
from django.dispatch import receiver
|
||||
|
||||
from certificates.models import CertificateGenerationCourseSetting
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview, COURSE_OVERVIEW_UPDATED
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from openedx.core.djangoapps.models.course_details import COURSE_PACING_CHANGE
|
||||
|
||||
|
||||
@receiver(COURSE_OVERVIEW_UPDATED)
|
||||
def _listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=unused-argument
|
||||
""" Catches the signal that a course overview table has been updated in database and
|
||||
enable/disable the self-generated certificates according to course-pacing.
|
||||
@receiver(COURSE_PACING_CHANGE, dispatch_uid="course_pacing_changed")
|
||||
def _listen_for_course_publish(sender, course_key, course_self_paced, **kwargs): # pylint: disable=unused-argument
|
||||
"""
|
||||
set_self_generated_certs.delay(unicode(course_key))
|
||||
Catches the signal that course pacing has changed and enable/disable
|
||||
the self-generated certificates according to course-pacing.
|
||||
"""
|
||||
enable_self_generated_certs.delay(course_key, course_self_paced)
|
||||
|
||||
|
||||
@task()
|
||||
def set_self_generated_certs(course_key):
|
||||
def enable_self_generated_certs(course_key, course_self_paced):
|
||||
"""
|
||||
Enable or disable self-generated certificates for a course according to pacing.
|
||||
"""
|
||||
course_key = CourseKey.from_string(course_key)
|
||||
course = CourseOverview.get_from_id(course_key)
|
||||
CertificateGenerationCourseSetting.set_enabled_for_course(course_key, course.self_paced)
|
||||
CertificateGenerationCourseSetting.set_enabled_for_course(course_key, course_self_paced)
|
||||
|
||||
@@ -29,7 +29,7 @@ class SelfGeneratedCertsSignalTest(ModuleStoreTestCase):
|
||||
"""
|
||||
self.assertFalse(certs_api.cert_generation_enabled(self.course.id))
|
||||
|
||||
_listen_for_course_publish('store', self.course.id)
|
||||
_listen_for_course_publish('store', self.course.id, self.course.self_paced)
|
||||
self.assertTrue(certs_api.cert_generation_enabled(self.course.id))
|
||||
|
||||
def test_cert_generation_disabled_for_instructor_paced(self):
|
||||
@@ -40,5 +40,5 @@ class SelfGeneratedCertsSignalTest(ModuleStoreTestCase):
|
||||
self.course.self_paced = False
|
||||
self.store.update_item(self.course, self.user.id)
|
||||
|
||||
_listen_for_course_publish('store', self.course.id)
|
||||
_listen_for_course_publish('store', self.course.id, self.course.self_paced)
|
||||
self.assertFalse(certs_api.cert_generation_enabled(self.course.id))
|
||||
|
||||
@@ -10,7 +10,6 @@ from django.db import models, transaction
|
||||
from django.db.models.fields import BooleanField, DateTimeField, DecimalField, TextField, FloatField, IntegerField
|
||||
from django.db.utils import IntegrityError
|
||||
from django.template import defaultfilters
|
||||
from django.dispatch import Signal
|
||||
|
||||
from ccx_keys.locator import CCXLocator
|
||||
from model_utils.models import TimeStampedModel
|
||||
@@ -26,7 +25,6 @@ from xmodule.error_module import ErrorDescriptor
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from openedx.core.djangoapps.xmodule_django.models import CourseKeyField, UsageKeyField
|
||||
|
||||
COURSE_OVERVIEW_UPDATED = Signal(providing_args=["course_key"])
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -647,12 +645,6 @@ class CourseOverview(TimeStampedModel):
|
||||
"""Represent ourselves with the course key."""
|
||||
return unicode(self.id)
|
||||
|
||||
def send_signal(self):
|
||||
"""
|
||||
Sends out the signal that course_overview table has been updated.
|
||||
"""
|
||||
COURSE_OVERVIEW_UPDATED.send(sender=None, course_key=self.id)
|
||||
|
||||
|
||||
class CourseOverviewTab(models.Model):
|
||||
"""
|
||||
|
||||
@@ -11,11 +11,9 @@ from xmodule.modulestore.django import SignalHandler
|
||||
def _listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=unused-argument
|
||||
"""
|
||||
Catches the signal that a course has been published in Studio and
|
||||
updates the corresponding CourseOverview cache entry. Also sends out
|
||||
the signal that course_overview table has been updated.
|
||||
updates the corresponding CourseOverview cache entry.
|
||||
"""
|
||||
course_overview = CourseOverview.load_from_module_store(course_key)
|
||||
course_overview.send_signal()
|
||||
CourseOverview.load_from_module_store(course_key)
|
||||
|
||||
|
||||
@receiver(SignalHandler.course_deleted)
|
||||
|
||||
@@ -5,6 +5,7 @@ import re
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.dispatch import Signal
|
||||
|
||||
from xmodule.fields import Date
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
@@ -12,6 +13,8 @@ from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
|
||||
from openedx.core.lib.courses import course_image_url
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
COURSE_PACING_CHANGE = Signal(providing_args=["course_key", "course_self_paced"])
|
||||
|
||||
|
||||
# This list represents the attribute keys for a course's 'about' info.
|
||||
# Note: The 'video' attribute is intentionally excluded as it must be
|
||||
@@ -188,6 +191,7 @@ class CourseDetails(object):
|
||||
descriptor = module_store.get_course(course_key)
|
||||
|
||||
dirty = False
|
||||
is_pacing_changed = False
|
||||
|
||||
# In the descriptor's setter, the date is converted to JSON
|
||||
# using Date's to_json method. Calling to_json on something that
|
||||
@@ -271,6 +275,7 @@ class CourseDetails(object):
|
||||
and jsondict['self_paced'] != descriptor.self_paced):
|
||||
descriptor.self_paced = jsondict['self_paced']
|
||||
dirty = True
|
||||
is_pacing_changed = True
|
||||
|
||||
if dirty:
|
||||
module_store.update_item(descriptor, user.id)
|
||||
@@ -285,6 +290,10 @@ class CourseDetails(object):
|
||||
|
||||
cls.update_about_video(descriptor, jsondict['intro_video'], user.id)
|
||||
|
||||
if is_pacing_changed:
|
||||
# sends out the signal that course pacing has changed
|
||||
COURSE_PACING_CHANGE.send(sender=None, course_key=course_key, course_self_paced=descriptor.self_paced)
|
||||
|
||||
# Could just return jsondict w/o doing any db reads, but I put
|
||||
# the reads in as a means to confirm it persisted correctly
|
||||
return CourseDetails.fetch(course_key)
|
||||
|
||||
Reference in New Issue
Block a user