def test_no_certificates_for_user(self): """ Test the case when there are no certificates for a user. """ self.assertEqual( certs_api.get_certificates_for_user(self.student_no_cert.username), [])
def _get_certificates_for_user(self, username): """ Returns a user's viewable certificates sorted by course name. """ course_certificates = get_certificates_for_user(username) passing_certificates = {} for course_certificate in course_certificates: if course_certificate.get('is_passing', False): course_key = course_certificate['course_key'] passing_certificates[course_key] = course_certificate viewable_certificates = [] for course_key, course_overview in CourseOverview.get_from_ids_if_exists( passing_certificates.keys()).items(): if certificates_viewable_for_course(course_overview): course_certificate = passing_certificates[course_key] course_certificate[ 'course_display_name'] = course_overview.display_name_with_default course_certificate[ 'course_organization'] = course_overview.display_org_with_default viewable_certificates.append(course_certificate) viewable_certificates.sort( key=lambda certificate: certificate['created']) return viewable_certificates
def course_runs_with_state(self): """ Determine which course runs have been completed and failed by the user. A course run is considered completed for a user if they have a certificate in the correct state and the certificate is available. Returns: dict with a list of completed and failed runs """ course_run_certificates = certificate_api.get_certificates_for_user( self.user.username) completed_runs, failed_runs = [], [] for certificate in course_run_certificates: course_key = certificate['course_key'] course_data = { 'course_run_id': str(course_key), 'type': self._certificate_mode_translation(certificate['type']), } try: may_certify = CourseOverview.get_from_id( course_key).may_certify() except CourseOverview.DoesNotExist: may_certify = True if (CertificateStatuses.is_passing_status(certificate['status']) and may_certify): completed_runs.append(course_data) else: failed_runs.append(course_data) return {'completed': completed_runs, 'failed': failed_runs}
def course_runs_with_state(self): """ Determine which course runs have been completed and failed by the user. Returns: dict with a list of completed and failed runs """ course_run_certificates = certificate_api.get_certificates_for_user(self.user.username) completed_runs, failed_runs = [], [] for certificate in course_run_certificates: certificate_type = certificate['type'] # Treat "no-id-professional" certificates as "professional" certificates if certificate_type == CourseMode.NO_ID_PROFESSIONAL_MODE: certificate_type = CourseMode.PROFESSIONAL course_data = { 'course_run_id': unicode(certificate['course_key']), 'type': certificate_type, } if certificate_api.is_passing_status(certificate['status']): completed_runs.append(course_data) else: failed_runs.append(course_data) return {'completed': completed_runs, 'failed': failed_runs}
def _get_ordered_certificates_for_user(self, request, username): """ Returns a user's certificates sorted by course name. """ course_certificates = certificate_api.get_certificates_for_user( username) passing_certificates = [] for course_certificate in course_certificates: if course_certificate.get('is_passing', False): course_key = course_certificate['course_key'] try: course_overview = CourseOverview.get_from_id(course_key) course_certificate['course'] = course_overview if certificates_viewable_for_course(course_overview): # add certificate into passing certificate list only if it's a PDF certificate # or there is an active certificate configuration. if course_certificate[ 'is_pdf_certificate'] or course_overview.has_any_active_web_certificate: passing_certificates.append(course_certificate) except CourseOverview.DoesNotExist: # This is unlikely to fail as the course should exist. # Ideally the cert should have all the information that # it needs. This might be solved by the Credentials API. pass passing_certificates.sort(key=lambda certificate: certificate['course'] .display_name_with_default) return passing_certificates
def _does_name_change_require_verification(user_profile, old_name, new_name): """ If name change requires ID verification, do not update it through this API. """ profile_meta = user_profile.get_meta() old_names_list = profile_meta[ 'old_names'] if 'old_names' in profile_meta else [] user = user_profile.user # We only want to validate on a list of passing certificates for the learner. A learner may have # a certificate in a non-passing status, and we do not have to require ID verification based on certificates # that are not passing. passing_certs = filter( lambda cert: CertificateStatuses.is_passing_status(cert["status"]), get_certificates_for_user(user.username)) num_passing_certs = len(list(passing_certs)) # We check whether the learner has active verified enrollments because we do not want to # require the learner to perform ID verification if the learner is not enrolled in a verified mode # in any courses. The learner will not be able to complete ID verification without being enrolled in # at least one seat. has_verified_enrollments = len(get_verified_enrollments(user.username)) > 0 validator = NameChangeValidator(old_names_list, num_passing_certs, old_name, new_name) return not validator.validate() and has_verified_enrollments
def _get_certificates_for_user(self, username): """ Returns a user's viewable certificates sorted by course name. """ course_certificates = get_certificates_for_user(username) passing_certificates = {} for course_certificate in course_certificates: if course_certificate.get('is_passing', False): course_key = course_certificate['course_key'] passing_certificates[course_key] = course_certificate viewable_certificates = [] for course_key, course_overview in CourseOverview.get_from_ids( list(passing_certificates.keys())).items(): if not course_overview: # For deleted XML courses in which learners have a valid certificate. # i.e. MITx/7.00x/2013_Spring course_overview = self._get_pseudo_course_overview(course_key) if certificates_viewable_for_course(course_overview): course_certificate = passing_certificates[course_key] # add certificate into viewable certificate list only if it's a PDF certificate # or there is an active certificate configuration. if course_certificate[ 'is_pdf_certificate'] or course_overview.has_any_active_web_certificate: course_certificate[ 'course_display_name'] = course_overview.display_name_with_default course_certificate[ 'course_organization'] = course_overview.display_org_with_default viewable_certificates.append(course_certificate) viewable_certificates.sort( key=lambda certificate: certificate['created']) return viewable_certificates
def course_runs_with_state(self): """ Determine which course runs have been completed and failed by the user. Returns: dict with a list of completed and failed runs """ course_run_certificates = certificate_api.get_certificates_for_user( self.user.username) completed_runs, failed_runs = [], [] for certificate in course_run_certificates: certificate_type = certificate['type'] # Treat "no-id-professional" certificates as "professional" certificates if certificate_type == CourseMode.NO_ID_PROFESSIONAL_MODE: certificate_type = CourseMode.PROFESSIONAL course_data = { 'course_run_id': unicode(certificate['course_key']), 'type': certificate_type, } if certificate_api.is_passing_status(certificate['status']): completed_runs.append(course_data) else: failed_runs.append(course_data) return {'completed': completed_runs, 'failed': failed_runs}
def test_no_certificates_for_user(self): """ Test the case when there are no certificates for a user. """ self.assertEqual( certs_api.get_certificates_for_user(self.student_no_cert.username), [] )
def completed_course_runs(self): """ Determine which course runs have been completed by the user. Returns: list of dicts, each representing a course run certificate """ course_run_certificates = certificate_api.get_certificates_for_user(self.user.username) return [ {'course_run_id': unicode(certificate['course_key']), 'type': certificate['type']} for certificate in course_run_certificates if certificate_api.is_passing_status(certificate['status']) ]
def _get_ordered_certificates_for_user(self, request, username): """ Returns a user's certificates sorted by course name. """ course_certificates = certificate_api.get_certificates_for_user( username) for course_certificate in course_certificates: course_key = course_certificate['course_key'] course_overview = get_course_overview_with_access( request.user, 'load', course_key) course_certificate['course'] = course_overview course_certificates.sort(key=lambda certificate: certificate['course']. display_name_with_default) return course_certificates
def _does_name_change_require_verification(user_profile, old_name, new_name): """ If name change requires verification, do not update it through this API. """ profile_meta = user_profile.get_meta() old_names_list = profile_meta[ 'old_names'] if 'old_names' in profile_meta else [] user = user_profile.user num_certs = len(get_certificates_for_user(user.username)) validator = NameChangeValidator(old_names_list, num_certs, old_name, new_name) return (is_verified_name_enabled() and not validator.validate())
def get_completed_courses(student): """ Determine which courses have been completed by the user. Args: student: User object representing the student Returns: iterable of dicts with structure {'course_id': course_key, 'mode': cert_type} """ all_certs = get_certificates_for_user(student.username) return [{ 'course_id': unicode(cert['course_key']), 'mode': cert['type'] } for cert in all_certs if is_passing_status(cert['status'])]
def get_completed_courses(student): """ Determine which courses have been completed by the user. Args: student: User object representing the student Returns: iterable of dicts with structure {'course_id': course_key, 'mode': cert_type} """ all_certs = certificate_api.get_certificates_for_user(student.username) return [ {'course_id': unicode(cert['course_key']), 'mode': cert['type']} for cert in all_certs if certificate_api.is_passing_status(cert['status']) ]
def _get_ordered_certificates_for_user(self, request, username): """ Returns a user's certificates sorted by course name. """ course_certificates = certificate_api.get_certificates_for_user(username) passing_certificates = [] for course_certificate in course_certificates: if course_certificate.get('is_passing', False): course_key = course_certificate['course_key'] try: course_overview = CourseOverview.get_from_id(course_key) course_certificate['course'] = course_overview passing_certificates.append(course_certificate) except CourseOverview.DoesNotExist: # This is unlikely to fail as the course should exist. # Ideally the cert should have all the information that # it needs. This might be solved by the Credentials API. pass passing_certificates.sort(key=lambda certificate: certificate['course'].display_name_with_default) return passing_certificates
def course_runs_with_state(self): """ Determine which course runs have been completed and failed by the user. Returns: dict with a list of completed and failed runs """ course_run_certificates = certificate_api.get_certificates_for_user( self.user.username) completed_runs, failed_runs = [], [] for certificate in course_run_certificates: course_data = { 'course_run_id': unicode(certificate['course_key']), 'type': certificate['type'] } if certificate_api.is_passing_status(certificate['status']): completed_runs.append(course_data) else: failed_runs.append(course_data) return {'completed': completed_runs, 'failed': failed_runs}
def award_program_certificates(username): """ This task is designed to be called whenever a user's completion status changes with respect to one or more courses (primarily, when a course certificate is awarded). It will consult with a variety of APIs to determine whether or not the specified user should be awarded a certificate in one or more programs, and use the credentials service to create said certificates if so. This task may also be invoked independently of any course completion status change - for example, to backpopulate missing program credentials for a user. TODO: this is shelled out and incomplete for now. """ # fetch the set of all course runs for which the user has earned a certificate LOGGER.debug('fetching all completed courses for user %s', username) user_certs = get_certificates_for_user(username) course_certs = [ {'course_id': uc['course_id'], 'mode': uc['mode']} for uc in user_certs if uc['status'] in ('downloadable', 'generating') ] # invoke the Programs API completion check endpoint to identify any programs # that are satisfied by these course completions LOGGER.debug('determining completed programs for courses: %r', course_certs) program_ids = [] # TODO # determine which program certificates the user has already been awarded, if # any, and remove those, since they already exist. LOGGER.debug('fetching existing program certificates for %s', username) existing_program_ids = [] # TODO new_program_ids = list(set(program_ids) - set(existing_program_ids)) # generate a new certificate for each of the remaining programs. LOGGER.debug('generating new program certificates for %s in programs: %r', username, new_program_ids) for program_id in new_program_ids: LOGGER.debug('calling credentials service to issue certificate for user %s in program %s', username, program_id)
def _get_ordered_certificates_for_user(self, request, username): """ Returns a user's certificates sorted by course name. """ course_certificates = certificate_api.get_certificates_for_user( username) passing_certificates = [] for course_certificate in course_certificates: if course_certificate.get('is_passing', False): course_key = course_certificate['course_key'] try: course_overview = CourseOverview.get_from_id(course_key) course_certificate['course'] = course_overview passing_certificates.append(course_certificate) except CourseOverview.DoesNotExist: # This is unlikely to fail as the course should exist. # Ideally the cert should have all the information that # it needs. This might be solved by the Credentials API. pass passing_certificates.sort(key=lambda certificate: certificate['course'] .display_name_with_default) return passing_certificates
def test_get_certificates_for_user(self): """ Test to get all the certificates for a user """ certs = certs_api.get_certificates_for_user(self.student.username) self.assertEqual(len(certs), 2) self.assertEqual(certs[0]['username'], self.student.username) self.assertEqual(certs[1]['username'], self.student.username) self.assertEqual(certs[0]['course_key'], self.web_cert_course.id) self.assertEqual(certs[1]['course_key'], self.pdf_cert_course.id) self.assertEqual(certs[0]['created'], self.now) self.assertEqual(certs[1]['created'], self.now) self.assertEqual(certs[0]['type'], CourseMode.VERIFIED) self.assertEqual(certs[1]['type'], CourseMode.HONOR) self.assertEqual(certs[0]['status'], CertificateStatuses.downloadable) self.assertEqual(certs[1]['status'], CertificateStatuses.downloadable) self.assertEqual(certs[0]['is_passing'], True) self.assertEqual(certs[1]['is_passing'], True) self.assertEqual(certs[0]['grade'], '0.88') self.assertEqual(certs[1]['grade'], '0.99') self.assertEqual(certs[0]['download_url'], 'www.google.com') self.assertEqual(certs[1]['download_url'], 'www.gmail.com')
def course_runs_with_state(self): """ Determine which course runs have been completed and failed by the user. Returns: dict with a list of completed and failed runs """ course_run_certificates = certificate_api.get_certificates_for_user(self.user.username) completed_runs, failed_runs = [], [] for certificate in course_run_certificates: course_data = { 'course_run_id': unicode(certificate['course_key']), 'type': self._certificate_mode_translation(certificate['type']), } if certificate_api.is_passing_status(certificate['status']): completed_runs.append(course_data) else: failed_runs.append(course_data) return {'completed': completed_runs, 'failed': failed_runs}
def test_get_certificates_for_user(self): """ Test to get all the certificates for a user """ certs = get_certificates_for_user(self.student.username) assert len(certs) == 2 assert certs[0]['username'] == self.student.username assert certs[1]['username'] == self.student.username assert certs[0]['course_key'] == self.web_cert_course.id assert certs[1]['course_key'] == self.pdf_cert_course.id assert certs[0]['created'] == self.now assert certs[1]['created'] == self.now assert certs[0]['type'] == CourseMode.VERIFIED assert certs[1]['type'] == CourseMode.HONOR assert certs[0]['status'] == CertificateStatuses.downloadable assert certs[1]['status'] == CertificateStatuses.downloadable assert certs[0]['is_passing'] is True assert certs[1]['is_passing'] is True assert certs[0]['grade'] == '0.88' assert certs[1]['grade'] == '0.99' assert certs[0]['download_url'] == 'www.google.com' assert certs[1]['download_url'] == 'www.gmail.com'
def search_certificates(request): """ Search for certificates for a particular user OR along with the given course. Supports search by either username or email address along with course id. First filter the records for the given username/email and then filter against the given course id (if given). Show the 'Regenerate' button if a record found in 'generatedcertificate' model otherwise it will show the Generate button. Arguments: request (HttpRequest): The request object. Returns: JsonResponse Example Usage: GET /certificates/[email protected] GET /certificates/[email protected]&course_id=xyz Response: 200 OK Content-Type: application/json [ { "username": "******", "course_key": "edX/DemoX/Demo_Course", "type": "verified", "status": "downloadable", "download_url": "http://www.example.com/cert.pdf", "grade": "0.98", "created": 2015-07-31T00:00:00Z, "modified": 2015-07-31T00:00:00Z } ] """ unbleached_filter = urllib.parse.unquote( urllib.parse.quote_plus(request.GET.get("user", ""))) user_filter = bleach.clean(unbleached_filter) if not user_filter: msg = _("user is not given.") return HttpResponseBadRequest(msg) try: user = User.objects.get(Q(email=user_filter) | Q(username=user_filter)) except User.DoesNotExist: return HttpResponseBadRequest( _("user '{user}' does not exist").format(user=user_filter)) certificates = get_certificates_for_user(user.username) for cert in certificates: cert["course_key"] = str(cert["course_key"]) cert["created"] = cert["created"].isoformat() cert["modified"] = cert["modified"].isoformat() cert["regenerate"] = not cert['is_pdf_certificate'] course_id = urllib.parse.quote_plus(request.GET.get("course_id", ""), safe=':/') if course_id: try: course_key = CourseKey.from_string(course_id) except InvalidKeyError: return HttpResponseBadRequest( _("Course id '{course_id}' is not valid").format( course_id=course_id)) else: try: if CourseOverview.get_from_id(course_key): certificates = [ certificate for certificate in certificates if certificate['course_key'] == course_id ] if not certificates: return JsonResponse([{ 'username': user.username, 'course_key': course_id, 'regenerate': False }]) except CourseOverview.DoesNotExist: msg = _( "The course does not exist against the given key '{course_key}'" ).format(course_key=course_key) return HttpResponseBadRequest(msg) return JsonResponse(certificates)
def search_certificates(request): """ Search for certificates for a particular user OR along with the given course. Supports search by either username or email address along with course id. First filter the records for the given username/email and then filter against the given course id (if given). Show the 'Regenerate' button if a record found in 'generatedcertificate' model otherwise it will show the Generate button. Arguments: request (HttpRequest): The request object. Returns: JsonResponse Example Usage: GET /certificates/[email protected] GET /certificates/[email protected]&course_id=xyz Response: 200 OK Content-Type: application/json [ { "username": "******", "course_key": "edX/DemoX/Demo_Course", "type": "verified", "status": "downloadable", "download_url": "http://www.example.com/cert.pdf", "grade": "0.98", "created": 2015-07-31T00:00:00Z, "modified": 2015-07-31T00:00:00Z } ] """ user_filter = urllib.unquote(urllib.quote_plus(request.GET.get("user", ""))) if not user_filter: msg = _("user is not given.") return HttpResponseBadRequest(msg) try: user = User.objects.get(Q(email=user_filter) | Q(username=user_filter)) except User.DoesNotExist: return HttpResponseBadRequest(_("user '{user}' does not exist").format(user=user_filter)) certificates = api.get_certificates_for_user(user.username) for cert in certificates: cert["course_key"] = unicode(cert["course_key"]) cert["created"] = cert["created"].isoformat() cert["modified"] = cert["modified"].isoformat() cert["regenerate"] = True course_id = urllib.quote_plus(request.GET.get("course_id", ""), safe=':/') if course_id: try: course_key = CourseKey.from_string(course_id) except InvalidKeyError: return HttpResponseBadRequest(_("Course id '{course_id}' is not valid").format(course_id=course_id)) else: try: if CourseOverview.get_from_id(course_key): certificates = [certificate for certificate in certificates if certificate['course_key'] == course_id] if not certificates: return JsonResponse([{'username': user.username, 'course_key': course_id, 'regenerate': False}]) except CourseOverview.DoesNotExist: msg = _("The course does not exist against the given key '{course_key}'").format(course_key=course_key) return HttpResponseBadRequest(msg) return JsonResponse(certificates)
def learner_profile_context(request, profile_username, user_is_staff): """Context for the learner profile page. Args: logged_in_user (object): Logged In user. profile_username (str): username of user whose profile is requested. user_is_staff (bool): Logged In user has staff access. build_absolute_uri_func (): Returns: dict Raises: ObjectDoesNotExist: the specified profile_username does not exist. """ profile_user = User.objects.get(username=profile_username) logged_in_user = request.user own_profile = (logged_in_user.username == profile_username) account_settings_data = get_account_settings(request, [profile_username])[0] preferences_data = get_user_preferences(profile_user, profile_username) #Added by Mahendra user_enrolled_courses = CourseEnrollment.objects.filter( user_id=profile_user.id, is_active=1) cid = [] for courseid in user_enrolled_courses: course_id = courseid.course_id cid.append(course_id) instructor_courses = CourseAccessRole.objects.filter( user_id=profile_user.id, role='instructor') instrsuctor_courseids = [] for courseid in instructor_courses: course_id = courseid.course_id instrsuctor_courseids.append(course_id) try: userprofile_extrainfo = extrafields.objects.get( user_id=profile_user.id) except Exception as e: userprofile_extrainfo, created = extrafields.objects.get_or_create( user_id=profile_user.id) course_data = CourseOverview.objects.all().filter( pk__in=cid).order_by('start')[::-1] instructor_course_delivered = CourseOverview.objects.all().filter( pk__in=instrsuctor_courseids).order_by('start')[::-1] experience_data = experience.objects.all().filter( user=profile_user.id).order_by('-year') education_data = education.objects.all().filter( user=profile_user.id).order_by('-id') award_data = awards.objects.all().filter( user=profile_user.id).order_by('-year') research_data = research_papers.objects.all().filter( user=profile_user.id).order_by('-id') featured_data = media_featured.objects.all().filter( user=profile_user.id).order_by('-id') clinic_hospital_data = clinic_hospital_address.objects.all().filter( user=profile_user.id).order_by('-id') userprofile = UserProfile.objects.get(user_id=profile_user.id) course_certificates = certificate_api.get_certificates_for_user( profile_user.username) awareness_videos = healthcare_awareness_videos.objects.all().filter( user=profile_user.id) context = { 'own_profile': own_profile, 'platform_name': configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME), 'data': { 'profile_user_id': profile_user.id, 'default_public_account_fields': settings.ACCOUNT_VISIBILITY_CONFIGURATION['public_fields'], 'default_visibility': settings.ACCOUNT_VISIBILITY_CONFIGURATION['default_visibility'], 'accounts_api_url': reverse("accounts_api", kwargs={'username': profile_username}), 'preferences_api_url': reverse('preferences_api', kwargs={'username': profile_username}), 'preferences_data': preferences_data, 'account_settings_data': account_settings_data, 'profile_image_upload_url': reverse('profile_image_upload', kwargs={'username': profile_username}), 'profile_image_remove_url': reverse('profile_image_remove', kwargs={'username': profile_username}), 'profile_image_max_bytes': settings.PROFILE_IMAGE_MAX_BYTES, 'profile_image_min_bytes': settings.PROFILE_IMAGE_MIN_BYTES, 'account_settings_page_url': reverse('account_settings'), 'has_preferences_access': (logged_in_user.username == profile_username or user_is_staff), 'own_profile': own_profile, 'country_options': list(countries), 'find_courses_url': marketing_link('COURSES'), 'language_options': settings.ALL_LANGUAGES, 'badges_logo': staticfiles_storage.url('certificates/images/backpack-logo.png'), 'badges_icon': staticfiles_storage.url( 'certificates/images/ico-mozillaopenbadges.png'), 'backpack_ui_img': staticfiles_storage.url('certificates/images/backpack-ui.png'), 'platform_name': configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME), 'social_platforms': settings.SOCIAL_PLATFORMS, }, 'show_program_listing': ProgramsApiConfig.is_enabled(), 'show_dashboard_tabs': True, 'disable_courseware_js': True, 'nav_hidden': True, 'records_url': get_credentials_records_url(), #Added by Mahendra 'instructor_courses': instructor_course_delivered, 'courses': course_data, 'experience_data': experience_data, 'education_data': education_data, 'award_data': award_data, 'research_data': research_data, 'featured_data': featured_data, 'clinic_hospital_data': clinic_hospital_data, 'userprofile': userprofile, 'userprofile_extrainfo': userprofile_extrainfo, 'course_certificates': course_certificates, 'awareness_videos': awareness_videos, } if own_profile or user_is_staff: achievements_fragment = LearnerAchievementsFragmentView( ).render_to_fragment( request, username=profile_user.username, own_profile=own_profile, ) context['achievements_fragment'] = achievements_fragment if badges_enabled(): context['data']['badges_api_url'] = reverse( "badges_api:user_assertions", kwargs={'username': profile_username}) return context
def test_no_certificates_for_user(self): """ Test the case when there are no certificates for a user. """ assert get_certificates_for_user(self.student_no_cert.username) == []