Пример #1
0
    def check_state(self,
                    user,
                    descriptor,
                    expected_score,
                    expected_max_score,
                    expected_attempts=1):
        """
        Check that the StudentModule state contains the expected values.

        The student module is found for the test course, given the `username` and problem `descriptor`.

        Values checked include the number of attempts, the score, and the max score for a problem.
        """
        module = self.get_student_module(user.username, descriptor)
        self.assertEqual(module.grade, expected_score)
        self.assertEqual(module.max_grade, expected_max_score)
        state = json.loads(module.state)
        attempts = state['attempts']
        self.assertEqual(attempts, expected_attempts)
        if attempts > 0:
            self.assertIn('correct_map', state)
            self.assertIn('student_answers', state)
            self.assertGreater(len(state['correct_map']), 0)
            self.assertGreater(len(state['student_answers']), 0)

        # assume only one problem in the subsection and the grades
        # are in sync.
        expected_subsection_grade = expected_score

        course_grade = CourseGradeFactory(user).create(self.course)
        self.assertEquals(
            course_grade.subsection_grade_totals_by_format['Homework']
            [0].earned,
            expected_subsection_grade,
        )
Пример #2
0
def atp_check_certificate(request, course_id):
    log.info("atp_check_certificate start: " +
             str(datetime.datetime.now().strftime("%s")))
    context = {}
    try:
        user = request.user
        username = user.username
        course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
        course = get_course_by_id(course_key)
        is_passed = CourseGradeFactory().create(user, course).passed
        if is_passed:
            certificate_url = '/api/atp/generate/certificate/' + course_id + '/'
        else:
            certificate_url = ''
        context['course_id'] = course_id
        context['username'] = username
        context['passed'] = is_passed
        context['certificate_url'] = certificate_url
        context['microsite'] = is_request_in_microsite()
        context['status'] = True

    except:
        context['status'] = False
        context['message'] = 'Error'

    log.info("atp_check_certificate end: " +
             str(datetime.datetime.now().strftime("%s")))
    return JsonResponse(context)
Пример #3
0
def get_all_course_progress(student, course):
    """
        Return course overall progress percentage for a student
    """

    course_grade = CourseGradeFactory().create(student, course)
    courseware_summary = course_grade.chapter_grades

    total_score = 0
    earned_score = 0

    for week in courseware_summary:
        sections = week.get('sections', [])

        for section in sections:
            total_score += section.all_total.possible
            earned_score += section.all_total.earned

    if total_score:
        average = earned_score / total_score
        percentage = average * 100
    else:
        percentage = 0

    return int(percentage)
Пример #4
0
    def get(self, request, course_id):
        """
        Gets a course progress status.

        Args:
            request (Request): Django request object.
            course_id (string): URI element specifying the course location.

        Return:
            A JSON serialized representation of the requesting user's current grade status.
        """

        course = self._get_course(course_id, request.user, 'load')
        if isinstance(course, Response):
            # Returns a 404 if course_id is invalid, or request.user is not enrolled in the course
            return course

        grade_user = self._get_effective_user(request, course)
        if isinstance(grade_user, Response):
            # Returns a 403 if the request.user can't access grades for the requested user,
            # or a 404 if the requested user does not exist.
            return grade_user

        prep_course_for_grading(course, request)
        course_grade = CourseGradeFactory().create(grade_user, course)
        return Response([{
            'username': grade_user.username,
            'course_key': course_id,
            'passed': course_grade.passed,
            'percent': course_grade.percent,
            'letter_grade': course_grade.letter_grade,
        }])
Пример #5
0
def ensure_certif(request, course_id):
    user_id = request.user.id
    username = request.user.username
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course_tma = get_course_by_id(course_key)
    is_graded = course_tma.is_graded
    grade_cutoffs = modulestore().get_course(
        course_key, depth=0).grade_cutoffs['Pass'] * 100
    grading_note = CourseGradeFactory().create(request.user, course_tma)

    #TMA GRADE TRACKING UPDATE
    mongo_persist = dashboardStats()
    collection = mongo_persist.connect()
    add_user = {}
    add_user['user_id'] = request.user.id
    add_user['username'] = request.user.username
    add_user['passed'] = grading_note.passed
    add_user['percent'] = grading_note.percent
    add_user['summary'] = grading_note.summary
    mongo_persist.add_user_grade_info(collection, str(course_id), add_user)
    # END TMA GRADE TRACKING UPDATE

    passed = grading_note.passed
    percent = float(int(grading_note.percent * 1000) / 10)
    overall_progress = get_overall_progress(request.user.id, course_key)
    context = {
        'passed': passed,
        'percent': percent,
        'is_graded': is_graded,
        'grade_cutoffs': grade_cutoffs,
        'overall_progress': overall_progress
    }

    return JsonResponse(context)
Пример #6
0
 def get_scores(self, user, course_id):
     """
     Return the scores for each qualifiable unit per user in a determinated course.
     """
     course = get_course_with_access(user, 'load', course_id, depth=None, check_if_enrolled=True)
     course_grade = CourseGradeFactory().create(user, course)
     return course_grade.summary
Пример #7
0
def get_grade_book_page(request, course, course_key):
    """
    Get student records per page along with page information i.e current page, total pages and
    offset information.
    """
    # Unsanitized offset
    current_offset = request.GET.get('offset', 0)
    enrolled_students = User.objects.filter(
        courseenrollment__course_id=course_key,
        courseenrollment__is_active=1).order_by('username').select_related(
            "profile")

    total_students = enrolled_students.count()
    page = calculate_page_info(current_offset, total_students)
    offset = page["offset"]
    total_pages = page["total_pages"]

    if total_pages > 1:
        # Apply limit on queryset only if total number of students are greater then MAX_STUDENTS_PER_PAGE_GRADE_BOOK.
        enrolled_students = enrolled_students[offset:offset +
                                              MAX_STUDENTS_PER_PAGE_GRADE_BOOK]

    with modulestore().bulk_operations(course.location.course_key):
        student_info = [{
            'username':
            student.username,
            'id':
            student.id,
            'email':
            student.email,
            'grade_summary':
            CourseGradeFactory().create(student, course).summary
        } for student in enrolled_students]
    return student_info, page
Пример #8
0
def send_composite_outcome(user_id, course_id, assignment_id, version):
    """
    Calculate and transmit the score for a composite module (such as a
    vertical).

    A composite module may contain multiple problems, so we need to
    calculate the total points earned and possible for all child problems. This
    requires calculating the scores for the whole course, which is an expensive
    operation.

    Callers should be aware that the score calculation code accesses the latest
    scores from the database. This can lead to a race condition between a view
    that updates a user's score and the calculation of the grade. If the Celery
    task attempts to read the score from the database before the view exits (and
    its transaction is committed), it will see a stale value. Care should be
    taken that this task is not triggered until the view exits.

    The GradedAssignment model has a version_number field that is incremented
    whenever the score is updated. It is used by this method for two purposes.
    First, it allows the task to exit if it detects that it has been superseded
    by another task that will transmit the score for the same assignment.
    Second, it prevents a race condition where two tasks calculate different
    scores for a single assignment, and may potentially update the campus LMS
    in the wrong order.
    """
    assignment = GradedAssignment.objects.get(id=assignment_id)
    if version != assignment.version_number:
        log.info(
            "Score passback for GradedAssignment %s skipped. More recent score available.",
            assignment.id
        )
        return
    course_key = CourseKey.from_string(course_id)
    mapped_usage_key = assignment.usage_key.map_into_course(course_key)
    user = User.objects.get(id=user_id)
    course = modulestore().get_course(course_key, depth=0)
    course_grade = CourseGradeFactory().create(user, course)
    earned, possible = course_grade.score_for_module(mapped_usage_key)
    if possible == 0:
        weighted_score = 0
    else:
        weighted_score = float(earned) / float(possible)

    assignment = GradedAssignment.objects.get(id=assignment_id)
    if assignment.version_number == version:
        outcomes.send_score_update(assignment, weighted_score)
Пример #9
0
    def assert_course_grade(self, user, expected_percent):
        """
        Verifies the given user's course grade is the expected percentage.
        Also verifies the user's grade information contains values for
        all problems in the course, whether or not they are currently
        gated.
        """
        course_grade = CourseGradeFactory().create(user, self.course)
        for prob in [self.gating_prob1, self.gated_prob2, self.prob3]:
            self.assertIn(prob.location, course_grade.locations_to_scores)

        self.assertEquals(course_grade.percent, expected_percent)
