diff --git a/course_metadata/apps.py b/course_metadata/apps.py index 26b3ee4..1e24164 100644 --- a/course_metadata/apps.py +++ b/course_metadata/apps.py @@ -8,8 +8,3 @@ class SolutionsAppCourseMetadataConfig(AppConfig): name = 'course_metadata' verbose_name = 'Course meta data' - - def ready(self): - - # import signal handlers - import course_metadata.signals # pylint: disable=unused-import diff --git a/course_metadata/signals.py b/course_metadata/signals.py deleted file mode 100644 index 107778f..0000000 --- a/course_metadata/signals.py +++ /dev/null @@ -1,18 +0,0 @@ -""" -This module has definition of receivers for signals -""" -from django.dispatch.dispatcher import receiver - -from xmodule.modulestore.django import SignalHandler - -from .tasks import update_course_aggregate_metadata - - -@receiver(SignalHandler.course_published, dispatch_uid='course_metadata') -def course_publish_handler_in_course_metadata(sender, course_key, **kwargs): # pylint: disable=unused-argument - """ - Receives signal and kicks off celery task to update course aggregate metadata - """ - # Note: The countdown=0 kwarg is set to to ensure the method below does not attempt to access the course - # before the signal emitter has finished all operations. This is also necessary to ensure all tests pass. - update_course_aggregate_metadata.apply_async([unicode(course_key)], countdown=0) diff --git a/course_metadata/tasks.py b/course_metadata/tasks.py deleted file mode 100644 index ea479b9..0000000 --- a/course_metadata/tasks.py +++ /dev/null @@ -1,34 +0,0 @@ -""" -This module has implementation of celery tasks to compute course aggregate metadata -""" - -import logging - -from celery.task import task -from opaque_keys.edx.keys import CourseKey - -from .models import CourseAggregatedMetaData -from .utils import get_course_leaf_nodes - -log = logging.getLogger('edx.celery.task') - - -@task(name=u'course_metadata.tasks.update_course_aggregate_metadata') -def update_course_aggregate_metadata(course_key): # pylint: disable=invalid-name - """ - Regenerates and updates the course aggregate metadata (in the database) for the specified course. - """ - if not isinstance(course_key, basestring): - raise ValueError('course_key must be a string. {} is not acceptable.'.format(type(course_key))) - - course_key = CourseKey.from_string(course_key) - - try: - course_leaf_nodes = get_course_leaf_nodes(course_key) - except Exception as ex: - log.exception('An error occurred while retrieving course assessments: %s', ex.message) - raise - - course_metadata, __ = CourseAggregatedMetaData.objects.get_or_create(id=course_key) - course_metadata.total_assessments = len(course_leaf_nodes) - course_metadata.save() diff --git a/course_metadata/tests/tests.py b/course_metadata/tests/tests.py index b59ac37..7385d17 100644 --- a/course_metadata/tests/tests.py +++ b/course_metadata/tests/tests.py @@ -8,7 +8,6 @@ from xmodule.modulestore.django import SignalHandler from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from course_metadata.signals import course_publish_handler_in_course_metadata from course_metadata.models import CourseAggregatedMetaData from xmodule.modulestore.tests.django_utils import ( @@ -52,27 +51,6 @@ def setUp(self): display_name="Html component" ) - def test_course_aggregate_metadata_update_on_course_published(self): - """ - Test course aggregate metadata update receiver is called on course_published signal - and CourseAggregatedMetaData is updated - """ - with mock_signal_receiver(SignalHandler.course_published, - wraps=course_publish_handler_in_course_metadata) as receiver: - self.assertEqual(receiver.call_count, 0) - - # adding new video unit to course should fire the signal - ItemFactory.create( - category="video", - parent_location=self.unit.location, - data=self.test_data, - display_name="Video to test aggregates" - ) - - self.assertEqual(receiver.call_count, 1) - total_assessments = CourseAggregatedMetaData.objects.get(id=self.course.id).total_assessments - self.assertEqual(total_assessments, 2) - def test_get_course_aggregate_metadata_by_course_key(self): """ Test course aggregate metadata should compute and return metadata diff --git a/course_metadata/utils.py b/course_metadata/utils.py index 6b68043..d218147 100644 --- a/course_metadata/utils.py +++ b/course_metadata/utils.py @@ -5,39 +5,17 @@ from django.db.models import Q from xmodule.modulestore.django import modulestore -from progress.models import StudentProgress, CourseModuleCompletion from student.models import CourseEnrollment -def remove_orphans_and_recalculate_progress(course_key, detached_categories): +def remove_orphans(course_key, detached_categories): from contentstore.views.item import _delete_orphans from xmodule.modulestore import ModuleStoreEnum - from progress.signals import is_valid_progress_module _delete_orphans( course_key, ModuleStoreEnum.UserID.mgmt_command, True ) - users = CourseEnrollment.objects.users_enrolled_in(course_key) - - detached_categories_list = [Q(content_id__contains=item.strip()) for item in detached_categories] - detached_categories_list = reduce(lambda a, b: a | b, detached_categories_list) - - for user in users: - completions = CourseModuleCompletion.objects.filter(course_id=course_key, user_id=user.id)\ - .exclude(detached_categories_list).values_list('content_id', flat=True).distinct() - - num_completions = sum([is_valid_progress_module(content_id=content_id) for content_id in completions]) - try: - progress_record = StudentProgress.objects.get(user=user, course_id=course_key) - - if progress_record.completions != num_completions: - progress_record.completions = num_completions - progress_record.save() - - except StudentProgress.DoesNotExist: - pass - def get_course_leaf_nodes(course_key): """ @@ -48,7 +26,7 @@ def get_course_leaf_nodes(course_key): store = modulestore() orphans = store.get_orphans(course_key) if orphans: - remove_orphans_and_recalculate_progress(course_key, detached_categories) + remove_orphans(course_key, detached_categories) verticals = store.get_items(course_key, qualifiers={'category': 'vertical'}) for vertical in verticals: if hasattr(vertical, 'children') and not is_progress_detached_vertical(vertical) and \ diff --git a/setup.py b/setup.py index 260f58c..2d06eeb 100755 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ setup( name='course-edx-platform-extensions', - version='1.1.1', + version='2.0.0', description='Course metadata management extension for edX platform', long_description=open('README.rst').read(), author='edX',