def get(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) course_usage_key = modulestore().make_course_usage_key(course_key) # Enable NR tracing for this view based on course monitoring_utils.set_custom_metric('course_id', course_key_string) monitoring_utils.set_custom_metric('user_id', request.user.id) monitoring_utils.set_custom_metric('is_staff', request.user.is_staff) course_tools = CourseToolsPluginManager.get_enabled_course_tools(request, course_key) transformers = BlockStructureTransformers() transformers += course_blocks_api.get_course_block_access_transformers(request.user) transformers += [ BlocksAPITransformer(None, None, depth=3), ] course_blocks = get_course_blocks(request.user, course_usage_key, transformers, include_completion=True) data = { 'course_tools': course_tools, 'course_blocks': course_blocks, } context = self.get_serializer_context() context['course_key'] = course_key serializer = self.get_serializer_class()(data, context=context) return Response(serializer.data)
def get(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) course_usage_key = modulestore().make_course_usage_key(course_key) # Enable NR tracing for this view based on course monitoring_utils.set_custom_metric('course_id', course_key_string) monitoring_utils.set_custom_metric('user_id', request.user.id) monitoring_utils.set_custom_metric('is_staff', request.user.is_staff) _, request.user = setup_masquerade(request, course_key, staff_access=has_access( request.user, 'staff', course_key), reset_masquerade_data=True) user_timezone_locale = user_timezone_locale_prefs(request) user_timezone = user_timezone_locale['user_timezone'] transformers = BlockStructureTransformers() transformers += course_blocks_api.get_course_block_access_transformers( request.user) transformers += [ BlocksAPITransformer(None, None, depth=3), ] course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True) course_blocks = get_course_blocks(request.user, course_usage_key, transformers, include_completion=True) enrollment_mode, _ = CourseEnrollment.enrollment_mode_for_user( request.user, course_key) course_grade = CourseGradeFactory().read(request.user, course) courseware_summary = course_grade.chapter_grades.values() data = { 'course_blocks': course_blocks, 'courseware_summary': courseware_summary, 'enrollment_mode': enrollment_mode, 'user_timezone': user_timezone, } context = self.get_serializer_context() context['staff_access'] = bool( has_access(request.user, 'staff', course)) context['course_key'] = course_key serializer = self.get_serializer_class()(data, context=context) return Response(serializer.data)
def init_course_blocks(user, root_block_key): """ Return a BlockStructure representing the course. Blocks must have the following attributes: .location .block_type """ # pragma: no-cover from lms.djangoapps.course_blocks.api import get_course_block_access_transformers, get_course_blocks # pylint: disable=import-error from openedx.core.djangoapps.content.block_structure.transformers import BlockStructureTransformers # pylint: disable=import-error transformers = BlockStructureTransformers( get_course_block_access_transformers(user) + [AggregatorAnnotationTransformer()]) return get_course_blocks(user, root_block_key, transformers)
def get(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) course_usage_key = modulestore().make_course_usage_key(course_key) # Enable NR tracing for this view based on course monitoring_utils.set_custom_metric('course_id', course_key_string) monitoring_utils.set_custom_metric('user_id', request.user.id) monitoring_utils.set_custom_metric('is_staff', request.user.is_staff) _, request.user = setup_masquerade(request, course_key, staff_access=has_access( request.user, 'staff', course_key), reset_masquerade_data=True) transformers = BlockStructureTransformers() transformers += course_blocks_api.get_course_block_access_transformers( request.user) transformers += [ BlocksAPITransformer(None, None, depth=3), ] get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True) course_blocks = get_course_blocks(request.user, course_usage_key, transformers, include_completion=True) enrollment_mode, _ = CourseEnrollment.enrollment_mode_for_user( request.user, course_key) data = { 'course_blocks': course_blocks, 'enrollment_mode': enrollment_mode, } serializer = self.get_serializer(data) return Response(serializer.data)
def setUp(self): super(TestBlockSerializerBase, self).setUp() self.user = UserFactory.create() blocks_api_transformer = BlocksAPITransformer( block_types_to_count=['video'], requested_student_view_data=['video'], ) self.transformers = BlockStructureTransformers( get_course_block_access_transformers() + [blocks_api_transformer]) self.block_structure = get_course_blocks( self.user, self.course.location, self.transformers, ) self.serializer_context = { 'request': MagicMock(), 'block_structure': self.block_structure, 'requested_fields': ['type'], }
def setUp(self): super(TestBlockSerializerBase, self).setUp() self.user = UserFactory.create() blocks_api_transformer = BlocksAPITransformer( block_types_to_count=['video'], requested_student_view_data=['video'], ) self.transformers = BlockStructureTransformers( get_course_block_access_transformers() + [blocks_api_transformer] ) self.block_structure = get_course_blocks( self.user, self.course.location, self.transformers, ) self.serializer_context = { 'request': MagicMock(), 'block_structure': self.block_structure, 'requested_fields': ['type'], }
def get_blocks( request, usage_key, user=None, depth=None, nav_depth=None, requested_fields=None, block_counts=None, student_view_data=None, return_type='dict', block_types_filter=None, hide_access_denials=False, allow_start_dates_in_future=False, ): """ Return a serialized representation of the course blocks. Arguments: request (HTTPRequest): Used for calling django reverse. usage_key (UsageKey): Identifies the starting block of interest. user (User): Optional user object for whom the blocks are being retrieved. If None, blocks are returned regardless of access checks. depth (integer or None): Identifies the depth of the tree to return starting at the root block. If None, the entire tree starting at the root is returned. nav_depth (integer): Optional parameter that indicates how far deep to traverse into the block hierarchy before bundling all the descendants for navigation. requested_fields (list): Optional list of names of additional fields to return for each block. Supported fields are listed in transformers.SUPPORTED_FIELDS. block_counts (list): Optional list of names of block types for which to return an aggregate count of blocks. student_view_data (list): Optional list of names of block types for which blocks to return their student_view_data. return_type (string): Possible values are 'dict' or 'list'. Indicates the format for returning the blocks. block_types_filter (list): Optional list of block type names used to filter the final result of returned blocks. hide_access_denials (bool): When True, filter out any blocks that were denied access to the user, even if they have access denial messages attached. allow_start_dates_in_future (bool): When True, will allow blocks to be returned that can bypass the StartDateTransformer's filter to show blocks with start dates in the future. """ if HIDE_ACCESS_DENIALS_FLAG.is_enabled(): hide_access_denials = True # create ordered list of transformers, adding BlocksAPITransformer at end. transformers = BlockStructureTransformers() if requested_fields is None: requested_fields = [] include_completion = 'completion' in requested_fields include_effort_estimation = (EffortEstimationTransformer.EFFORT_TIME in requested_fields or EffortEstimationTransformer.EFFORT_ACTIVITIES in requested_fields) include_gated_sections = 'show_gated_sections' in requested_fields include_has_scheduled_content = 'has_scheduled_content' in requested_fields include_special_exams = 'special_exam_info' in requested_fields if user is not None: transformers += course_blocks_api.get_course_block_access_transformers(user) transformers += [ MilestonesAndSpecialExamsTransformer( include_special_exams=include_special_exams, include_gated_sections=include_gated_sections ), HiddenContentTransformer() ] if hide_access_denials: transformers += [AccessDeniedMessageFilterTransformer()] # TODO: Remove this after REVE-52 lands and old-mobile-app traffic falls to < 5% of mobile traffic if is_request_from_mobile_app(request): transformers += [HideEmptyTransformer()] if include_effort_estimation: transformers += [EffortEstimationTransformer()] transformers += [ BlocksAPITransformer( block_counts, student_view_data, depth, nav_depth ) ] # transform blocks = course_blocks_api.get_course_blocks( user, usage_key, transformers, allow_start_dates_in_future=allow_start_dates_in_future, include_completion=include_completion, include_has_scheduled_content=include_has_scheduled_content ) # filter blocks by types if block_types_filter: block_keys_to_remove = [] for block_key in blocks: block_type = blocks.get_xblock_field(block_key, 'category') if block_type not in block_types_filter: block_keys_to_remove.append(block_key) for block_key in block_keys_to_remove: blocks.remove_block(block_key, keep_descendants=True) # serialize serializer_context = { 'request': request, 'block_structure': blocks, 'requested_fields': requested_fields or [], } if return_type == 'dict': serializer = BlockDictSerializer(blocks, context=serializer_context, many=False) else: serializer = BlockSerializer(blocks, context=serializer_context, many=True) # return serialized data return serializer.data
def get(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) course_usage_key = modulestore().make_course_usage_key(course_key) if not course_home_mfe_outline_tab_is_active(course_key): raise Http404 # Enable NR tracing for this view based on course monitoring_utils.set_custom_metric('course_id', course_key_string) monitoring_utils.set_custom_metric('user_id', request.user.id) monitoring_utils.set_custom_metric('is_staff', request.user.is_staff) course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=False) _masquerade, request.user = setup_masquerade( request, course_key, staff_access=has_access(request.user, 'staff', course_key), reset_masquerade_data=True, ) course_overview = CourseOverview.get_from_id(course_key) enrollment = CourseEnrollment.get_enrollment(request.user, course_key) allow_anonymous = COURSE_ENABLE_UNENROLLED_ACCESS_FLAG.is_enabled( course_key) allow_public = allow_anonymous and course.course_visibility == COURSE_VISIBILITY_PUBLIC is_enrolled = enrollment and enrollment.is_active is_staff = has_access(request.user, 'staff', course_key) show_enrolled = is_enrolled or is_staff show_handouts = show_enrolled or allow_public handouts_html = get_course_info_section( request, request.user, course, 'handouts') if show_handouts else '' # TODO: TNL-7185 Legacy: Refactor to return the offer & expired data and format the message in the MFE offer_html = generate_offer_html(request.user, course_overview) course_expired_html = generate_course_expired_message( request.user, course_overview) welcome_message_html = None if get_course_tag(request.user, course_key, PREFERENCE_KEY) != 'False': if LATEST_UPDATE_FLAG.is_enabled(course_key): welcome_message_html = LatestUpdateFragmentView( ).latest_update_html(request, course) else: welcome_message_html = WelcomeMessageFragmentView( ).welcome_message_html(request, course) enroll_alert = { 'can_enroll': True, 'extra_text': None, } if not show_enrolled: if CourseMode.is_masters_only(course_key): enroll_alert['can_enroll'] = False enroll_alert['extra_text'] = _( 'Please contact your degree administrator or ' 'edX Support if you have questions.') elif course.invitation_only: enroll_alert['can_enroll'] = False course_tools = CourseToolsPluginManager.get_enabled_course_tools( request, course_key) date_blocks = get_course_date_blocks(course, request.user, request, num_assignments=1) # User locale settings user_timezone_locale = user_timezone_locale_prefs(request) user_timezone = user_timezone_locale['user_timezone'] dates_tab_link = request.build_absolute_uri( reverse('dates', args=[course.id])) if course_home_mfe_dates_tab_is_active(course.id): dates_tab_link = get_microfrontend_url(course_key=course.id, view_name='dates') transformers = BlockStructureTransformers() transformers += get_course_block_access_transformers(request.user) transformers += [ BlocksAPITransformer(None, None, depth=3), ] course_blocks = get_course_blocks(request.user, course_usage_key, transformers, include_completion=True) dates_widget = { 'course_date_blocks': [ block for block in date_blocks if not isinstance(block, TodaysDate) ], 'dates_tab_link': dates_tab_link, 'user_timezone': user_timezone, } data = { 'course_blocks': course_blocks, 'course_expired_html': course_expired_html, 'course_tools': course_tools, 'dates_widget': dates_widget, 'enroll_alert': enroll_alert, 'handouts_html': handouts_html, 'offer_html': offer_html, 'welcome_message_html': welcome_message_html, } context = self.get_serializer_context() context['course_key'] = course_key serializer = self.get_serializer_class()(data, context=context) return Response(serializer.data)
def get(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) # Enable NR tracing for this view based on course monitoring_utils.set_custom_attribute('course_id', course_key_string) monitoring_utils.set_custom_attribute('user_id', request.user.id) monitoring_utils.set_custom_attribute('is_staff', request.user.is_staff) _, request.user = setup_masquerade(request, course_key, staff_access=has_access( request.user, 'staff', course_key), reset_masquerade_data=True) user_timezone_locale = user_timezone_locale_prefs(request) user_timezone = user_timezone_locale['user_timezone'] transformers = BlockStructureTransformers() transformers += course_blocks_api.get_course_block_access_transformers( request.user) transformers += [ BlocksAPITransformer(None, None, depth=3), ] course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True) enrollment_mode, _ = CourseEnrollment.enrollment_mode_for_user( request.user, course_key) course_grade = CourseGradeFactory().read(request.user, course) courseware_summary = course_grade.chapter_grades.values() verification_status = IDVerificationService.user_status(request.user) verification_link = None if verification_status['status'] is None or verification_status[ 'status'] == 'expired': verification_link = IDVerificationService.get_verify_location( course_id=course_key) elif verification_status['status'] == 'must_reverify': verification_link = IDVerificationService.get_verify_location( course_id=course_key) verification_data = { 'link': verification_link, 'status': verification_status['status'], 'status_date': verification_status['status_date'], } data = { 'certificate_data': get_cert_data(request.user, course, enrollment_mode, course_grade), 'courseware_summary': courseware_summary, 'credit_course_requirements': credit_course_requirements(course_key, request.user), 'credit_support_url': CREDIT_SUPPORT_URL, 'enrollment_mode': enrollment_mode, 'studio_url': get_studio_url(course, 'settings/grading'), 'user_timezone': user_timezone, 'verification_data': verification_data, } context = self.get_serializer_context() context['staff_access'] = bool( has_access(request.user, 'staff', course)) context['course_key'] = course_key serializer = self.get_serializer_class()(data, context=context) return Response(serializer.data)
def get_blocks( request, usage_key, user=None, depth=None, nav_depth=None, requested_fields=None, block_counts=None, student_view_data=None, return_type='dict', block_types_filter=None, hide_access_denials=False, ): """ Return a serialized representation of the course blocks. Arguments: request (HTTPRequest): Used for calling django reverse. usage_key (UsageKey): Identifies the starting block of interest. user (User): Optional user object for whom the blocks are being retrieved. If None, blocks are returned regardless of access checks. depth (integer or None): Identifies the depth of the tree to return starting at the root block. If None, the entire tree starting at the root is returned. nav_depth (integer): Optional parameter that indicates how far deep to traverse into the block hierarchy before bundling all the descendants for navigation. requested_fields (list): Optional list of names of additional fields to return for each block. Supported fields are listed in transformers.SUPPORTED_FIELDS. block_counts (list): Optional list of names of block types for which to return an aggregate count of blocks. student_view_data (list): Optional list of names of block types for which blocks to return their student_view_data. return_type (string): Possible values are 'dict' or 'list'. Indicates the format for returning the blocks. block_types_filter (list): Optional list of block type names used to filter the final result of returned blocks. hide_access_denials (bool): When True, filter out any blocks that were denied access to the user, even if they have access denial messages attached. """ course_blocks_namespace = WaffleFlagNamespace(name=u'course_blocks_api') hide_access_denials_flag = WaffleFlag( waffle_namespace=course_blocks_namespace, flag_name=u'hide_access_denials', flag_undefined_default=False ) if hide_access_denials_flag.is_enabled(): hide_access_denials = True # create ordered list of transformers, adding BlocksAPITransformer at end. transformers = BlockStructureTransformers() if requested_fields is None: requested_fields = [] include_completion = 'completion' in requested_fields include_special_exams = 'special_exam_info' in requested_fields include_gated_sections = 'show_gated_sections' in requested_fields if user is not None: transformers += course_blocks_api.get_course_block_access_transformers(user) transformers += [ MilestonesAndSpecialExamsTransformer( include_special_exams=include_special_exams, include_gated_sections=include_gated_sections ), HiddenContentTransformer() ] if hide_access_denials: transformers += [AccessDeniedMessageFilterTransformer()] # TODO: Remove this after REVE-52 lands and old-mobile-app traffic falls to < 5% of mobile traffic if is_request_from_mobile_app(request): transformers += [HideEmptyTransformer()] transformers += [ BlocksAPITransformer( block_counts, student_view_data, depth, nav_depth ) ] if include_completion: transformers += [BlockCompletionTransformer()] # transform blocks = course_blocks_api.get_course_blocks(user, usage_key, transformers) # filter blocks by types if block_types_filter: block_keys_to_remove = [] for block_key in blocks: block_type = blocks.get_xblock_field(block_key, 'category') if block_type not in block_types_filter: block_keys_to_remove.append(block_key) for block_key in block_keys_to_remove: blocks.remove_block(block_key, keep_descendants=True) # serialize serializer_context = { 'request': request, 'block_structure': blocks, 'requested_fields': requested_fields or [], } if return_type == 'dict': serializer = BlockDictSerializer(blocks, context=serializer_context, many=False) else: serializer = BlockSerializer(blocks, context=serializer_context, many=True) # return serialized data return serializer.data
def get_blocks( request, usage_key, user=None, depth=None, nav_depth=None, requested_fields=None, block_counts=None, student_view_data=None, return_type='dict', block_types_filter=None, ): """ Return a serialized representation of the course blocks. Arguments: request (HTTPRequest): Used for calling django reverse. usage_key (UsageKey): Identifies the starting block of interest. user (User): Optional user object for whom the blocks are being retrieved. If None, blocks are returned regardless of access checks. depth (integer or None): Identifies the depth of the tree to return starting at the root block. If None, the entire tree starting at the root is returned. nav_depth (integer): Optional parameter that indicates how far deep to traverse into the block hierarchy before bundling all the descendants for navigation. requested_fields (list): Optional list of names of additional fields to return for each block. Supported fields are listed in transformers.SUPPORTED_FIELDS. block_counts (list): Optional list of names of block types for which to return an aggregate count of blocks. student_view_data (list): Optional list of names of block types for which blocks to return their student_view_data. return_type (string): Possible values are 'dict' or 'list'. Indicates the format for returning the blocks. block_types_filter (list): Optional list of block type names used to filter the final result of returned blocks. """ # create ordered list of transformers, adding BlocksAPITransformer at end. transformers = BlockStructureTransformers() if requested_fields is None: requested_fields = [] include_completion = 'completion' in requested_fields include_special_exams = 'special_exam_info' in requested_fields include_gated_sections = 'show_gated_sections' in requested_fields if user is not None: transformers += course_blocks_api.get_course_block_access_transformers() transformers += [MilestonesAndSpecialExamsTransformer( include_special_exams=include_special_exams, include_gated_sections=include_gated_sections)] transformers += [HiddenContentTransformer()] transformers += [ BlocksAPITransformer( block_counts, student_view_data, depth, nav_depth ) ] if include_completion: transformers += [BlockCompletionTransformer()] # transform blocks = course_blocks_api.get_course_blocks(user, usage_key, transformers) # filter blocks by types if block_types_filter: block_keys_to_remove = [] for block_key in blocks: block_type = blocks.get_xblock_field(block_key, 'category') if block_type not in block_types_filter: block_keys_to_remove.append(block_key) for block_key in block_keys_to_remove: blocks.remove_block(block_key, keep_descendants=True) # serialize serializer_context = { 'request': request, 'block_structure': blocks, 'requested_fields': requested_fields or [], } if return_type == 'dict': serializer = BlockDictSerializer(blocks, context=serializer_context, many=False) else: serializer = BlockSerializer(blocks, context=serializer_context, many=True) # return serialized data return serializer.data
def get_blocks( request, usage_key, user=None, depth=None, nav_depth=None, requested_fields=None, block_counts=None, student_view_data=None, return_type='dict', block_types_filter=None, ): """ Return a serialized representation of the course blocks. Arguments: request (HTTPRequest): Used for calling django reverse. usage_key (UsageKey): Identifies the starting block of interest. user (User): Optional user object for whom the blocks are being retrieved. If None, blocks are returned regardless of access checks. depth (integer or None): Identifies the depth of the tree to return starting at the root block. If None, the entire tree starting at the root is returned. nav_depth (integer): Optional parameter that indicates how far deep to traverse into the block hierarchy before bundling all the descendants for navigation. requested_fields (list): Optional list of names of additional fields to return for each block. Supported fields are listed in transformers.SUPPORTED_FIELDS. block_counts (list): Optional list of names of block types for which to return an aggregate count of blocks. student_view_data (list): Optional list of names of block types for which blocks to return their student_view_data. return_type (string): Possible values are 'dict' or 'list'. Indicates the format for returning the blocks. block_types_filter (list): Optional list of block type names used to filter the final result of returned blocks. """ # create ordered list of transformers, adding BlocksAPITransformer at end. transformers = BlockStructureTransformers() if requested_fields is None: requested_fields = [] include_completion = 'completion' in requested_fields include_special_exams = 'special_exam_info' in requested_fields include_gated_sections = 'show_gated_sections' in requested_fields if user is not None: transformers += course_blocks_api.get_course_block_access_transformers( user) transformers += [ MilestonesAndSpecialExamsTransformer( include_special_exams=include_special_exams, include_gated_sections=include_gated_sections) ] transformers += [HiddenContentTransformer()] transformers += [ BlocksAPITransformer(block_counts, student_view_data, depth, nav_depth) ] if include_completion: transformers += [BlockCompletionTransformer()] # transform blocks = course_blocks_api.get_course_blocks(user, usage_key, transformers) # filter blocks by types if block_types_filter: block_keys_to_remove = [] for block_key in blocks: block_type = blocks.get_xblock_field(block_key, 'category') if block_type not in block_types_filter: block_keys_to_remove.append(block_key) for block_key in block_keys_to_remove: blocks.remove_block(block_key, keep_descendants=True) # serialize serializer_context = { 'request': request, 'block_structure': blocks, 'requested_fields': requested_fields or [], } if return_type == 'dict': serializer = BlockDictSerializer(blocks, context=serializer_context, many=False) else: serializer = BlockSerializer(blocks, context=serializer_context, many=True) # return serialized data return serializer.data
def get(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) course_usage_key = modulestore().make_course_usage_key(course_key) # Enable NR tracing for this view based on course monitoring_utils.set_custom_metric('course_id', course_key_string) monitoring_utils.set_custom_metric('user_id', request.user.id) monitoring_utils.set_custom_metric('is_staff', request.user.is_staff) course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=False) _, request.user = setup_masquerade( request, course_key, staff_access=has_access(request.user, 'staff', course_key), reset_masquerade_data=True, ) enrollment = CourseEnrollment.get_enrollment(request.user, course_key) allow_anonymous = COURSE_ENABLE_UNENROLLED_ACCESS_FLAG.is_enabled(course_key) allow_public = allow_anonymous and course.course_visibility == COURSE_VISIBILITY_PUBLIC is_enrolled = enrollment and enrollment.is_active is_staff = has_access(request.user, 'staff', course_key) show_handouts = is_enrolled or is_staff or allow_public handouts_html = get_course_info_section(request, request.user, course, 'handouts') if show_handouts else '' welcome_message_html = None if get_course_tag(request.user, course_key, PREFERENCE_KEY) != 'False': if LATEST_UPDATE_FLAG.is_enabled(course_key): welcome_message_html = LatestUpdateFragmentView().latest_update_html(request, course) else: welcome_message_html = WelcomeMessageFragmentView().welcome_message_html(request, course) course_tools = CourseToolsPluginManager.get_enabled_course_tools(request, course_key) date_blocks = get_course_date_blocks(course, request.user, request, num_assignments=1) # User locale settings user_timezone_locale = user_timezone_locale_prefs(request) user_timezone = user_timezone_locale['user_timezone'] dates_tab_link = request.build_absolute_uri(reverse('dates', args=[course.id])) if course_home_mfe_dates_tab_is_active(course.id): dates_tab_link = get_microfrontend_url(course_key=course.id, view_name='dates') transformers = BlockStructureTransformers() transformers += get_course_block_access_transformers(request.user) transformers += [ BlocksAPITransformer(None, None, depth=3), ] course_blocks = get_course_blocks(request.user, course_usage_key, transformers, include_completion=True) dates_widget = { 'course_date_blocks': [block for block in date_blocks if not isinstance(block, TodaysDate)], 'dates_tab_link': dates_tab_link, 'user_timezone': user_timezone, } data = { 'course_blocks': course_blocks, 'course_tools': course_tools, 'dates_widget': dates_widget, 'handouts_html': handouts_html, 'welcome_message_html': welcome_message_html, } context = self.get_serializer_context() context['course_key'] = course_key serializer = self.get_serializer_class()(data, context=context) return Response(serializer.data)
def get(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) course_usage_key = modulestore().make_course_usage_key(course_key) # Enable NR tracing for this view based on course monitoring_utils.set_custom_metric('course_id', course_key_string) monitoring_utils.set_custom_metric('user_id', request.user.id) monitoring_utils.set_custom_metric('is_staff', request.user.is_staff) course_tools = CourseToolsPluginManager.get_enabled_course_tools( request, course_key) course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=False) date_blocks = get_course_date_blocks(course, request.user, request, num_assignments=1) # User locale settings user_timezone_locale = user_timezone_locale_prefs(request) user_timezone = user_timezone_locale['user_timezone'] dates_tab_link = request.build_absolute_uri( reverse('dates', args=[course.id])) if course_home_mfe_dates_tab_is_active(course.id): dates_tab_link = get_microfrontend_url(course_key=course.id, view_name='dates') transformers = BlockStructureTransformers() transformers += course_blocks_api.get_course_block_access_transformers( request.user) transformers += [ BlocksAPITransformer(None, None, depth=3), ] course_blocks = get_course_blocks(request.user, course_usage_key, transformers, include_completion=True) dates_widget = { 'course_date_blocks': [ block for block in date_blocks if not isinstance(block, TodaysDate) ], 'dates_tab_link': dates_tab_link, 'user_timezone': user_timezone, } data = { 'course_tools': course_tools, 'course_blocks': course_blocks, 'dates_widget': dates_widget, } context = self.get_serializer_context() context['course_key'] = course_key serializer = self.get_serializer_class()(data, context=context) return Response(serializer.data)
def get_blocks( request, usage_key, user=None, depth=None, nav_depth=None, requested_fields=None, block_counts=None, student_view_data=None, return_type='dict', block_types_filter=None, hide_access_denials=False, allow_start_dates_in_future=False, ): """ Return a serialized representation of the course blocks. Arguments: request (HTTPRequest): Used for calling django reverse. usage_key (UsageKey): Identifies the starting block of interest. user (User): Optional user object for whom the blocks are being retrieved. If None, blocks are returned regardless of access checks. depth (integer or None): Identifies the depth of the tree to return starting at the root block. If None, the entire tree starting at the root is returned. nav_depth (integer): Optional parameter that indicates how far deep to traverse into the block hierarchy before bundling all the descendants for navigation. requested_fields (list): Optional list of names of additional fields to return for each block. Supported fields are listed in transformers.SUPPORTED_FIELDS. block_counts (list): Optional list of names of block types for which to return an aggregate count of blocks. student_view_data (list): Optional list of names of block types for which blocks to return their student_view_data. return_type (string): Possible values are 'dict' or 'list'. Indicates the format for returning the blocks. block_types_filter (list): Optional list of block type names used to filter the final result of returned blocks. hide_access_denials (bool): When True, filter out any blocks that were denied access to the user, even if they have access denial messages attached. allow_start_dates_in_future (bool): When True, will allow blocks to be returned that can bypass the StartDateTransformer's filter to show blocks with start dates in the future. """ if HIDE_ACCESS_DENIALS_FLAG.is_enabled(): hide_access_denials = True # create ordered list of transformers, adding BlocksAPITransformer at end. transformers = BlockStructureTransformers() if requested_fields is None: requested_fields = [] include_completion = 'completion' in requested_fields include_effort_estimation = (EffortEstimationTransformer.EFFORT_TIME in requested_fields or EffortEstimationTransformer.EFFORT_ACTIVITIES in requested_fields) include_gated_sections = 'show_gated_sections' in requested_fields include_has_scheduled_content = 'has_scheduled_content' in requested_fields include_special_exams = 'special_exam_info' in requested_fields if user is not None: transformers += course_blocks_api.get_course_block_access_transformers(user) transformers += [ MilestonesAndSpecialExamsTransformer( include_special_exams=include_special_exams, include_gated_sections=include_gated_sections ), HiddenContentTransformer() ] # Note: A change to the BlockCompletionTransformer (https://github.com/edx/edx-platform/pull/27622/) # will be introducing a bug if hide_access_denials is True. I'm accepting this risk because in # the AccessDeniedMessageFilterTransformer, there is note about deleting it and I believe it is # technically deprecated functionality. The only use case where hide_access_denials is True # (outside of explicitly setting the temporary waffle flag) is in lms/djangoapps/course_api/blocks/urls.py # for a v1 api that I also believe should have been deprecated and removed. When this code is removed, # please also remove this comment. Thanks! if hide_access_denials: transformers += [AccessDeniedMessageFilterTransformer()] if include_effort_estimation: transformers += [EffortEstimationTransformer()] transformers += [ BlocksAPITransformer( block_counts, student_view_data, depth, nav_depth ) ] # transform blocks = course_blocks_api.get_course_blocks( user, usage_key, transformers, allow_start_dates_in_future=allow_start_dates_in_future, include_completion=include_completion, include_has_scheduled_content=include_has_scheduled_content ) # filter blocks by types if block_types_filter: block_keys_to_remove = [] for block_key in blocks: block_type = blocks.get_xblock_field(block_key, 'category') if block_type not in block_types_filter: block_keys_to_remove.append(block_key) for block_key in block_keys_to_remove: blocks.remove_block(block_key, keep_descendants=True) # serialize serializer_context = { 'request': request, 'block_structure': blocks, 'requested_fields': requested_fields or [], } if return_type == 'dict': serializer = BlockDictSerializer(blocks, context=serializer_context, many=False) else: serializer = BlockSerializer(blocks, context=serializer_context, many=True) # return serialized data return serializer.data