Пример #10
0
def ccx_grades_csv(request, course, ccx=None):
    """
    Download grades as CSV.
    """
    if not ccx:
        raise Http404

    ccx_key = CCXLocator.from_course_locator(course.id, unicode(ccx.id))
    with ccx_course(ccx_key) as course:
        prep_course_for_grading(course, request)

        enrolled_students = User.objects.filter(
            courseenrollment__course_id=ccx_key,
            courseenrollment__is_active=1).order_by('username').select_related(
                "profile")
        grades = CourseGradeFactory().iter(course, enrolled_students)

        header = None
        rows = []
        for student, course_grade, __ in grades:
            if course_grade:
                # We were able to successfully grade this student for this
                # course.
                if not header:
                    # Encode the header row in utf-8 encoding in case there are
                    # unicode characters
                    header = [
                        section['label'].encode('utf-8') for section in
                        course_grade.summary[u'section_breakdown']
                    ]
                    rows.append(["id", "email", "username", "grade"] + header)

                percents = {
                    section['label']: section.get('percent', 0.0)
                    for section in course_grade.summary[u'section_breakdown']
                    if 'label' in section
                }

                row_percents = [percents.get(label, 0.0) for label in header]
                rows.append([
                    student.id, student.email, student.username,
                    course_grade.percent
                ] + row_percents)

        buf = StringIO()
        writer = csv.writer(buf)
        for row in rows:
            writer.writerow(row)

        response = HttpResponse(buf.getvalue(), content_type='text/csv')
        response['Content-Disposition'] = 'attachment'

        return response
Пример #11
0
 def handle(self, *args, **options):
     course_id = options['course']
     log.info('Fetching ungraded students for %s.', course_id)
     ungraded = GeneratedCertificate.objects.filter(  # pylint: disable=no-member
         course_id__exact=course_id).filter(grade__exact='')
     course = courses.get_course_by_id(course_id)
     for cert in ungraded:
         # grade the student
         grade = CourseGradeFactory().create(cert.user, course)
         log.info('grading %s - %s', cert.user, grade.percent)
         cert.grade = grade.percent
         if not options['noop']:
             cert.save()
Пример #12
0
def atp_generate_certificate(request, course_id):
    log.info("atp_generate_certificate start: " +
             str(datetime.datetime.now().strftime("%s")))
    context = {}
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="certificate.pdf"'
    user = request.user
    username = user.username
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course = get_course_by_id(course_key)
    categorie = course.categ
    course_factory = CourseGradeFactory().get_persisted(user, course)
    is_passed = course_factory.passed
    courseoverview = CourseOverview.get_from_id(course_key)
    course_title = courseoverview.display_name_with_default
    _temp_score = int(course_factory.percent * 1000)
    score = str(float(_temp_score / 10)) + '%'
    url = 'https://' + settings.FEATURES['LMS_BASE']

    if configuration_helpers.get_value('logo_couleur'):
        logo_path = configuration_helpers.get_value('logo_couleur')
    else:
        logo_path = '/media/certificates/images/logo-amundi.jpg'
    if configuration_helpers.get_value(
            'amundi_brand') and configuration_helpers.get_value(
                'amundi_brand') == "true":
        amundi_academy = '/media/certificates/images/logo-amundi-academy.jpg'
    else:
        amundi_academy = ''
    if configuration_helpers.get_value('primary_color'):
        primary_color = configuration_helpers.get_value('primary_color')
    else:
        primary_color = ''
    if configuration_helpers.get_value('secondary_color'):
        secondary_color = configuration_helpers.get_value('secondary_color')
    else:
        secondary_color = ''

    course_img_path = courseoverview.image_urls['raw']
    course_img_path = url + course_img_path
    template_path = '/certificates/template.html'
    certif_img_path = url + '/media/certificates/images/tampon.png'

    #return HttpResponse(pdf)
    return generate_html(username, score, course_img_path, template_path,
                         course_title, categorie, certif_img_path, logo_path,
                         amundi_academy, course.language,
                         user.first_name + ' ' + user.last_name, primary_color,
                         secondary_color)
Пример #13
0
 def _add_entrance_exam_to_context(self, courseware_context):
     """
     Adds entrance exam related information to the given context.
     """
     if course_has_entrance_exam(self.course) and getattr(
             self.chapter, 'is_entrance_exam', False):
         courseware_context[
             'entrance_exam_passed'] = user_has_passed_entrance_exam(
                 self.effective_user, self.course)
         courseware_context[
             'entrance_exam_current_score'] = get_entrance_exam_score_ratio(
                 CourseGradeFactory().create(self.effective_user,
                                             self.course),
                 get_entrance_exam_usage_key(self.course),
             )
Пример #14
0
    def get(self, request, course_id):
        """
        Gets a course progress status.

        Args:
            request (Request): Django request object.
            course_id (string): URI element specifying the course location.

        Return:
            A JSON serialized representation of the requesting user's current grade status.
        """
        username = request.GET.get('username')

        # only the student can access her own grade status info
        if request.user.username != username:
            log.info('User %s tried to access the grade for user %s.',
                     request.user.username, username)
            return self.make_error_response(
                status_code=status.HTTP_404_NOT_FOUND,
                developer_message=
                'The user requested does not match the logged in user.',
                error_code='user_mismatch')

        course = self._get_course(course_id, request.user, 'load')
        if isinstance(course, Response):
            return course

        prep_course_for_grading(course, request)
        course_grade = CourseGradeFactory(request.user).create(course)
        if not course_grade.has_access_to_course:
            # This means the student didn't have access to the course
            log.info('User %s not allowed to access grade for course %s',
                     request.user.username, username)
            return self.make_error_response(
                status_code=status.HTTP_403_FORBIDDEN,
                developer_message=
                'The user does not have access to the course.',
                error_code='user_does_not_have_access_to_course')

        return Response([{
            'username': username,
            'course_key': course_id,
            'passed': course_grade.passed,
            'percent': course_grade.percent,
            'letter_grade': course_grade.letter_grade,
        }])
Пример #15
0
def ensure_certif(request, course_id):
    user_id = request.user.id
    username = request.user.username
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course_tma = get_course_by_id(course_key)
    is_graded = course_tma.is_graded
    grade_cutoffs = modulestore().get_course(
        course_key, depth=0).grade_cutoffs['Pass'] * 100
    grading_note = CourseGradeFactory().create(request.user, course_tma)
    passed = grading_note.passed
    percent = float(int(grading_note.percent * 1000) / 10)
    overall_progress = get_overall_progress(request.user.id, course_key)
    context = {
        'passed': passed,
        'percent': percent,
        'is_graded': is_graded,
        'grade_cutoffs': grade_cutoffs,
        'overall_progress': overall_progress
    }

    return JsonResponse(context)
