def render_to_fragment(self, request, course_id, **kwargs): if(not _has_page_access(request.user, course_id)): raise Http404() course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, "load", course_key) # masquerade and student required for preview_menu (admin) staff_access = bool(has_access(request.user, 'staff', course)) can_masquerade = request.user.has_perm(MASQUERADE_AS_STUDENT, course) masquerade, student = setup_masquerade(request, course_key, staff_access, reset_masquerade_data=True) prefetch_related_objects([student], 'groups') if request.user.id != student.id: course = get_course_with_access(student, 'load', course_key, check_if_enrolled=True) context = { "course": course, "student_id": student.id, "supports_preview_menu": True, "staff_access": staff_access, "can_masquerade": can_masquerade, "masquerade": masquerade, 'studio_url': get_studio_url(course, 'settings/grading'), "DEV_URL": configuration_helpers.get_value('EOL_PROGRESS_TAB_DEV_URL', settings.EOL_PROGRESS_TAB_DEV_URL) } html = render_to_string('eol_progress_tab/eol_progress_tab_fragment.html', context) fragment = Fragment(html) return fragment
def test_external_plugin_integration(self, mock_get_plugins_view_context): """ Tests that whether context from plugins is being reflected/added in instructor dashboard. """ test_studio_url = get_studio_url(self.course, 'course') context = {'studio_url': test_studio_url} mock_get_plugins_view_context.return_value = context response = self.client.get(self.url) self.assertContains(response, test_studio_url)
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) 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 = { 'certificate_data': get_cert_data(request.user, course, enrollment_mode, course_grade), 'courseware_summary': courseware_summary, 'enrollment_mode': enrollment_mode, 'studio_url': get_studio_url(course, 'settings/grading'), '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 instructor_dashboard_2(request, course_id): """ Display the instructor dashboard for a course. """ try: course_key = CourseKey.from_string(course_id) except InvalidKeyError: log.error(u"Unable to find course with course key %s while loading the Instructor Dashboard.", course_id) return HttpResponseServerError() course = get_course_by_id(course_key, depth=0) access = { 'admin': request.user.is_staff, 'instructor': bool(has_access(request.user, 'instructor', course)), 'finance_admin': CourseFinanceAdminRole(course_key).has_user(request.user), 'sales_admin': CourseSalesAdminRole(course_key).has_user(request.user), 'staff': bool(has_access(request.user, 'staff', course)), 'forum_admin': has_forum_access(request.user, course_key, FORUM_ROLE_ADMINISTRATOR), 'data_researcher': request.user.has_perm(permissions.CAN_RESEARCH, course_key), } if not request.user.has_perm(permissions.VIEW_DASHBOARD, course_key): raise Http404() is_white_label = CourseMode.is_white_label(course_key) reports_enabled = configuration_helpers.get_value('SHOW_ECOMMERCE_REPORTS', False) sections = [] if access['staff']: sections.extend([ _section_course_info(course, access), _section_membership(course, access), _section_cohort_management(course, access), _section_discussions_management(course, access), _section_student_admin(course, access), ]) if access['data_researcher']: sections.append(_section_data_download(course, access)) analytics_dashboard_message = None if show_analytics_dashboard_message(course_key) and (access['staff'] or access['instructor']): # Construct a URL to the external analytics dashboard analytics_dashboard_url = '{0}/courses/{1}'.format(settings.ANALYTICS_DASHBOARD_URL, six.text_type(course_key)) link_start = HTML(u"<a href=\"{}\" rel=\"noopener\" target=\"_blank\">").format(analytics_dashboard_url) analytics_dashboard_message = _( u"To gain insights into student enrollment and participation {link_start}" u"visit {analytics_dashboard_name}, our new course analytics product{link_end}." ) analytics_dashboard_message = Text(analytics_dashboard_message).format( link_start=link_start, link_end=HTML("</a>"), analytics_dashboard_name=settings.ANALYTICS_DASHBOARD_NAME) # Temporarily show the "Analytics" section until we have a better way of linking to Insights sections.append(_section_analytics(course, access)) # Check if there is corresponding entry in the CourseMode Table related to the Instructor Dashboard course course_mode_has_price = False paid_modes = CourseMode.paid_modes_for_course(course_key) if len(paid_modes) == 1: course_mode_has_price = True elif len(paid_modes) > 1: log.error( u"Course %s has %s course modes with payment options. Course must only have " u"one paid course mode to enable eCommerce options.", six.text_type(course_key), len(paid_modes) ) if access['instructor'] and is_enabled_for_course(course_key): sections.insert(3, _section_extensions(course)) # Gate access to course email by feature flag & by course-specific authorization if is_bulk_email_feature_enabled(course_key) and (access['staff'] or access['instructor']): sections.append(_section_send_email(course, access)) # Gate access to Special Exam tab depending if either timed exams or proctored exams # are enabled in the course user_has_access = any([ request.user.is_staff, CourseStaffRole(course_key).has_user(request.user), CourseInstructorRole(course_key).has_user(request.user) ]) course_has_special_exams = course.enable_proctored_exams or course.enable_timed_exams can_see_special_exams = course_has_special_exams and user_has_access and settings.FEATURES.get( 'ENABLE_SPECIAL_EXAMS', False) if can_see_special_exams: sections.append(_section_special_exams(course, access)) # Certificates panel # This is used to generate example certificates # and enable self-generated certificates for a course. # Note: This is hidden for all CCXs certs_enabled = CertificateGenerationConfiguration.current().enabled and not hasattr(course_key, 'ccx') if certs_enabled and access['admin']: sections.append(_section_certificates(course)) openassessment_blocks = modulestore().get_items( course_key, qualifiers={'category': 'openassessment'} ) # filter out orphaned openassessment blocks openassessment_blocks = [ block for block in openassessment_blocks if block.parent is not None ] if len(openassessment_blocks) > 0 and access['staff']: sections.append(_section_open_response_assessment(request, course, openassessment_blocks, access)) disable_buttons = not CourseEnrollment.objects.is_small_course(course_key) certificate_white_list = CertificateWhitelist.get_certificate_white_list(course_key) generate_certificate_exceptions_url = reverse( 'generate_certificate_exceptions', kwargs={'course_id': six.text_type(course_key), 'generate_for': ''} ) generate_bulk_certificate_exceptions_url = reverse( 'generate_bulk_certificate_exceptions', kwargs={'course_id': six.text_type(course_key)} ) certificate_exception_view_url = reverse( 'certificate_exception_view', kwargs={'course_id': six.text_type(course_key)} ) certificate_invalidation_view_url = reverse( 'certificate_invalidation_view', kwargs={'course_id': six.text_type(course_key)} ) certificate_invalidations = CertificateInvalidation.get_certificate_invalidations(course_key) context = { 'course': course, 'studio_url': get_studio_url(course, 'course'), 'sections': sections, 'disable_buttons': disable_buttons, 'analytics_dashboard_message': analytics_dashboard_message, 'certificate_white_list': certificate_white_list, 'certificate_invalidations': certificate_invalidations, 'generate_certificate_exceptions_url': generate_certificate_exceptions_url, 'generate_bulk_certificate_exceptions_url': generate_bulk_certificate_exceptions_url, 'certificate_exception_view_url': certificate_exception_view_url, 'certificate_invalidation_view_url': certificate_invalidation_view_url, 'xqa_server': settings.FEATURES.get('XQA_SERVER', "http://your_xqa_server.com"), } return render_to_response('instructor/instructor_dashboard_2/instructor_dashboard_2.html', context)
def get(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) if not course_home_mfe_progress_tab_is_active(course_key): raise Http404 # 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) 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) # The block structure is used for both the course_grade and has_scheduled content fields # So it is called upfront and reused for optimization purposes collected_block_structure = get_block_structure_manager( course_key).get_collected() course_grade = CourseGradeFactory().read( request.user, collected_block_structure=collected_block_structure) # Get has_scheduled_content data transformers = BlockStructureTransformers() transformers += [start_date.StartDateTransformer()] usage_key = collected_block_structure.root_block_usage_key course_blocks = get_course_blocks( request.user, usage_key, transformers=transformers, collected_block_structure=collected_block_structure, include_has_scheduled_content=True) has_scheduled_content = course_blocks.get_xblock_field( usage_key, 'has_scheduled_content') # Get user_has_passing_grade data user_has_passing_grade = False if not request.user.is_anonymous: user_grade = course_grade.percent user_has_passing_grade = user_grade >= course.lowest_passing_grade descriptor = modulestore().get_course(course_key) grading_policy = descriptor.grading_policy 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 = { 'end': course.end, 'user_has_passing_grade': user_has_passing_grade, 'certificate_data': get_cert_data(request.user, course, enrollment_mode, course_grade), 'completion_summary': get_course_blocks_completion_summary(course_key, request.user), 'course_grade': course_grade, 'has_scheduled_content': has_scheduled_content, 'section_scores': course_grade.chapter_grades.values(), 'enrollment_mode': enrollment_mode, 'grading_policy': grading_policy, 'studio_url': get_studio_url(course, 'settings/grading'), '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(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(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) student_id = kwargs.get('student_id') if student_id: try: student_id = int(student_id) except ValueError: raise Http404 if not course_home_mfe_progress_tab_is_active(course_key): raise Http404 # 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) is_staff = bool(has_access(request.user, 'staff', course_key)) if student_id is None or student_id == request.user.id: _, student = setup_masquerade(request, course_key, staff_access=is_staff, reset_masquerade_data=True) else: # When a student_id is passed in, we display the progress page for the user # with the provided user id, rather than the requesting user try: coach_access = has_ccx_coach_role(request.user, course_key) except CCXLocatorValidationException: coach_access = False has_access_on_students_profiles = is_staff or coach_access # Requesting access to a different student's profile if not has_access_on_students_profiles: raise Http404 try: student = User.objects.get(id=student_id) except User.DoesNotExist as exc: raise Http404 from exc username = get_enterprise_learner_generic_name( request) or student.username course = get_course_with_access(student, 'load', course_key, check_if_enrolled=False) course_overview = CourseOverview.get_from_id(course_key) enrollment = CourseEnrollment.get_enrollment(student, course_key) enrollment_mode = getattr(enrollment, 'mode', None) if not (enrollment and enrollment.is_active) and not is_staff: return Response('User not enrolled.', status=401) # The block structure is used for both the course_grade and has_scheduled content fields # So it is called upfront and reused for optimization purposes collected_block_structure = get_block_structure_manager( course_key).get_collected() course_grade = CourseGradeFactory().read( student, collected_block_structure=collected_block_structure) # Get has_scheduled_content data transformers = BlockStructureTransformers() transformers += [ start_date.StartDateTransformer(), ContentTypeGateTransformer() ] usage_key = collected_block_structure.root_block_usage_key course_blocks = get_course_blocks( student, usage_key, transformers=transformers, collected_block_structure=collected_block_structure, include_has_scheduled_content=True) has_scheduled_content = course_blocks.get_xblock_field( usage_key, 'has_scheduled_content') # Get user_has_passing_grade data user_has_passing_grade = False if not student.is_anonymous: user_grade = course_grade.percent user_has_passing_grade = user_grade >= course.lowest_passing_grade descriptor = modulestore().get_course(course_key) grading_policy = descriptor.grading_policy verification_status = IDVerificationService.user_status(student) 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 = { 'username': username, 'end': course.end, 'user_has_passing_grade': user_has_passing_grade, 'certificate_data': get_cert_data(student, course, enrollment_mode, course_grade), 'completion_summary': get_course_blocks_completion_summary(course_key, student), 'course_grade': course_grade, 'has_scheduled_content': has_scheduled_content, 'section_scores': course_grade.chapter_grades.values(), 'enrollment_mode': enrollment_mode, 'grading_policy': grading_policy, 'studio_url': get_studio_url(course, 'settings/grading'), 'verification_data': verification_data, } context = self.get_serializer_context() context['staff_access'] = is_staff context['course_blocks'] = course_blocks context['course_key'] = course_key # course_overview and enrollment will be used by VerifiedModeSerializerMixin context['course_overview'] = course_overview context['enrollment'] = enrollment 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) if not course_home_mfe_progress_tab_is_active(course_key): raise Http404 # 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) 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)\ descriptor = modulestore().get_course(course_key) grading_policy = descriptor.grading_policy 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), 'completion_summary': get_course_blocks_completion_summary(course_key, request.user), 'course_grade': course_grade, 'section_scores': course_grade.chapter_grades.values(), 'enrollment_mode': enrollment_mode, 'grading_policy': grading_policy, 'studio_url': get_studio_url(course, 'settings/grading'), '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(self, request, *args, **kwargs): course_key_string = kwargs.get('course_key_string') course_key = CourseKey.from_string(course_key_string) student_id = kwargs.get('student_id') if not course_home_mfe_progress_tab_is_active(course_key): raise Http404 # 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) is_staff = bool(has_access(request.user, 'staff', course_key)) student = self._get_student_user(request, course_key, student_id, is_staff) username = get_enterprise_learner_generic_name( request) or student.username course = get_course_with_access(student, 'load', course_key, check_if_enrolled=False) course_overview = CourseOverview.get_from_id(course_key) enrollment = CourseEnrollment.get_enrollment(student, course_key) enrollment_mode = getattr(enrollment, 'mode', None) if not (enrollment and enrollment.is_active) and not is_staff: return Response('User not enrolled.', status=401) # The block structure is used for both the course_grade and has_scheduled content fields # So it is called upfront and reused for optimization purposes collected_block_structure = get_block_structure_manager( course_key).get_collected() course_grade = CourseGradeFactory().read( student, collected_block_structure=collected_block_structure) # recalculate course grade from visible grades (stored grade was calculated over all grades, visible or not) course_grade.update(visible_grades_only=True, has_staff_access=is_staff) # Get has_scheduled_content data transformers = BlockStructureTransformers() transformers += [ start_date.StartDateTransformer(), ContentTypeGateTransformer() ] usage_key = collected_block_structure.root_block_usage_key course_blocks = get_course_blocks( student, usage_key, transformers=transformers, collected_block_structure=collected_block_structure, include_has_scheduled_content=True) has_scheduled_content = course_blocks.get_xblock_field( usage_key, 'has_scheduled_content') # Get user_has_passing_grade data user_has_passing_grade = False if not student.is_anonymous: user_grade = course_grade.percent user_has_passing_grade = user_grade >= course.lowest_passing_grade descriptor = modulestore().get_course(course_key) grading_policy = descriptor.grading_policy verification_status = IDVerificationService.user_status(student) 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'], } access_expiration = get_access_expiration_data(request.user, course_overview) data = { 'access_expiration': access_expiration, 'certificate_data': get_cert_data(student, course, enrollment_mode, course_grade), 'completion_summary': get_course_blocks_completion_summary(course_key, student), 'course_grade': course_grade, 'credit_course_requirements': credit_course_requirements(course_key, student), 'end': course.end, 'enrollment_mode': enrollment_mode, 'grading_policy': grading_policy, 'has_scheduled_content': has_scheduled_content, 'section_scores': list(course_grade.chapter_grades.values()), 'studio_url': get_studio_url(course, 'settings/grading'), 'username': username, 'user_has_passing_grade': user_has_passing_grade, 'verification_data': verification_data, } context = self.get_serializer_context() context['staff_access'] = is_staff context['course_blocks'] = course_blocks context['course_key'] = course_key # course_overview and enrollment will be used by VerifiedModeSerializer context['course_overview'] = course_overview context['enrollment'] = enrollment serializer = self.get_serializer_class()(data, context=context) return Response(serializer.data)