diff --git a/lms/djangoapps/course_api/blocks/api.py b/lms/djangoapps/course_api/blocks/api.py index 1befdb2def31c30cc623640765f5b5b477890964..07c62fc41df724f37e7337988341aac874e1874d 100644 --- a/lms/djangoapps/course_api/blocks/api.py +++ b/lms/djangoapps/course_api/blocks/api.py @@ -72,6 +72,7 @@ def get_blocks( if requested_fields is None: requested_fields = [] include_completion = 'completion' in requested_fields + include_has_scheduled_content = 'has_scheduled_content' in requested_fields include_special_exams = 'special_exam_info' in requested_fields include_gated_sections = 'show_gated_sections' in requested_fields @@ -106,7 +107,12 @@ def get_blocks( # transform blocks = course_blocks_api.get_course_blocks( - user, usage_key, transformers, allow_start_dates_in_future=allow_start_dates_in_future) + user, + usage_key, + transformers, + allow_start_dates_in_future=allow_start_dates_in_future, + include_has_scheduled_content=include_has_scheduled_content + ) # filter blocks by types if block_types_filter: diff --git a/lms/djangoapps/course_api/blocks/serializers.py b/lms/djangoapps/course_api/blocks/serializers.py index d8361fa81f634b992352377d64e16e7b94afbb27..ce570f28a105d9ddd0df4c0ec9a6f36567199e4c 100644 --- a/lms/djangoapps/course_api/blocks/serializers.py +++ b/lms/djangoapps/course_api/blocks/serializers.py @@ -52,6 +52,7 @@ SUPPORTED_FIELDS = [ SupportedFieldType('due'), SupportedFieldType('contains_gated_content'), SupportedFieldType('has_score'), + SupportedFieldType('has_scheduled_content'), SupportedFieldType('weight'), SupportedFieldType('show_correctness'), # 'student_view_data' diff --git a/lms/djangoapps/course_blocks/api.py b/lms/djangoapps/course_blocks/api.py index a8eb5bf0e55cb8bb8cd1b5bb876023de4bd8edf6..c978f54e02d5f63a80bd98b5659bcc3c2f2cd127 100644 --- a/lms/djangoapps/course_blocks/api.py +++ b/lms/djangoapps/course_blocks/api.py @@ -61,6 +61,7 @@ def get_course_blocks( collected_block_structure=None, allow_start_dates_in_future=False, include_completion=False, + include_has_scheduled_content=False, ): """ A higher order function implemented on top of the @@ -96,7 +97,12 @@ def get_course_blocks( transformers = BlockStructureTransformers(get_course_block_access_transformers(user)) if include_completion: transformers += [BlockCompletionTransformer()] - transformers.usage_info = CourseUsageInfo(starting_block_usage_key.course_key, user, allow_start_dates_in_future) + transformers.usage_info = CourseUsageInfo( + starting_block_usage_key.course_key, + user, + allow_start_dates_in_future, + include_has_scheduled_content + ) return get_block_structure_manager(starting_block_usage_key.course_key).get_transformed( transformers, diff --git a/lms/djangoapps/course_blocks/transformers/start_date.py b/lms/djangoapps/course_blocks/transformers/start_date.py index 900a8b74c0dd2357b966f0cea36b859901d150b5..5edde343b75c345c6c1435dcb51c9028a2c74b92 100644 --- a/lms/djangoapps/course_blocks/transformers/start_date.py +++ b/lms/djangoapps/course_blocks/transformers/start_date.py @@ -43,6 +43,23 @@ class StartDateTransformer(FilteringTransformerMixin, BlockStructureTransformer) """ return "start_date" + @classmethod + def _check_has_scheduled_content(cls, block_structure, scheduled_content_condition): + ''' + Returns a block structure where the root course block has been + updated to include a has_scheduled_content field (True if the course + has any blocks with release dates in the future, False otherwise). + ''' + has_scheduled_content = False + for block_key in block_structure.topological_traversal(): + if scheduled_content_condition(block_key): + has_scheduled_content = True + break + + block_structure.override_xblock_field( + block_structure.root_block_usage_key, 'has_scheduled_content', has_scheduled_content + ) + @classmethod def _get_merged_start_date(cls, block_structure, block_key): """ @@ -85,4 +102,8 @@ class StartDateTransformer(FilteringTransformerMixin, BlockStructureTransformer) usage_info.course_key, now=now, ) + + if usage_info.include_has_scheduled_content: + self._check_has_scheduled_content(block_structure, removal_condition) + return [block_structure.create_removal_filter(removal_condition)] diff --git a/lms/djangoapps/course_blocks/usage_info.py b/lms/djangoapps/course_blocks/usage_info.py index 457fc00f0abd5cb781549185d2cd6b0706cf4615..7e9e678ce3c18f7dc80aaeb02046191b4c49b692 100644 --- a/lms/djangoapps/course_blocks/usage_info.py +++ b/lms/djangoapps/course_blocks/usage_info.py @@ -14,7 +14,7 @@ class CourseUsageInfo(object): an instance of it in calls to BlockStructureTransformer.transform methods. ''' - def __init__(self, course_key, user, allow_start_dates_in_future=False): + def __init__(self, course_key, user, allow_start_dates_in_future=False, include_has_scheduled_content=False): # Course identifier (opaque_keys.edx.keys.CourseKey) self.course_key = course_key @@ -27,6 +27,11 @@ class CourseUsageInfo(object): # assignments that have not yet been released. self.allow_start_dates_in_future = allow_start_dates_in_future + # This value is used within the StartDateTransformer in the case where we + # would like to know whether there are future start dates, while still + # filtering the blocks with start dates in the future. + self.include_has_scheduled_content = include_has_scheduled_content + # Cached value of whether the user has staff access (bool/None) self._has_staff_access = None