Пример #16
0
def send_grade_report(microsite, course_id, register_form, certificate_form,
                      report_fields, receivers):
    #Get report info
    course_key = CourseKey.from_string(course_id)
    course = get_course_by_id(course_key)

    #Dict of labels
    form_labels = {}
    for field in register_form:
        form_labels[field.get('name')] = field.get('label')
    for field in certificate_form:
        form_labels[field.get('name')] = field.get('label')
    form_labels['last_connexion'] = "Dernière connexion"
    form_labels['inscription_date'] = "Date d'inscription"
    form_labels['user_id'] = 'Id Utilisateur'
    form_labels['email'] = 'Email'
    form_labels['grade_final'] = 'Note finale'
    form_labels['cohorte_names'] = "Nom de la cohorte"

    #Form Factory
    form_factory = ensure_form_factory()
    form_factory_db = 'ensure_form'
    form_factory_collection = 'certificate_form'
    form_factory.connect(db=form_factory_db,
                         collection=form_factory_collection)

    #get workbook
    wb = Workbook(encoding='utf-8')
    filename = '/home/edxtma/csv/{}_{}.xls'.format(
        time.strftime("%Y_%m_%d"), course.display_name_with_default)
    sheet = wb.add_sheet('Stats')

    #Prepare header
    log.info('report_fields {}'.format(report_fields))
    cell = 0
    for field in report_fields:
        if field == "grade_detailed":
            grade_detail_labels = []
            for evaluation in course._grading_policy['RAW_GRADER']:
                grade_detail_labels.append(evaluation['type'])
                sheet.write(0, cell, evaluation['type'])
                cell += 1
        else:
            sheet.write(0, cell, form_labels.get(field))
            cell += 1

    if "cohorte_names" in report_fields:
        cohortes = CourseUserGroup.objects.filter(course_id=course_key)
        cohortes_names = {}
        for cohorte in cohortes:
            cohortes_names[cohorte.id] = cohorte.name

    #Get user report info
    course_enrollments = CourseEnrollment.objects.filter(course_id=course_key)

    line = 1
    for enrollment in course_enrollments:
        cell = 0
        user = enrollment.user
        user_grade = CourseGradeFactory().create(user, course)
        grade_summary = {}
        for section_grade in user_grade.grade_value['section_breakdown']:
            grade_summary[section_grade['category']] = section_grade['percent']
        try:
            custom_field = json.loads(
                UserProfile.objects.get(user=user).custom_field)
        except:
            custom_field = {}

        user_certificate_info = {}
        form_factory.microsite = microsite
        form_factory.user_id = user.id

        try:
            user_certificate_info = form_factory.getForm(
                user_id=True, microsite=True).get('form')
        except:
            pass

        for field in report_fields:
            if field == "last_connexion":
                try:
                    last_login = user.last_login.strftime('%d-%m-%y')
                except:
                    last_login = ''
                sheet.write(line, cell, last_login)
                cell += 1
            elif field == "inscription_date":
                try:
                    date_joined = user.date_joined.strftime('%d-%m-%y')
                except:
                    date_joined = ''
                sheet.write(line, cell, date_joined)
                cell += 1
            elif field == "user_id":
                sheet.write(line, cell, user.id)
                cell += 1
            elif field == "email":
                sheet.write(line, cell, user.email)
                cell += 1
            elif field == "cohorte_names":
                cohortes_list = ''
                if CohortMembership.objects.filter(course_id=course_key,
                                                   user_id=user.id).exists():
                    user_cohortes = CohortMembership.objects.filter(
                        course_id=course_key, user_id=user.id)
                    log.info('user cohorteeeeeeeeeeessssssss{}'.format(
                        user_cohortes))
                    for cohorte in user_cohortes:
                        cohortes_list += cohortes_names[
                            cohorte.course_user_group_id] + " "
                sheet.write(line, cell, cohortes_list)
                cell += 1
            elif field == "grade_detailed":
                for section in grade_detail_labels:
                    section_grade = str(
                        int(round(grade_summary[section] * 100))) + '%'
                    sheet.write(line, cell, section_grade)
                    cell += 1

            elif field == "grade_final":
                percent = str(int(round(user_grade.percent * 100))) + '%'
                sheet.write(line, cell, percent)
                cell += 1
            elif field in user_certificate_info.keys():
                certificate_value = user_certificate_info.get(field)
                sheet.write(line, cell, certificate_value)
                cell += 1
            else:
                try:
                    user_data = custom_field[field]
                except:
                    user_data = ""
                sheet.write(line, cell, user_data)
                cell += 1

        line += 1
        log.warning("file ok")

        #Save the file
        output = BytesIO()
        wb.save(output)
        _files_values = output.getvalue()
    log.warning("file saved")

    html = "<html><head></head><body><p>Bonjour,<br/><br/>Vous trouverez en PJ le rapport de donnees du MOOC {}<br/><br/>Bonne reception<br>The MOOC Agency<br></p></body></html>".format(
        course.display_name)
    part2 = MIMEText(html.encode('utf-8'), 'html', 'utf-8')

    for receiver in receivers:
        fromaddr = "*****@*****.**"
        toaddr = str(receiver)
        msg = MIMEMultipart()
        msg['From'] = fromaddr
        msg['To'] = toaddr
        msg['Subject'] = "Rapport des reussites"
        attachment = _files_values
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(attachment)
        encoders.encode_base64(part)
        part.add_header(
            'Content-Disposition',
            "attachment; filename= %s" % os.path.basename(filename))
        msg.attach(part)
        server = smtplib.SMTP('mail3.themoocagency.com', 25)
        server.starttls()
        server.login('contact', 'waSwv6Eqer89')
        msg.attach(part2)
        text = msg.as_string()
        server.sendmail(fromaddr, toaddr, text)
        server.quit()
        log.warning("file sent to {}".format(receiver))

    response = {'path': filename, 'send_to': receivers}

    return response
    def task_generate_xls(self):
        log.info('Start task generate XLS')
        #Get report infos
        self.microsite = self.request.get('microsite')
        report_fields = self.request.get('form')
        register_fields = self.request.get('register_form')
        certificate_fields = self.request.get('certificate_form')
        course_key = CourseKey.from_string(self.course_id)
        course = get_course_by_id(course_key)

        form_factory = ensure_form_factory()
        form_factory.connect(db='ensure_form', collection='certificate_form')

        #Dict of labels
        form_labels = {
            "last_connexion": _("Last login"),
            "inscription_date": _("Register date"),
            "user_id": _("User id"),
            "email": _("Email"),
            "grade_final": _("Final Grade"),
            "cohorte_names": _("Cohorte name"),
            "time_tracking": _("Time spent"),
            "certified": _("Attestation"),
            "username": _("Username"),
        }
        for field in register_fields:
            form_labels[field.get('name')] = field.get('label')
        for field in certificate_fields:
            form_labels[field.get('name')] = field.get('label')

        #Identify multiple cells fields
        multiple_cell_fields = ["exercises_grade", "grade_detailed"]

        #Is report cohort specific?
        course_cohorted = is_course_cohorted(course_key)
        if course_cohorted:
            cohortes_targeted = [
                field.replace('cohort_selection_', '')
                for field in report_fields
                if field.find('cohort_selection_') > -1
            ]
            for field in report_fields:
                log.info(field)
                log.info(field.find('cohort_selection_'))
            log.info(cohortes_targeted)
            log.info('cohortes_targeted')
            if cohortes_targeted and not 'cohorte_names' in report_fields:
                report_fields.append('cohorte_names')
        else:
            if 'cohorte_names' in report_fields:
                report_fields.remove('cohorte_names')

        #Get Graded block for exercises_grade details
        graded_scorable_blocks = self.tma_graded_scorable_blocks_to_header(
            course_key)

        #Create Workbook
        wb = Workbook(encoding='utf-8')
        filename = '/home/edxtma/csv/{}_{}.xls'.format(
            time.strftime("%Y_%m_%d"), course.display_name_with_default)
        sheet = wb.add_sheet('Grade Report')

        #Write information
        line = 1
        course_enrollments = CourseEnrollment.objects.filter(
            course_id=course_key, is_active=1)
        for enrollment in course_enrollments:
            #do not include in reports if not active
            if not enrollment.is_active:
                continue
            #Gather user information
            user = enrollment.user
            user_grade = CourseGradeFactory().create(user, course)
            grade_summary = {}

            if course_cohorted:
                user_cohorte = get_cohort(user, course_key).name
                #if cohort specific report avoid student that are not part of cohortes_targeted provided
                if cohortes_targeted and not user_cohorte in cohortes_targeted:
                    continue

            for section_grade in user_grade.grade_value['section_breakdown']:
                grade_summary[
                    section_grade['category']] = section_grade['percent']
            try:
                custom_field = json.loads(
                    UserProfile.objects.get(user=user).custom_field)
            except:
                custom_field = {}

            user_certificate_info = {}
            try:
                form_factory.microsite = self.microsite
                form_factory.user_id = user.id
                user_certificate_info = form_factory.getForm(
                    user_id=True, microsite=True).get('form')
            except:
                pass

            cell = 0
            for field in report_fields:
                if field in multiple_cell_fields:
                    if field == "grade_detailed":
                        for section in grade_summary:
                            section_grade = str(
                                int(round(grade_summary[section] * 100))) + '%'
                            sheet.write(line, cell, section_grade)
                            #Write header
                            if line == 1:
                                sheet.write(0, cell, "Travail - " + section)
                            cell += 1
                    elif field == "exercises_grade":
                        for block_location in graded_scorable_blocks.items():
                            try:
                                problem_score = user_grade.locations_to_scores[
                                    block_location[0]]
                                if problem_score.attempted:
                                    value = round(
                                        float(problem_score.earned) /
                                        problem_score.possible, 2)
                                else:
                                    value = _('n.a.')
                            except:
                                value = _('inv.')
                            sheet.write(line, cell, value)
                            if line == 1:
                                sheet.write(0, cell, block_location[1])
                            cell += 1
                else:
                    value = ''
                    if field == "user_id":
                        value = user.id
                    elif field == "email":
                        value = user.email
                    elif field == "first_name":
                        try:
                            if user.first_name:
                                value = user.first_name
                            elif custom_field:
                                value = custom_field.get(
                                    'first_name', 'unkowna')
                            else:
                                value = 'unknown'
                        except:
                            value = 'unknown'
                    elif field == "last_name":
                        try:
                            if user.last_name:
                                value = user.last_name
                            elif custom_field:
                                value = custom_field.get(
                                    'last_name', 'unkowna')
                        except:
                            value = 'unknown'
                    elif field == "last_connexion":
                        try:
                            value = user.last_login.strftime('%d-%m-%y')
                        except:
                            value = ''
                    elif field == "inscription_date":
                        try:
                            value = user.date_joined.strftime('%d-%m-%y')
                        except:
                            value = ''
                    elif field == "cohorte_names":
                        try:
                            value = user_cohorte
                        except:
                            value = ''
                    elif field == "time_tracking":
                        value = self.get_time_tracking(enrollment)
                    elif field == "certified":
                        if user_grade.passed:
                            value = _("Yes")
                        else:
                            value = _("No")
                    elif field == "grade_final":
                        value = str(int(round(user_grade.percent * 100))) + '%'
                    elif field == "username":
                        value = user.username
                    elif field in user_certificate_info.keys():
                        value = user_certificate_info.get(field)
                    else:
                        value = custom_field.get(field, '')
                    #Write header and write value
                    log.info('field')
                    log.info(field)
                    log.info('value')
                    log.info(value)
                    log.info(form_labels)
                    if field in form_labels.keys():
                        sheet.write(line, cell, value)
                        if line == 1:
                            sheet.write(0, cell, form_labels.get(field))
                        cell += 1
            line += 1
            log.warning("file ok")

        #Save the file
        output = BytesIO()
        wb.save(output)
        _files_values = output.getvalue()
        log.warning("file saved")

        #Send the email to receivers
        receivers = self.request.get('send_to')

        html = "<html><head></head><body><p>Bonjour,<br/><br/>Vous trouverez en PJ le rapport de donnees du MOOC {}<br/><br/>Bonne reception<br>The MOOC Agency<br></p></body></html>".format(
            course.display_name)
        part2 = MIMEText(html.encode('utf-8'), 'html', 'utf-8')

        for receiver in receivers:
            fromaddr = "*****@*****.**"
            toaddr = str(receiver)
            msg = MIMEMultipart()
            msg['From'] = fromaddr
            msg['To'] = toaddr
            msg['Subject'] = "Rapport de donnees"
            attachment = _files_values
            part = MIMEBase('application', 'octet-stream')
            part.set_payload(attachment)
            encoders.encode_base64(part)
            part.add_header(
                'Content-Disposition',
                "attachment; filename= %s" % os.path.basename(filename))
            msg.attach(part)
            server = smtplib.SMTP('mail3.themoocagency.com', 25)
            server.starttls()
            server.login('contact', 'waSwv6Eqer89')
            msg.attach(part2)
            text = msg.as_string()
            server.sendmail(fromaddr, toaddr, text)
            server.quit()
            log.warning("file sent to {}".format(receiver))

        response = {'path': self.filename, 'send_to': receivers}

        return response
