def listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=unused-argument """ Receives publishing signal and performs publishing related workflows, such as registering proctored exams, building up credit requirements, and performing search indexing """ # import here, because signal is registered at startup, but items in tasks are not yet able to be loaded from cms.djangoapps.contentstore.tasks import ( update_outline_from_modulestore_task, update_search_index, update_special_exams_and_publish ) # register special exams asynchronously course_key_str = str(course_key) update_special_exams_and_publish.delay(course_key_str) if key_supports_outlines(course_key): # Push the course outline to learning_sequences asynchronously. update_outline_from_modulestore_task.delay(course_key_str) # Finally call into the course search subsystem # to kick off an indexing action if CoursewareSearchIndexer.indexing_is_enabled() and CourseAboutSearchIndexer.indexing_is_enabled(): update_search_index.delay(course_key_str, datetime.now(UTC).isoformat())
def listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable=unused-argument """ Receives publishing signal and performs publishing related workflows, such as registering proctored exams, building up credit requirements, and performing search indexing """ # first is to registered exams, the credit subsystem will assume that # all proctored exams have already been registered, so we have to do that first try: register_special_exams(course_key) # pylint: disable=broad-except except Exception as exception: log.exception(exception) # then call into the credit subsystem (in /openedx/djangoapps/credit) # to perform any 'on_publish' workflow on_course_publish(course_key) # import here, because signal is registered at startup, but items in tasks are not yet able to be loaded from cms.djangoapps.contentstore.tasks import update_outline_from_modulestore_task, update_search_index if key_supports_outlines(course_key): update_outline_from_modulestore_task.delay(str(course_key)) # Finally call into the course search subsystem # to kick off an indexing action if CoursewareSearchIndexer.indexing_is_enabled( ) and CourseAboutSearchIndexer.indexing_is_enabled(): update_search_index.delay(str(course_key), datetime.now(UTC).isoformat())
def handle(self, *args, **options): dry_run = options.get('dry', False) force_all = options.get('force', False) log.info("Starting backfill_course_outlines: dry=%s, force=%s", dry_run, force_all) all_course_keys_qs = CourseOverview.objects.values_list('id', flat=True) if force_all: target_courses_qs = all_course_keys_qs log.info("Forcing re-generation for all %d course runs.", len(target_courses_qs)) else: # .difference() is not supported in MySQL, but this at least does the # SELECT NOT IN... subquery in the database rather than Python. target_courses_qs = all_course_keys_qs.exclude( id__in=get_course_keys_with_outlines()) log.info("Found %d courses without outlines.", len(target_courses_qs)) for course_key in target_courses_qs: if key_supports_outlines(course_key): log.info("Queuing outline creation for %s", course_key) if not dry_run: update_outline_from_modulestore_task.delay(str(course_key)) else: log.info("Outlines not supported for %s - skipping", course_key)
def update_outline_from_modulestore_task(course_key_str): """ Celery task that creates a learning_sequence course outline. """ try: course_key = CourseKey.from_string(course_key_str) if not key_supports_outlines(course_key): LOGGER.warning( ("update_outline_from_modulestore_task called for course key" " %s, which does not support learning_sequence outlines."), course_key_str) return update_outline_from_modulestore(course_key) except Exception: # pylint disable=broad-except LOGGER.exception("Could not create course outline for course %s", course_key_str) raise # Re-raise so that errors are noted in reporting.
def regenerate_course_outlines_subset(modeladmin, request, queryset): """ Create a celery task to regenerate a single course outline for each passed-in course key. If the number of passed-in course keys is above a threshold, then instead create a celery task which will then create a celery task to regenerate a single course outline for each passed-in course key. """ all_course_keys_qs = queryset.values_list('id', flat=True) # Create a separate celery task for each course outline requested. regenerates = 0 for course_key in all_course_keys_qs: if key_supports_outlines(course_key): log.info("Queuing outline creation for %s", course_key) update_outline_from_modulestore_task.delay(str(course_key)) regenerates += 1 else: log.info("Outlines not supported for %s - skipping", course_key) msg = _( "Number of course outline regenerations successfully requested: {regenerates}" ).format(regenerates=regenerates) modeladmin.message_user(request, msg)
def handle(self, *args, **options): dry_run = options.get('dry', False) log.info("Starting backfill_course_outlines{}".format( " (dry run)" if dry_run else "")) all_course_keys_qs = CourseOverview.objects.values_list('id', flat=True) # .difference() is not supported in MySQL, but this at least does the # SELECT NOT IN... subquery in the database rather than Python. missing_outlines_qs = all_course_keys_qs.exclude( id__in=get_course_keys_with_outlines()) num_courses_needing_outlines = len(missing_outlines_qs) log.info("Found %d courses without outlines. Queuing tasks...", num_courses_needing_outlines) for course_key in missing_outlines_qs: if key_supports_outlines(course_key): log.info("Queuing outline creation for %s", course_key) if not dry_run: update_outline_from_modulestore_task.delay(str(course_key)) else: log.info("Outlines not supported for %s - skipping", course_key)
def update_all_outlines_from_modulestore_task(): """ Celery task that creates multiple celery tasks - one per learning_sequence course outline to regenerate. The list of course keys to regenerate comes from the proxy model itself. """ course_key_list = [ str(course_key) for course_key in CourseOutlineRegenerate.get_course_outline_ids() ] for course_key_str in course_key_list: try: course_key = CourseKey.from_string(course_key_str) if not key_supports_outlines(course_key): LOGGER.warning(( "update_multiple_outlines_from_modulestore_task called for course key" " %s, which does not support learning_sequence outlines."), course_key_str) continue update_outline_from_modulestore_task.delay(course_key_str) except Exception: # pylint: disable=broad-except # Swallow the exception to continue the loop through course keys - but log it. LOGGER.exception("Could not create course outline for course %s", course_key_str)