Пример #18
0
    def handle(self, *args, **options):
        if os.path.exists(options['output']):
            raise CommandError("File {0} already exists".format(
                options['output']))

        status_interval = 100

        # parse out the course into a coursekey
        if options['course']:
            try:
                course_key = CourseKey.from_string(options['course'])
            # if it's not a new-style course key, parse it from an old-style
            # course key
            except InvalidKeyError:
                course_key = SlashSeparatedCourseKey.from_deprecated_string(
                    options['course'])

        print "Fetching enrolled students for {0}".format(course_key)
        enrolled_students = User.objects.filter(
            courseenrollment__course_id=course_key)
        factory = RequestMock()
        request = factory.get('/')

        total = enrolled_students.count()
        print "Total enrolled: {0}".format(total)
        course = courses.get_course_by_id(course_key)
        total = enrolled_students.count()
        start = datetime.datetime.now()
        rows = []
        header = None
        print "Fetching certificate data"
        cert_grades = {
            cert.user.username: cert.grade
            for cert in list(
                GeneratedCertificate.objects.filter(  # pylint: disable=no-member
                    course_id=course_key).prefetch_related('user'))
        }
        print "Grading students"
        for count, student in enumerate(enrolled_students):
            count += 1
            if count % status_interval == 0:
                # Print a status update with an approximation of
                # how much time is left based on how long the last
                # interval took
                diff = datetime.datetime.now() - start
                timeleft = diff * (total - count) / status_interval
                hours, remainder = divmod(timeleft.seconds, 3600)
                minutes, __ = divmod(remainder, 60)
                print "{0}/{1} completed ~{2:02}:{3:02}m remaining".format(
                    count, total, hours, minutes)
                start = datetime.datetime.now()
            request.user = student
            grade = CourseGradeFactory().create(student, course)
            if not header:
                header = [
                    section['label']
                    for section in grade.summary[u'section_breakdown']
                ]
                rows.append(
                    ["email", "username", "certificate-grade", "grade"] +
                    header)
            percents = {
                section['label']: section['percent']
                for section in grade.summary[u'section_breakdown']
            }
            row_percents = [percents[label] for label in header]
            if student.username in cert_grades:
                rows.append([
                    student.email, student.username,
                    cert_grades[student.username], grade.percent
                ] + row_percents, )
            else:
                rows.append(
                    [student.email, student.username, "N/A", grade.percent] +
                    row_percents)
        with open(options['output'], 'wb') as f:
            writer = csv.writer(f)
            writer.writerows(rows)
Пример #19
0
    def tma_users_registered(self):
        context = {}
        enrolled_to_current_course = False
        user_email = self.request.POST['user_email']

        if User.objects.filter(email=user_email).exists():
            user = User.objects.get(email=user_email)
            #Get preprofile info
            userprofile = UserProfile.objects.get(user=user)
            try:
                custom_field = json.loads(user.profile.custom_field)
                first_name = custom_field['first_name']
                last_name = custom_field['last_name']
            except:
                custom_field = {}
                last_name = 'Undefined'
                first_name = 'Undefined'

            #Get courses enrollments
            microsite_courses = get_courses(
                user=user,
                org=configuration_helpers.get_value('course_org_filter'))

            user_ms_course_list = {}
            for course in microsite_courses:
                if CourseEnrollment.objects.filter(
                        user=user, course_id=course.id).exists():
                    user_ms_course_list[str(course.id)] = {
                        'course_name':
                        course.display_name_with_default,
                        'course_grades':
                        '/courses/' + str(course.id) + '/progress/' +
                        str(user.id),
                        'opened_enrollments':
                        is_enrollment_opened(course),
                        'opened_course':
                        is_course_opened(course),
                        'on_invitation':
                        course.invitation_only,
                    }

            #Get user grade for this course
            course_key = SlashSeparatedCourseKey.from_deprecated_string(
                self.course_id)
            current_course = get_course_by_id(course_key)
            grade = CourseGradeFactory().create(user, current_course)

            #User dates
            if user.last_login is not None:
                last_login = user.date_joined.strftime("%d-%b-%Y %H:%M:%S")
            else:
                last_login = _('User has not logged in yet')

            context = {
                'email': str(user_email),
                'id': str(user.id),
                'inscription':
                str(user.date_joined.strftime("%d-%b-%Y %H:%M:%S")),
                'last_login': last_login,
                'first_name': first_name,
                'last_name': last_name,
                'user_ms_course_list': user_ms_course_list,
                'custom_field': custom_field,
                'grade': grade.grade_value['percent'],
                'passed': grade.grade_value['grade'],
                'active': user.is_active,
                'login_failure': LoginFailures.is_user_locked_out(user),
            }

            #Check if user is registered to this course
            course_key = SlashSeparatedCourseKey.from_deprecated_string(
                self.course_id)
            if CourseEnrollment.objects.filter(user=user,
                                               course_id=course_key,
                                               is_active=1).exists():
                current_course_grades = '/courses/' + str(
                    self.course_id) + '/progress/' + str(user.id)
                context['enrolled_to_current_course'] = True
                context['current_course_grades'] = current_course_grades
            else:
                context['enrolled_to_current_course'] = False

        else:
            context = {
                'error':
                'Le participant n\'a pas de compte sur nos plateformes.'
            }

        return context
Пример #20
0
    def add_cert(self,
                 student,
                 course_id,
                 course=None,
                 forced_grade=None,
                 template_file=None,
                 generate_pdf=True):
        """
        Request a new certificate for a student.

        Arguments:
          student   - User.object
          course_id - courseenrollment.course_id (CourseKey)
          forced_grade - a string indicating a grade parameter to pass with
                         the certificate request. If this is given, grading
                         will be skipped.
          generate_pdf - Boolean should a message be sent in queue to generate certificate PDF

        Will change the certificate status to 'generating' or
        `downloadable` in case of web view certificates.

        The course must not be a CCX.

        Certificate must be in the 'unavailable', 'error',
        'deleted' or 'generating' state.

        If a student has a passing grade or is in the whitelist
        table for the course a request will be made for a new cert.

        If a student has allow_certificate set to False in the
        userprofile table the status will change to 'restricted'

        If a student does not have a passing grade the status
        will change to status.notpassing

        Returns the newly created certificate instance
        """

        if hasattr(course_id, 'ccx'):
            LOGGER.warning(
                (u"Cannot create certificate generation task for user %s "
                 u"in the course '%s'; "
                 u"certificates are not allowed for CCX courses."), student.id,
                unicode(course_id))
            return None

        valid_statuses = [
            status.generating,
            status.unavailable,
            status.deleted,
            status.error,
            status.notpassing,
            status.downloadable,
            status.auditing,
            status.audit_passing,
            status.audit_notpassing,
        ]

        cert_status = certificate_status_for_student(student,
                                                     course_id)['status']
        cert = None

        if cert_status not in valid_statuses:
            LOGGER.warning(
                (u"Cannot create certificate generation task for user %s "
                 u"in the course '%s'; "
                 u"the certificate status '%s' is not one of %s."), student.id,
                unicode(course_id), cert_status, unicode(valid_statuses))
            return None

        # The caller can optionally pass a course in to avoid
        # re-fetching it from Mongo. If they have not provided one,
        # get it from the modulestore.
        if course is None:
            course = modulestore().get_course(course_id, depth=0)

        profile = UserProfile.objects.get(user=student)
        profile_name = profile.name

        # Needed for access control in grading.
        self.request.user = student
        self.request.session = {}

        is_whitelisted = self.whitelist.filter(user=student,
                                               course_id=course_id,
                                               whitelist=True).exists()
        grade = CourseGradeFactory().create(student, course).summary
        enrollment_mode, __ = CourseEnrollment.enrollment_mode_for_user(
            student, course_id)
        mode_is_verified = enrollment_mode in GeneratedCertificate.VERIFIED_CERTS_MODES
        user_is_verified = SoftwareSecurePhotoVerification.user_is_verified(
            student)
        cert_mode = enrollment_mode
        is_eligible_for_certificate = is_whitelisted or CourseMode.is_eligible_for_certificate(
            enrollment_mode)
        unverified = False
        # For credit mode generate verified certificate
        if cert_mode == CourseMode.CREDIT_MODE:
            cert_mode = CourseMode.VERIFIED

        if template_file is not None:
            template_pdf = template_file
        elif mode_is_verified and user_is_verified:
            template_pdf = "certificate-template-{id.org}-{id.course}-verified.pdf".format(
                id=course_id)
        elif mode_is_verified and not user_is_verified:
            template_pdf = "certificate-template-{id.org}-{id.course}.pdf".format(
                id=course_id)
            if CourseMode.mode_for_course(course_id, CourseMode.HONOR):
                cert_mode = GeneratedCertificate.MODES.honor
            else:
                unverified = True
        else:
            # honor code and audit students
            template_pdf = "certificate-template-{id.org}-{id.course}.pdf".format(
                id=course_id)
        if forced_grade:
            grade['grade'] = forced_grade

        LOGGER.info((
            u"Certificate generated for student %s in the course: %s with template: %s. "
            u"given template: %s, "
            u"user is verified: %s, "
            u"mode is verified: %s"), student.username, unicode(course_id),
                    template_pdf, template_file, user_is_verified,
                    mode_is_verified)

        cert, created = GeneratedCertificate.objects.get_or_create(
            user=student, course_id=course_id)  # pylint: disable=no-member

        cert.mode = cert_mode
        cert.user = student
        cert.grade = grade['percent']
        cert.course_id = course_id
        cert.name = profile_name
        cert.download_url = ''

        # Strip HTML from grade range label
        grade_contents = grade.get('grade', None)
        try:
            grade_contents = lxml.html.fromstring(
                grade_contents).text_content()
            passing = True
        except (TypeError, XMLSyntaxError, ParserError) as exc:
            LOGGER.info((u"Could not retrieve grade for student %s "
                         u"in the course '%s' "
                         u"because an exception occurred while parsing the "
                         u"grade contents '%s' as HTML. "
                         u"The exception was: '%s'"), student.id,
                        unicode(course_id), grade_contents, unicode(exc))

            # Log if the student is whitelisted
            if is_whitelisted:
                LOGGER.info(u"Student %s is whitelisted in '%s'", student.id,
                            unicode(course_id))
                passing = True
            else:
                passing = False

        # If this user's enrollment is not eligible to receive a
        # certificate, mark it as such for reporting and
        # analytics. Only do this if the certificate is new, or
        # already marked as ineligible -- we don't want to mark
        # existing audit certs as ineligible.
        cutoff = settings.AUDIT_CERT_CUTOFF_DATE
        if (cutoff and cert.created_date >= cutoff
            ) and not is_eligible_for_certificate:
            cert.status = CertificateStatuses.audit_passing if passing else CertificateStatuses.audit_notpassing
            cert.save()
            LOGGER.info(
                u"Student %s with enrollment mode %s is not eligible for a certificate.",
                student.id, enrollment_mode)
            return cert
        # If they are not passing, short-circuit and don't generate cert
        elif not passing:
            cert.status = status.notpassing
            cert.save()

            LOGGER.info(
                (u"Student %s does not have a grade for '%s', "
                 u"so their certificate status has been set to '%s'. "
                 u"No certificate generation task was sent to the XQueue."),
                student.id, unicode(course_id), cert.status)
            return cert

        # Check to see whether the student is on the the embargoed
        # country restricted list. If so, they should not receive a
        # certificate -- set their status to restricted and log it.
        if self.restricted.filter(user=student).exists():
            cert.status = status.restricted
            cert.save()

            LOGGER.info(
                (u"Student %s is in the embargoed country restricted "
                 u"list, so their certificate status has been set to '%s' "
                 u"for the course '%s'. "
                 u"No certificate generation task was sent to the XQueue."),
                student.id, cert.status, unicode(course_id))
            return cert

        if unverified:
            cert.status = status.unverified
            cert.save()
            LOGGER.info(
                (u"User %s has a verified enrollment in course %s "
                 u"but is missing ID verification. "
                 u"Certificate status has been set to unverified"),
                student.id,
                unicode(course_id),
            )
            return cert

        # Finally, generate the certificate and send it off.
        return self._generate_cert(cert, course, student, grade_contents,
                                   template_pdf, generate_pdf)
Пример #21
0
    def export(self, sended_email):
        reload(sys)
        sys.setdefaultencoding('utf8')

        log.warning("export: Start Task grade reports course_id : " +
                    str(self.course_id))
        course_key = CourseKey.from_string(self.course_id)
        course = get_course_by_id(course_key)
        course_enrollement = CourseEnrollment.objects.filter(
            course_id=course_key)

        #prepare xls
        header = [
            "id", "email", "first name", "last name", "level 1", "level 2",
            "level 3", "level 4"
        ]

        # Email content
        language_setup = {
            "en": {
                "subject":
                "Score report for {}",
                "text_content":
                "Please, find attached the score report for {}.\nRemember that if your training campaign is still in progress, this file is an intermediate statistical status."
            },
            "fr": {
                "subject":
                "Résultats des participants du module {}",
                "text_content":
                "Veuillez trouver en pièce attachée les résultats des participants pour le module {}.\nA noter que si votre campagne de formation est toujours en cours, ce fichier constitue un état statistique intermédiaire."
            }
        }

        title = self.get_titles()

        for n in title:
            header.append(n.get('unit') + ' - ' + n.get('title'))

        header.append('total grade (in %)')

        filename = '{}_grades_reports.xls'.format(self.course_id).replace(
            '+', '_')

        wb = Workbook(encoding='utf-8')
        sheet = wb.add_sheet('Users')

        for i, head in enumerate(header):
            sheet.write(0, i, head)

        j = 0

        for i in range(len(course_enrollement)):

            j = j + 1

            user = course_enrollement[i].user
            course_grade = CourseGradeFactory().create(user, course)

            user_id = user.id
            email = user.email
            first_name = user.first_name
            last_name = user.last_name
            log.info("export: getting grade for user: "******"", "", "", ""]

            final_grade = course_grade.percent * 100

            _user_blocks = self._user(user_id)

            sheet.write(j, 0, user_id)
            sheet.write(j, 1, email)
            sheet.write(j, 2, first_name)
            sheet.write(j, 3, last_name)
            sheet.write(j, 4, _lvl[0])
            sheet.write(j, 5, _lvl[1])
            sheet.write(j, 6, _lvl[2])
            sheet.write(j, 7, _lvl[3])

            k = 8

            for val in title:
                _grade = 0
                for block in _user_blocks:

                    if block.get('root') == val.get('root'):
                        _grade = block.get('earned')

                sheet.write(j, k, _grade)

                k = k + 1

            sheet.write(j, k, final_grade)

        output = BytesIO()
        wb.save(output)
        _files_values = output.getvalue()

        log.warning("End Task grade reports course_id : " +
                    str(self.course_id))

        #sending mail
        log.warning("send grade reports course_id : " + str(filename))
        log.warning("email5 : " + str(sended_email))

        # Email content according to course language (look for #Email content to add new languages)
        subject = ''
        text_content = ''
        if course.language in language_setup:
            subject = language_setup[course.language]['subject'].format(
                course.display_name_with_default_escaped)
            text_content = language_setup[
                course.language]['text_content'].format(
                    course.display_name_with_default_escaped)
        else:
            subject = language_setup['en']['subject'].format(
                course.display_name_with_default_escaped)
            text_content = language_setup['en']['text_content'].format(
                course.display_name_with_default_escaped)

        from_email = configuration_helpers.get_value(
            'email_from_address', settings.DEFAULT_FROM_EMAIL)
        to = sended_email
        mimetype = 'application/vnd.ms-excel'
        fail_silently = False
        _data = _files_values
        #_encoded = base64.b64encode(wb)
        log.warning("end send grade : right before email is sent out")
        _email = EmailMessage(subject, text_content, from_email, [to])
        _email.attach(filename, _data, mimetype=mimetype)
        _email.send(fail_silently=fail_silently)

        log.warning("end send grade reports course_id : " + str(filename))

        context = {"filename": filename}

        return context
Пример #22
0
    def get(self, request, course_id):
        """
        Gets a course progress status.

        Args:
            request (Request): Django request object.
            course_id (string): URI element specifying the course location.

        Return:
            A JSON serialized representation of the requesting user's current grade status.
        """
        username = request.GET.get('username')

        # only the student can access her own grade status info
        if request.user.username != username:
            log.info('User %s tried to access the grade for user %s.',
                     request.user.username, username)
            return self.make_error_response(
                status_code=status.HTTP_404_NOT_FOUND,
                developer_message=
                'The user requested does not match the logged in user.',
                error_code='user_mismatch')

        # build the course key
        try:
            course_key = CourseKey.from_string(course_id)
        except InvalidKeyError:
            return self.make_error_response(
                status_code=status.HTTP_404_NOT_FOUND,
                developer_message='The provided course key cannot be parsed.',
                error_code='invalid_course_key')
        # load the course
        try:
            course = courses.get_course_with_access(request.user,
                                                    'load',
                                                    course_key,
                                                    depth=None,
                                                    check_if_enrolled=True)
        except Http404:
            log.info('Course with ID "%s" not found', course_id)
            return self.make_error_response(
                status_code=status.HTTP_404_NOT_FOUND,
                developer_message='The user, the course or both do not exist.',
                error_code='user_or_course_does_not_exist')
        prep_course_for_grading(course, request)
        course_grade = CourseGradeFactory(request.user).create(course)
        if not course_grade.has_access_to_course:
            # This means the student didn't have access to the course
            log.info('User %s not allowed to access grade for course %s',
                     request.user.username, username)
            return self.make_error_response(
                status_code=status.HTTP_403_FORBIDDEN,
                developer_message=
                'The user does not have access to the course.',
                error_code='user_does_not_have_access_to_course')

        return Response([{
            'username': username,
            'course_key': course_id,
            'passed': course_grade.passed,
            'percent': course_grade.percent,
            'letter_grade': course_grade.letter_grade,
        }])
Пример #23
0
    def _dashboard_username(self):

        context = {
            "course_id": self.course_id,
            "username": self.username,
            "user_id": '',
            "course_grade": [],
            "user_info": '',
        }

        try:
            # get users info
            users = User.objects.get(username=self.username)
            # get user id
            user_id = users.id
            # get course_key from url's param
            course_key = SlashSeparatedCourseKey.from_deprecated_string(
                self.course_id)
            # get course from course_key
            course = get_course_by_id(course_key)
            # get all courses block of the site
            course_block = StudentModule.objects.all().filter(
                student_id=user_id,
                course_id=course_key,
                max_grade__isnull=False)
            # var of grades / course_structure
            course_grade = []
            # get course_users_info
            course_user_info = CourseGradeFactory().create(users, course)
            # user info responses
            user_info = [{
                'Grade': str(course_user_info.percent * 100) + '%'
            }, {
                'First_name': users.first_name
            }, {
                'Last_name': users.last_name
            }, {
                'Email': users.email
            }]

            for n in course_block:
                q = {}
                usage_key = n.module_state_key
                block_view = BlocksView()
                block_name = get_blocks(self.request,
                                        usage_key,
                                        depth='all',
                                        requested_fields=['display_name'])
                root = block_name['root']
                display_name = block_name['blocks'][root]['display_name']
                q['earned'] = n.grade
                q['possible'] = n.max_grade
                q['display_name'] = display_name
                q['root'] = root
                course_grade.append(q)

            context["user_id"] = user_id
            context["course_grade"] = course_grade
            context["user_info"] = user_info

        except:
            pass

        return context
Пример #24
0
    def get_student_info(self, email):
        if User.objects.filter(email=email).exists():
            student = User.objects.get(email=email)
            # List of courses user is enrolled to
            org_filter_out_set = ''
            course_org_filter = ''
            course_enrollments = list(
                get_course_enrollments(student, course_org_filter,
                                       org_filter_out_set))

            #last login data_email
            last_login_brut = str(student.last_login)
            last_login = last_login_brut.split('.')

            #Check if microsite admin
            if MicrositeAdminManager.objects.filter(user=student).exists():
                check_admin_microsite = True
                microsite_key = MicrositeAdminManager.objects.get(
                    user=student).microsite_id
                microsite_admin_org = Microsite.objects.get(
                    pk=microsite_key).key
            else:
                check_admin_microsite = False

            #Check wich course invited first
            if CourseEnrollment.objects.filter(user=student).exists():
                course_id = CourseEnrollment.objects.filter(
                    user=student).order_by('-created')[0].course_id
                user_org = str(course_id).split('+')[0].replace(
                    "course-v1:", "")
            else:
                user_org = "No organization found for user"

            #Course counters
            compteur_progress = 0
            compteur_finish = 0
            compteur_start = 0
            compteur_certified = 0

            progress_courses = []
            finish_courses = []
            start_courses = []
            certified_courses = []

            _now = int(datetime.datetime.now().strftime("%s"))

            if len(course_enrollments) > 0:
                #For each course user is enrolled to
                for dashboard_index, enrollment in enumerate(
                        course_enrollments):
                    course_id = enrollment.course_overview.id
                    user_id = student.id
                    course_tma = get_course_by_id(enrollment.course_id)
                    try:
                        course_grade_factory = CourseGradeFactory().create(
                            student, course_tma)
                        passed = course_grade_factory.passed
                        percent = course_grade_factory.percent
                    except:
                        passed = False
                        percent = 0
                    course_progression = get_overall_progress(
                        user_id, course_id)
                    try:
                        _end = int(
                            enrollment.course_overview.end.strftime("%s"))
                    except:
                        _end = 0
                    _progress = True
                    if _end > 0 and _end < _now:
                        _progress = False

                    #storing student results for this class
                    q = {}
                    q['passed'] = passed
                    q['percent'] = float(int(percent * 1000) / 10)
                    q['course_id'] = str(enrollment.course_id)
                    q['duration'] = CourseDetails.fetch(
                        enrollment.course_id).effort
                    q['required'] = course_tma.is_required_atp
                    q['content_data'] = course_tma.content_data
                    q['category'] = course_tma.categ
                    q['display_name_with_default'] = enrollment.course_overview.display_name_with_default
                    q['course_progression'] = course_progression

                    if passed == True:
                        compteur_certified += 1
                        certified_courses.append(q)
                    if course_progression > 0 and course_progression < 100 and passed == False and _progress == True:
                        compteur_progress += 1
                        progress_courses.append(q)
                    elif course_progression == 100 or passed or _progress == False:
                        compteur_finish += 1
                        finish_courses.append(q)
                    elif course_progression == 0 and _progress == True:
                        compteur_start += 1
                        start_courses.append(q)

            #Candidate status
            if student.is_staff:
                status = "Staff"
            elif check_admin_microsite:
                status = "Admin Microsite"
            else:
                status = "Student"

            context = {
                'student_id': student.id,
                'status': status,
                'student_mail': student.email,
                'student_name': student.first_name + " " + student.last_name,
                'progress_courses': compteur_progress,
                #'progress_courses': progress_courses,
                'finished_courses': compteur_finish,
                #'finish_courses': finish_courses,
                'started_courses': compteur_start,
                #'start_courses':start_courses,
                'certified_courses': compteur_certified,
                #'certified_course' : certified_courses,
                'user_org': user_org,
                'last login': last_login[0]
            }
            if check_admin_microsite:
                context['microsite_admin_org'] = microsite_admin_org

        else:
            if UserPreprofile.objects.filter(email=email).exists():
                user = UserPreprofile.objects.get(email=email)
                if CourseEnrollmentAllowed.objects.filter(
                        email=email).exists():
                    profile = CourseEnrollmentAllowed.objects.filter(
                        email=email).order_by('-created')
                    course_id = profile[0].course_id
                    user_org = str(course_id).split('+')[0].replace(
                        "course-v1:", "")
                else:
                    user_org = "No organization found for user"

                context = {
                    'student_mail': email,
                    'student_name': user.first_name + " " + user.last_name,
                    'status': "User preregistered on platform",
                    'user_org': user_org
                }
            else:
                context = {
                    'student_mail': email,
                    'status': "Unknown user",
                }

        return context
Пример #25
0
def testMail(self):

    course_key_string = "course-v1:nautisme-durable+2018+2019"
    course_key = CourseKey.from_string(course_key_string)
    requestFalse = {
        "fields": [
            "user_id", "email", "first_name", "last_name",
            "situation_professionnelle", "inscription_date", "last_connexion",
            "time_tracking", "grade_detailed", "exercises_grade",
            "grade_final", "certified", "cohorte_names", "cp", "phone_number"
        ],
        "receivers": ["*****@*****.**"]
    }

    otoMicrosite = configuration_helpers.get_value('domain_prefix')

    report_fields = requestFalse.get('fields')
    register_fields = configuration_helpers.get_value('FORM_EXTRA')
    certificate_fields = configuration_helpers.get_value(
        'CERTIFICATE_FORM_EXTRA')

    course = get_course_by_id(course_key)
    microsite_information = Microsite.objects.get(key=otoMicrosite)

    form_factory = ensure_form_factory()
    form_factory.connect(db='ensure_form', collection='certificate_form')

    #Dict of labels
    form_labels = {
        "last_connexion": _("Last login"),
        "inscription_date": _("Register date"),
        "user_id": _("User id"),
        "email": _("Email"),
        "grade_final": _("Final Grade"),
        "cohorte_names": _("Cohorte name"),
        "time_tracking": _("Time spent"),
        "certified": _("Attestation"),
        "username": _("Username"),
    }
    for field in register_fields:
        form_labels[field.get('name')] = field.get('label')
    for field in certificate_fields:
        form_labels[field.get('name')] = field.get('label')

    #Identify multiple cells fields
    multiple_cell_fields = ["exercises_grade", "grade_detailed"]

    #Is report cohort specific?
    course_cohorted = is_course_cohorted(course_key)
    cohortes_targeted = []

    course_enrollments = CourseEnrollment.objects.filter(course_id=course_key,
                                                         is_active=1)
    grade_summary = {}
    user_certificate_info = {}

    for enrollment in course_enrollments:
        if not enrollment.is_active:
            continue
        #Gather user information
        user = enrollment.user
        user_grade = CourseGradeFactory().create(user, course)
        # graded_scorable_blocks = tma_graded_scorable_blocks_to_header(course_key)

        for section_grade in user_grade.grade_value['section_breakdown']:
            grade_summary[section_grade['category']] = section_grade['percent']
        try:
            custom_field = json.loads(
                UserProfile.objects.get(user=user).custom_field)
        except:
            custom_field = {}

        user_certificate_info = {}
        try:
            form_factory.microsite = self.microsite
            form_factory.user_id = user.id
            user_certificate_info = form_factory.getForm(
                user_id=True, microsite=True).get('form')
        except:
            pass

        valueArrB = []
        dictSelection = {}
        userDict = {}
        for field in report_fields:
            userDict["course_id"] = str(course_key)
            if field in multiple_cell_fields:

                if field == "grade_detailed":
                    i = 0
                    for section in grade_summary:
                        print("len(section)")
                        print(len(section))
                        i += 1
                        eval = "eval"
                        evalstr = eval + str(i)
                        section_grade = str(
                            int(round(grade_summary[section] * 100))) + '%'
                        userDict[evalstr] = section_grade
                        userDict["nbrWorks"] = i
            else:
                value = ''
                if field == "user_id":
                    value = user.id
                    userDict[field] = value
                elif field == "email":
                    value = user.email
                    userDict[field] = value
                elif field == "first_name":
                    try:
                        if user.first_name:
                            value = user.first_name
                            userDict[field] = value
                        elif custom_field:
                            value = custom_field.get('first_name', 'unkowna')
                            userDict[field] = value
                        else:
                            value = 'unknown'
                            userDict[field] = value
                    except:
                        value = 'unknown'
                        userDict[field] = value
                elif field == "last_name":
                    try:
                        if user.last_name:
                            value = user.last_name
                            userDict[field] = value
                        elif custom_field:
                            value = custom_field.get('last_name', 'unkowna')
                            userDict[field] = value
                    except:
                        value = 'unknown'
                        userDict[field] = value
                elif field == "last_connexion":
                    try:
                        dateR = user.last_login.strftime('%m-%d-%y')
                        dt = parse(str(dateR))
                        f_date = dt.date()
                        l_date = str(datetime.date.today())
                        g_date = parse(l_date)
                        h_date = g_date.date()
                        delta = h_date - f_date
                        if not delta:
                            deltaStr = 0
                        elif delta == "":
                            deltaStr = 0
                        else:
                            deltaStr = str(delta.days)
                        userDict[field] = deltaStr

                    except:
                        value = ''
                        userDict[field] = value
                elif field == "inscription_date":
                    try:
                        value = user.date_joined.strftime('%d-%m-%y')
                        userDict[field] = value
                    except:
                        value = ''
                        userDict[field] = value
                elif field == "certified":
                    if user_grade.passed:
                        value = _("Yes")
                        userDict[field] = value
                    else:
                        value = _("No")
                        userDict[field] = value
                elif field == "grade_final":
                    value = str(int(round(user_grade.percent * 100))) + '%'
                    userDict[field] = value
                elif field == "username":
                    value = user.username
                    userDict[field] = value

        cut = len(course_enrollments)
        bigNar.append(userDict)
        res = bigNar[0:cut]
    prepare_and_send(res)
    return JsonResponse(res)
Пример #26
0
    def get_student_info(self, student):
        # List of courses user is enrolled to
        org_filter_out_set = ''
        course_org_filter = ''
        course_enrollments = list(
            get_course_enrollments(student, course_org_filter,
                                   org_filter_out_set))

        #last login data_email
        last_login_brut = str(student.last_login)
        last_login = last_login_brut.split('.')

        #Check if user is staff / microsite admin / student
        check_admin_microsite = False
        try:
            microsite_key = MicrositeAdminManager.objects.get(
                user=student).microsite_id
            user_org = microsite = Microsite.objects.get(pk=microsite_key).key
            check_admin_microsite = True
        except:
            user_org = "Not microsite admin"
            pass

        compteur_progress = 0
        compteur_finish = 0
        compteur_start = 0
        compteur_certified = 0

        progress_courses = []
        finish_courses = []
        start_courses = []
        certified_courses = []

        _now = int(datetime.datetime.now().strftime("%s"))

        if len(course_enrollments) > 0:
            #For each course user is enrolled to
            for dashboard_index, enrollment in enumerate(course_enrollments):
                course_id = enrollment.course_overview.id
                user_id = student.id
                course_tma = get_course_by_id(enrollment.course_id)
                try:
                    course_grade_factory = CourseGradeFactory().create(
                        student, course_tma)
                    passed = course_grade_factory.passed
                    percent = course_grade_factory.percent
                except:
                    passed = False
                    percent = 0
                course_progression = get_overall_progress(user_id, course_id)
                try:
                    _end = int(enrollment.course_overview.end.strftime("%s"))
                except:
                    _end = 0
                _progress = True
                if _end > 0 and _end < _now:
                    _progress = False

                #storing student results for this class
                q = {}
                q['passed'] = passed
                q['percent'] = float(int(percent * 1000) / 10)
                q['course_id'] = str(enrollment.course_id)
                q['duration'] = CourseDetails.fetch(
                    enrollment.course_id).effort
                q['required'] = course_tma.is_required_atp
                q['content_data'] = course_tma.content_data
                q['category'] = course_tma.categ
                q['display_name_with_default'] = enrollment.course_overview.display_name_with_default
                q['course_progression'] = course_progression

                if passed == True:
                    compteur_certified += 1
                    certified_courses.append(q)
                if course_progression > 0 and course_progression < 100 and passed == False and _progress == True:
                    compteur_progress += 1
                    progress_courses.append(q)
                elif course_progression == 100 or passed or _progress == False:
                    compteur_finish += 1
                    finish_courses.append(q)
                elif course_progression == 0 and _progress == True:
                    compteur_start += 1
                    start_courses.append(q)

        if student.is_staff:
            status = "Staff"
        elif check_admin_microsite:
            status = "Admin Microsite"
        else:
            status = "Student"

        context = {
            'student_id': student.id,
            'status': status,
            'student_mail': student.email,
            'student_name': student.first_name + " " + student.last_name,
            'progress_courses': compteur_progress,
            #'progress_courses': progress_courses,
            'finished_courses': compteur_finish,
            #'finish_courses': finish_courses,
            'started_courses': compteur_start,
            #'start_courses':start_courses,
            'certified_courses': compteur_certified,
            #'certified_course' : certified_courses,
            'user org': user_org,
            'last login': last_login[0]
        }

        return context
Пример #27
0
    def add_cert(self, student, course_id, course=None, forced_grade=None, template_file=None, generate_pdf=True):
        """
        Request a new certificate for a student.

        Arguments:
          student   - User.object
          course_id - courseenrollment.course_id (CourseKey)
          forced_grade - a string indicating a grade parameter to pass with
                         the certificate request. If this is given, grading
                         will be skipped.
          generate_pdf - Boolean should a message be sent in queue to generate certificate PDF

        Will change the certificate status to 'generating' or
        `downloadable` in case of web view certificates.

        The course must not be a CCX.

        Certificate must be in the 'unavailable', 'error',
        'deleted' or 'generating' state.

        If a student has a passing grade or is in the whitelist
        table for the course a request will be made for a new cert.

        If a student has allow_certificate set to False in the
        userprofile table the status will change to 'restricted'

        If a student does not have a passing grade the status
        will change to status.notpassing

        Returns the newly created certificate instance
        """

        if hasattr(course_id, 'ccx'):
            LOGGER.warning(
                (
                    u"Cannot create certificate generation task for user %s "
                    u"in the course '%s'; "
                    u"certificates are not allowed for CCX courses."
                ),
                student.id,
                unicode(course_id)
            )
            return None

        valid_statuses = [
            status.generating,
            status.unavailable,
            status.deleted,
            status.error,
            status.notpassing,
            status.downloadable,
            status.auditing,
            status.audit_passing,
            status.audit_notpassing,
        ]

        cert_status = certificate_status_for_student(student, course_id)['status']
        cert = None

        if cert_status not in valid_statuses:
            LOGGER.warning(
                (
                    u"Cannot create certificate generation task for user %s "
                    u"in the course '%s'; "
                    u"the certificate status '%s' is not one of %s."
                ),
                student.id,
                unicode(course_id),
                cert_status,
                unicode(valid_statuses)
            )
            return None

        # The caller can optionally pass a course in to avoid
        # re-fetching it from Mongo. If they have not provided one,
        # get it from the modulestore.
        if course is None:
            course = modulestore().get_course(course_id, depth=0)

        profile = UserProfile.objects.get(user=student)
        profile_name = profile.name

        # Needed for access control in grading.
        self.request.user = student
        self.request.session = {}

        is_whitelisted = self.whitelist.filter(user=student, course_id=course_id, whitelist=True).exists()
        grade = CourseGradeFactory().create(student, course).summary
        enrollment_mode, __ = CourseEnrollment.enrollment_mode_for_user(student, course_id)
        mode_is_verified = enrollment_mode in GeneratedCertificate.VERIFIED_CERTS_MODES
        user_is_verified = SoftwareSecurePhotoVerification.user_is_verified(student)
        cert_mode = enrollment_mode
        is_eligible_for_certificate = is_whitelisted or CourseMode.is_eligible_for_certificate(enrollment_mode)
        unverified = False
        # For credit mode generate verified certificate
        if cert_mode == CourseMode.CREDIT_MODE:
            cert_mode = CourseMode.VERIFIED

        if template_file is not None:
            template_pdf = template_file
        elif mode_is_verified and user_is_verified:
            template_pdf = "certificate-template-{id.org}-{id.course}-verified.pdf".format(id=course_id)
        elif mode_is_verified and not user_is_verified:
            template_pdf = "certificate-template-{id.org}-{id.course}.pdf".format(id=course_id)
            if CourseMode.mode_for_course(course_id, CourseMode.HONOR):
                cert_mode = GeneratedCertificate.MODES.honor
            else:
                unverified = True
        else:
            # honor code and audit students
            template_pdf = "certificate-template-{id.org}-{id.course}.pdf".format(id=course_id)
        if forced_grade:
            grade['grade'] = forced_grade

        LOGGER.info(
            (
                u"Certificate generated for student %s in the course: %s with template: %s. "
                u"given template: %s, "
                u"user is verified: %s, "
                u"mode is verified: %s"
            ),
            student.username,
            unicode(course_id),
            template_pdf,
            template_file,
            user_is_verified,
            mode_is_verified
        )

        cert, created = GeneratedCertificate.objects.get_or_create(user=student, course_id=course_id)  # pylint: disable=no-member

        cert.mode = cert_mode
        cert.user = student
        cert.grade = grade['percent']
        cert.course_id = course_id
        cert.name = profile_name
        cert.download_url = ''

        # Strip HTML from grade range label
        grade_contents = grade.get('grade', None)
        try:
            grade_contents = lxml.html.fromstring(grade_contents).text_content()
            passing = True
        except (TypeError, XMLSyntaxError, ParserError) as exc:
            LOGGER.info(
                (
                    u"Could not retrieve grade for student %s "
                    u"in the course '%s' "
                    u"because an exception occurred while parsing the "
                    u"grade contents '%s' as HTML. "
                    u"The exception was: '%s'"
                ),
                student.id,
                unicode(course_id),
                grade_contents,
                unicode(exc)
            )

            # Log if the student is whitelisted
            if is_whitelisted:
                LOGGER.info(
                    u"Student %s is whitelisted in '%s'",
                    student.id,
                    unicode(course_id)
                )
                passing = True
            else:
                passing = False

        # If this user's enrollment is not eligible to receive a
        # certificate, mark it as such for reporting and
        # analytics. Only do this if the certificate is new, or
        # already marked as ineligible -- we don't want to mark
        # existing audit certs as ineligible.
        cutoff = settings.AUDIT_CERT_CUTOFF_DATE
        if (cutoff and cert.created_date >= cutoff) and not is_eligible_for_certificate:
            cert.status = CertificateStatuses.audit_passing if passing else CertificateStatuses.audit_notpassing
            cert.save()
            LOGGER.info(
                u"Student %s with enrollment mode %s is not eligible for a certificate.",
                student.id,
                enrollment_mode
            )
            return cert
        # If they are not passing, short-circuit and don't generate cert
        elif not passing:
            cert.status = status.notpassing
            cert.save()

            LOGGER.info(
                (
                    u"Student %s does not have a grade for '%s', "
                    u"so their certificate status has been set to '%s'. "
                    u"No certificate generation task was sent to the XQueue."
                ),
                student.id,
                unicode(course_id),
                cert.status
            )
            return cert

        # Check to see whether the student is on the the embargoed
        # country restricted list. If so, they should not receive a
        # certificate -- set their status to restricted and log it.
        if self.restricted.filter(user=student).exists():
            cert.status = status.restricted
            cert.save()

            LOGGER.info(
                (
                    u"Student %s is in the embargoed country restricted "
                    u"list, so their certificate status has been set to '%s' "
                    u"for the course '%s'. "
                    u"No certificate generation task was sent to the XQueue."
                ),
                student.id,
                cert.status,
                unicode(course_id)
            )
            return cert

        if unverified:
            cert.status = status.unverified
            cert.save()
            LOGGER.info(
                (
                    u"User %s has a verified enrollment in course %s "
                    u"but is missing ID verification. "
                    u"Certificate status has been set to unverified"
                ),
                student.id,
                unicode(course_id),
            )
            return cert

        # Finally, generate the certificate and send it off.
        return self._generate_cert(cert, course, student, grade_contents, template_pdf, generate_pdf)
 def get_course_grade(self):
     """
     Return CourseGrade for current user and course.
     """
     return CourseGradeFactory().create(self.student_user, self.course)