コード例 #1
0
def student_process(request, course_id, user_id):
    try:
        __, course = _get_locator_and_course(course_id,
                                             'draft',
                                             None,
                                             course_id.split('.')[-1],
                                             request.user,
                                             depth=None)
    except:
        raise Http404('没有找到对应课程!')

    student = User.objects.prefetch_related("groups").get(id=user_id)

    courseware_summary = grades.progress_summary(student, request, course)
    grade_summary = grade.grade(student, request, course)

    if courseware_summary is None:
        raise Http404

    context = {
        'course': course,
        'courseware_summary': courseware_summary,
        'grade_summary': grade_summary,
        'student': student,
    }

    return JsonResponse(context)
コード例 #2
0
ファイル: tasks.py プロジェクト: KaplanTestPrep/edxanalytics
def get_student_course_stats_base(request,course, type="grades"):
    """
    Called by get_student_course_stats and get_student_problem_stats
    Gets a list of users in a course, and then computes grades for them
    request - a mock request (using RequestDict)
    course - a string course id
    type - whether to get student weighted grades or unweighted grades.  If "grades" will get weighted
    """
    fs, db = common.get_db_and_fs_cron(common.student_course_stats_stub)
    course_obj = get_course_with_access(request.user, course, 'load', depth=None)
    users_in_course = StudentModule.objects.filter(course_id=course).values('student').distinct()
    users_in_course_ids = [u['student'] for u in users_in_course]
    log.debug("Users in course count: {0}".format(len(users_in_course_ids)))
    courseware_summaries = []
    for i in xrange(0,len(users_in_course_ids)):
        try:
            user = users_in_course_ids[i]
            current_task.update_state(state='PROGRESS', meta={'current': i, 'total': len(users_in_course_ids)})
            student = User.objects.using('remote').prefetch_related("groups").get(id=int(user))

            model_data_cache = None

            if type=="grades":
                grade_summary = grades.grade(student, request, course_obj, model_data_cache)
            else:
                grade_summary = grades.progress_summary(student, request, course_obj, model_data_cache)
            courseware_summaries.append(grade_summary)
        except:
            log.exception("Could not generate data for {0}".format(users_in_course_ids[i]))
    return courseware_summaries, users_in_course_ids
コード例 #3
0
ファイル: certificate.py プロジェクト: nttks/edx-platform
    def report(self):
        """Report course grade."""
        students = self._get_students()

        print "\nFetching course data for {0}".format(self.course_id)
        course = courses.get_course_by_id(self.course_id)
        request = self._create_request()
        total = {'users': 0, 'pass': 0, 'notpass': 0}

        print "Summary Report: Course Name [{0}]".format(
            course.display_name.encode('utf_8'))

        for student in students.iterator():
            request.user = student
            total['users'] += 1

            certs = GeneratedCertificate.objects.filter(
                user=student, course_id=self.course_id)

            for cert in certs.iterator():
                grade = grades.grade(cert.user, request, course)
                summary = grades.progress_summary(student, request, course)
                self._report_summary(summary)
                self._add_total(cert.user, grade, total)

        self._report_total(total)
コード例 #4
0
    def report(self):
        """Report course grade."""
        students = self._get_students()

        print "\nFetching course data for {0}".format(self.course_id)
        course = courses.get_course_by_id(self.course_id)
        request = self._create_request()
        total = {'users': 0, 'pass': 0, 'notpass': 0}

        print "Summary Report: Course Name [{0}]".format(
            course.display_name.encode('utf_8'))

        for student in students.iterator():
            request.user = student
            total['users'] += 1

            certs = GeneratedCertificate.objects.filter(
                user=student, course_id=self.course_id)

            for cert in certs.iterator():
                grade = grades.grade(cert.user, request, course)
                summary = grades.progress_summary(student, request, course)
                self._report_summary(summary)
                self._add_total(cert.user, grade, total)

        self._report_total(total)
    def handle(self, *args, **options):

        course_ids = options.get('course_ids')
        user_ids = options.get('user_ids')

        # Get the list of courses from the system
        courses = modulestore().get_courses()

        # If one or more courses were specified by the caller, just use those ones...
        if course_ids is not None:
            filtered_courses = []
            for course in courses:
                if unicode(course.id) in course_ids.split(','):
                    filtered_courses.append(course)
            courses = filtered_courses

        for course in courses:
            users = CourseEnrollment.objects.users_enrolled_in(course.id)
            # If one or more users were specified by the caller, just use those ones...
            if user_ids is not None:
                filtered_users = []
                for user in users:
                    if str(user.id) in user_ids.split(','):
                        filtered_users.append(user)
                users = filtered_users

            # For each user...
            for user in users:
                grade_data = grades.grade(user, course)
                grade = grade_data['percent']
                grading_policy = course.grading_policy
                proforma_grade = grades.calculate_proforma_grade(grade_data, grading_policy)
                progress_summary = grades.progress_summary(user, course)
                try:
                    gradebook_entry = StudentGradebook.objects.get(user=user, course_id=course.id)
                    if (gradebook_entry.grade != grade or
                            gradebook_entry.proforma_grade != proforma_grade or
                            gradebook_entry.progress_summary != progress_summary or
                            gradebook_entry.grade_summary != grade_data or
                            gradebook_entry.grading_policy != grading_policy):
                        gradebook_entry.grade = grade
                        gradebook_entry.proforma_grade = proforma_grade
                        gradebook_entry.progress_summary = json.dumps(progress_summary, cls=EdxJSONEncoder)
                        gradebook_entry.grade_summary = json.dumps(grade_data, cls=EdxJSONEncoder)
                        gradebook_entry.grading_policy = json.dumps(grading_policy, cls=EdxJSONEncoder)
                        gradebook_entry.save()
                except StudentGradebook.DoesNotExist:
                    StudentGradebook.objects.create(
                        user=user,
                        course_id=course.id,
                        grade=grade,
                        proforma_grade=proforma_grade,
                        progress_summary=json.dumps(progress_summary, cls=EdxJSONEncoder),
                        grade_summary=json.dumps(grade_data, cls=EdxJSONEncoder),
                        grading_policy=json.dumps(grading_policy, cls=EdxJSONEncoder)
                    )
                log_msg = 'Gradebook entry created -- Course: {}, User: {}  (grade: {}, proforma_grade: {})'.format(course.id, user.id, grade, proforma_grade)
                print log_msg
                log.info(log_msg)
コード例 #6
0
def _progress(request, course_key, student_id):
    """
    Unwrapped version of "progress".

    User progress. We show the grade bar and every problem score.

    Course staff are allowed to see the progress of students in their class.
    """
    course = get_course_with_access(request.user,
                                    'load',
                                    course_key,
                                    depth=None,
                                    check_if_enrolled=True)

    # check to see if there is a required survey that must be taken before
    # the user can access the course.
    if survey.utils.must_answer_survey(course, request.user):
        return redirect(reverse('course_survey', args=[unicode(course.id)]))

    staff_access = has_access(request.user, 'staff', course)

    if student_id is None or student_id == request.user.id:
        # always allowed to see your own profile
        student = request.user
    else:
        # Requesting access to a different student's profile
        if not staff_access:
            raise Http404
        student = User.objects.get(id=int(student_id))

    # NOTE: To make sure impersonation by instructor works, use
    # student instead of request.user in the rest of the function.

    # The pre-fetching of groups is done to make auth checks not require an
    # additional DB lookup (this kills the Progress page in particular).
    student = User.objects.prefetch_related("groups").get(id=student.id)

    courseware_summary = grades.progress_summary(student, request, course)
    studio_url = get_studio_url(course, 'settings/grading')
    grade_summary = grades.grade(student, request, course)

    if courseware_summary is None:
        #This means the student didn't have access to the course (which the instructor requested)
        raise Http404

    context = {
        'course': course,
        'courseware_summary': courseware_summary,
        'studio_url': studio_url,
        'grade_summary': grade_summary,
        'staff_access': staff_access,
        'student': student,
        'reverifications': fetch_reverify_banner_info(request, course_key)
    }

    with grades.manual_transaction():
        response = render_to_response('courseware/progress.html', context)

    return response
コード例 #7
0
def render_accordion(request, course, chapter, section, model_data_cache):
    """
    Draws navigation bar. Takes current position in accordion as
    parameter.

    If chapter and section are '' or None, renders a default accordion.

    course, chapter, and section are the url_names.

    Returns the html string
    """

    staff_access = has_access(request.user, course, "staff")

    # NOTE: To make sure impersonation by instructor works, use
    # student instead of request.user in the rest of the function.

    # The pre-fetching of groups is done to make auth checks not require an
    # additional DB lookup (this kills the Progress page in particular).
    course_id = course.id
    student_id = None
    if student_id is None or student_id == request.user.id:
        # always allowed to see your own profile
        student = request.user
    else:
        # Requesting access to a different student's profile
        if not staff_access:
            raise Http404
        student = User.objects.get(id=int(student_id))

    student = User.objects.prefetch_related("groups").get(id=student.id)

    model_data_cache = ModelDataCache.cache_for_descriptor_descendents(course_id, student, course, depth=None)

    courseware_summary = grades.progress_summary(student, request, course, model_data_cache)

    print("<-------------")
    print(courseware_summary)
    print("------------->")

    # grab the table of contents
    user = User.objects.prefetch_related("groups").get(id=request.user.id)
    request.user = user  # keep just one instance of User
    toc = toc_for_course(user, request, course, chapter, section, model_data_cache)

    context = dict(
        [
            ("toc", toc),
            ("course_id", course.id),
            ("csrf", csrf(request)["csrf_token"]),
            ("show_timezone", course.show_timezone),
            ("courseware_summary", courseware_summary),
        ]
        + template_imports.items()
    )
    return render_to_string("courseware/accordion.html", context)
コード例 #8
0
ファイル: views.py プロジェクト: alexmerser/lms
def _progress(request, course_key, student_id):
    """
    Unwrapped version of "progress".

    User progress. We show the grade bar and every problem score.

    Course staff are allowed to see the progress of students in their class.
    """
    course = get_course_with_access(request.user, 'load', course_key, depth=None, check_if_enrolled=True)

    # check to see if there is a required survey that must be taken before
    # the user can access the course.
    if survey.utils.must_answer_survey(course, request.user):
        return redirect(reverse('course_survey', args=[unicode(course.id)]))

    staff_access = has_access(request.user, 'staff', course)

    if student_id is None or student_id == request.user.id:
        # always allowed to see your own profile
        student = request.user
    else:
        # Requesting access to a different student's profile
        if not staff_access:
            raise Http404
        student = User.objects.get(id=int(student_id))

    # NOTE: To make sure impersonation by instructor works, use
    # student instead of request.user in the rest of the function.

    # The pre-fetching of groups is done to make auth checks not require an
    # additional DB lookup (this kills the Progress page in particular).
    student = User.objects.prefetch_related("groups").get(id=student.id)

    courseware_summary = grades.progress_summary(student, request, course)
    studio_url = get_studio_url(course, 'settings/grading')
    grade_summary = grades.grade(student, request, course)

    if courseware_summary is None:
        #This means the student didn't have access to the course (which the instructor requested)
        raise Http404

    context = {
        'course': course,
        'courseware_summary': courseware_summary,
        'studio_url': studio_url,
        'grade_summary': grade_summary,
        'staff_access': staff_access,
        'student': student,
        'reverifications': fetch_reverify_banner_info(request, course_key)
    }

    with grades.manual_transaction():
        response = render_to_response('courseware/progress.html', context)

    return response
コード例 #9
0
    def get_progress_summary(self):
        """
        Return progress summary structure for current user and course.

        Returns
        - courseware_summary is a summary of all sections with problems in the course.
        It is organized as an array of chapters, each containing an array of sections,
        each containing an array of scores. This contains information for graded and
        ungraded problems, and is good for displaying a course summary with due dates,
        etc.
        """
        return grades.progress_summary(self.student_user, self.course)
コード例 #10
0
ファイル: tests.py プロジェクト: hughdbrown/edx-platform
    def get_progress_summary(self):
        '''return progress summary structure for current user and course'''
        model_data_cache = ModelDataCache.cache_for_descriptor_descendents(
            self.course.id, self.student_user, self.course)

        fake_request = self.factory.get(
            reverse('progress', kwargs={'course_id': self.course.id}))

        progress_summary = grades.progress_summary(self.student_user,
                                                   fake_request, self.course,
                                                   model_data_cache)
        return progress_summary
コード例 #11
0
    def get_progress_summary(self):
        '''return progress summary structure for current user and course'''
        model_data_cache = ModelDataCache.cache_for_descriptor_descendents(
            self.course.id, self.student_user, self.course)

        fake_request = self.factory.get(reverse('progress',
                                        kwargs={'course_id': self.course.id}))

        progress_summary = grades.progress_summary(self.student_user,
                                                   fake_request,
                                                   self.course,
                                                   model_data_cache)
        return progress_summary
コード例 #12
0
ファイル: views.py プロジェクト: mjg2203/edx-platform-seas
def _progress(request, course_id, student_id):
    """
    Unwrapped version of "progress".

    User progress. We show the grade bar and every problem score.

    Course staff are allowed to see the progress of students in their class.
    """
    course = get_course_with_access(request.user,
                                    course_id,
                                    'load',
                                    depth=None)
    staff_access = has_access(request.user, course, 'staff')

    if student_id is None or student_id == request.user.id:
        # always allowed to see your own profile
        student = request.user
    else:
        # Requesting access to a different student's profile
        if not staff_access:
            raise Http404
        student = User.objects.get(id=int(student_id))

    # NOTE: To make sure impersonation by instructor works, use
    # student instead of request.user in the rest of the function.

    # The pre-fetching of groups is done to make auth checks not require an
    # additional DB lookup (this kills the Progress page in particular).
    student = User.objects.prefetch_related("groups").get(id=student.id)

    courseware_summary = grades.progress_summary(student, request, course)

    grade_summary = grades.grade(student, request, course)

    if courseware_summary is None:
        #This means the student didn't have access to the course (which the instructor requested)
        raise Http404

    context = {
        'course': course,
        'courseware_summary': courseware_summary,
        'grade_summary': grade_summary,
        'staff_access': staff_access,
        'student': student,
    }

    with grades.manual_transaction():
        response = render_to_response('courseware/progress.html', context)

    return response
コード例 #13
0
def _progress(request, course_id, student_id):
    """
    Unwrapped version of "progress".

    User progress. We show the grade bar and every problem score.

    Course staff are allowed to see the progress of students in their class.
    """
    course = get_course_with_access(request.user, course_id, "load", depth=None)
    staff_access = has_access(request.user, course, "staff")

    if student_id is None or student_id == request.user.id:
        # always allowed to see your own profile
        student = request.user
    else:
        # Requesting access to a different student's profile
        if not staff_access:
            raise Http404
        student = User.objects.get(id=int(student_id))

    # NOTE: To make sure impersonation by instructor works, use
    # student instead of request.user in the rest of the function.

    # The pre-fetching of groups is done to make auth checks not require an
    # additional DB lookup (this kills the Progress page in particular).
    student = User.objects.prefetch_related("groups").get(id=student.id)

    courseware_summary = grades.progress_summary(student, request, course)
    studio_url = get_studio_url(course_id, "settings/grading")
    grade_summary = grades.grade(student, request, course)

    if courseware_summary is None:
        # This means the student didn't have access to the course (which the instructor requested)
        raise Http404

    context = {
        "course": course,
        "courseware_summary": courseware_summary,
        "studio_url": studio_url,
        "grade_summary": grade_summary,
        "staff_access": staff_access,
        "student": student,
        "reverifications": fetch_reverify_banner_info(request, course_id),
    }

    with grades.manual_transaction():
        response = render_to_response("courseware/progress.html", context)

    return response
コード例 #14
0
    def get_progress_summary(self):
        """
        Return progress summary structure for current user and course.

        Returns
        - courseware_summary is a summary of all sections with problems in the course.
        It is organized as an array of chapters, each containing an array of sections,
        each containing an array of scores. This contains information for graded and
        ungraded problems, and is good for displaying a course summary with due dates,
        etc.
        """

        fake_request = self.factory.get(reverse("progress", kwargs={"course_id": self.course.id}))

        progress_summary = grades.progress_summary(self.student_user, fake_request, self.course)
        return progress_summary
コード例 #15
0
    def handle(self, *args, **options):

        course_id = options.get('course_id')
        course_ids = []

        if course_id:
            course_ids.append(course_id)
        else:
            course_ids = StudentGradebook.objects.filter(
                grade_summary='').values_list('course_id', flat=True)

        for course_id in course_ids:
            course_key = CourseKey.from_string(course_id)
            users = CourseEnrollment.objects.users_enrolled_in(course_key)
            course = modulestore().get_course(course_key, depth=None)
            if course:
                # For each user...
                for user in users:
                    request = RequestMockWithoutMiddleware().get('/')
                    request.user = user
                    grade_data = grades.grade(user, course)
                    grade = grade_data['percent']
                    grading_policy = course.grading_policy
                    proforma_grade = grades.calculate_proforma_grade(
                        grade_data, grading_policy)
                    progress_summary = grades.progress_summary(user, course)
                    try:
                        gradebook_entry = StudentGradebook.objects.get(
                            user=user, course_id=course.id)
                        if not gradebook_entry.grade_summary:
                            gradebook_entry.grade = grade
                            gradebook_entry.proforma_grade = proforma_grade
                            gradebook_entry.progress_summary = json.dumps(
                                progress_summary, cls=EdxJSONEncoder)
                            gradebook_entry.grade_summary = json.dumps(
                                grade_data, cls=EdxJSONEncoder)
                            gradebook_entry.grading_policy = json.dumps(
                                grading_policy, cls=EdxJSONEncoder)
                            gradebook_entry.save()
                    except StudentGradebook.DoesNotExist:
                        pass

                    log_msg = 'Gradebook entry created -- Course: {}, User: {}  (grade: {}, proforma_grade: {})'.format(
                        course.id, user.id, grade, proforma_grade)
                    log.info(log_msg)
コード例 #16
0
    def get_progress_summary(self):
        """
        Return progress summary structure for current user and course.

        Returns
        - courseware_summary is a summary of all sections with problems in the course.
        It is organized as an array of chapters, each containing an array of sections,
        each containing an array of scores. This contains information for graded and
        ungraded problems, and is good for displaying a course summary with due dates,
        etc.
        """

        fake_request = self.factory.get(
            reverse('progress', kwargs={'course_id': self.course.id}))

        progress_summary = grades.progress_summary(self.student_user,
                                                   fake_request, self.course)
        return progress_summary
コード例 #17
0
ファイル: views.py プロジェクト: EduPepperPD/pepper2013
def progress(request, course_id, student_id=None):
    """ User progress. We show the grade bar and every problem score.

    Course staff are allowed to see the progress of students in their class.
    """
    course = get_course_with_access(request.user, course_id, 'load', depth=None)
    staff_access = has_access(request.user, course, 'staff')

    if student_id is None or student_id == request.user.id:
        # always allowed to see your own profile
        student = request.user
    else:
        # Requesting access to a different student's profile
        if not staff_access:
            raise Http404
        student = User.objects.get(id=int(student_id))

    # NOTE: To make sure impersonation by instructor works, use
    # student instead of request.user in the rest of the function.

    # The pre-fetching of groups is done to make auth checks not require an
    # additional DB lookup (this kills the Progress page in particular).
    student = User.objects.prefetch_related("groups").get(id=student.id)

    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course_id, student, course, depth=None)

    courseware_summary = grades.progress_summary(student, request, course,
                                                 field_data_cache)
    grade_summary = grades.grade(student, request, course, field_data_cache)

    if courseware_summary is None:
        #This means the student didn't have access to the course (which the instructor requested)
        raise Http404

    context = {'course': course,
               'courseware_summary': courseware_summary,
               'grade_summary': grade_summary,
               'staff_access': staff_access,
               'student': student,
               }
    context.update()

    return render_to_response('courseware/progress.html', context)
コード例 #18
0
ファイル: tasks.py プロジェクト: Manoharsai/edxanalytics
def get_student_course_stats_base(request, course, type="grades"):
    """
    Called by get_student_course_stats and get_student_problem_stats
    Gets a list of users in a course, and then computes grades for them
    request - a mock request (using RequestDict)
    course - a string course id
    type - whether to get student weighted grades or unweighted grades.  If "grades" will get weighted
    """
    fs, db = common.get_db_and_fs_cron(common.student_course_stats_stub)
    course_obj = get_course_with_access(request.user,
                                        course,
                                        'load',
                                        depth=None)
    users_in_course = StudentModule.objects.filter(
        course_id=course).values('student').distinct()
    users_in_course_ids = [u['student'] for u in users_in_course]
    log.debug("Users in course count: {0}".format(len(users_in_course_ids)))
    courseware_summaries = []
    for i in xrange(0, len(users_in_course_ids)):
        try:
            user = users_in_course_ids[i]
            current_task.update_state(state='PROGRESS',
                                      meta={
                                          'current': i,
                                          'total': len(users_in_course_ids)
                                      })
            student = User.objects.using('remote').prefetch_related(
                "groups").get(id=int(user))

            model_data_cache = None

            if type == "grades":
                grade_summary = grades.grade(student, request, course_obj,
                                             model_data_cache)
            else:
                grade_summary = grades.progress_summary(
                    student, request, course_obj, model_data_cache)
            courseware_summaries.append(grade_summary)
        except:
            log.exception("Could not generate data for {0}".format(
                users_in_course_ids[i]))
    return courseware_summaries, users_in_course_ids
コード例 #19
0
ファイル: utils.py プロジェクト: geekaia/edx-platform
def progress(request, course_id, student_id):
    """
    Unwrapped version of "progress".
courseware_summary
    User progress. We show the grade bar and every problem score.

    Course staff are allowed to see the progress of students in their class.
    """

    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course = get_course_with_access(request.user, 'load', course_key, depth=None)

    # course = get_course_with_access(request.user, course_id, 'load', depth=None)
    staff_access = has_access(request.user, 'staff', course)

    if not staff_access:
            raise Http404

    if student_id is None or student_id == request.user.id:
        # always allowed to see your own profile
        student = request.user
    else:
        # Requesting access to a different student's profile
        if not staff_access:
            raise Http404
        student = User.objects.get(id=int(student_id))

    # NOTE: To make sure impersonation by instructor works, use
    # student instead of request.user in the rest of the function.

    # The pre-fetching of groups is done to make auth checks not require an
    # additional DB lookup (this kills the Progress page in particular).
    student = User.objects.prefetch_related("groups").get(id=student.id)


    try:
        courseware_summary = grades.progress_summary(student, request, course)
    except:
        courseware_summary = None


    return courseware_summary
コード例 #20
0
ファイル: views.py プロジェクト: pelikanchik/edx-platform
def render_accordion(request, course, chapter, section, field_data_cache):
    """
    Draws navigation bar. Takes current position in accordion as
    parameter.

    If chapter and section are '' or None, renders a default accordion.

    course, chapter, and section are the url_names.

    Returns the html string
    """

    # grab the table of contents
    staff_access = has_access(request.user, course, 'staff')
    student_id = None
    if student_id is None or student_id == request.user.id:
        # always allowed to see your own profile
        student = request.user
    else:
        # Requesting access to a different student's profile
        if not staff_access:
            raise Http404
        student = User.objects.get(id=int(student_id))

    student = User.objects.prefetch_related("groups").get(id=student.id)
    user = User.objects.prefetch_related("groups").get(id=request.user.id)
    request.user = user	# keep just one instance of User
    toc = toc_for_course(user, request, course, chapter, section, field_data_cache)
    is_demo = UserProfile.objects.get(user=request.user).is_demo
    courseware_summary = grades.progress_summary(student, request, course)

    context = dict([('toc', toc),
                    ('course_id', course.id),
                    ('is_demo', is_demo),
                    ('csrf', csrf(request)['csrf_token']),
                    ('courseware_summary', courseware_summary),
                    ('due_date_display_format', course.due_date_display_format)] + template_imports.items())
    return render_to_string('courseware/accordion.html', context)
コード例 #21
0
    def get_progress_summary(self):
        """
        Return progress summary structure for current user and course.

        Returns
        - courseware_summary is a summary of all sections with problems in the course.
        It is organized as an array of chapters, each containing an array of sections,
        each containing an array of scores. This contains information for graded and
        ungraded problems, and is good for displaying a course summary with due dates,
        etc.
        """

        model_data_cache = ModelDataCache.cache_for_descriptor_descendents(
            self.course.id, self.student_user, self.course)

        fake_request = self.factory.get(reverse('progress',
                                        kwargs={'course_id': self.course.id}))

        progress_summary = grades.progress_summary(self.student_user,
                                                   fake_request,
                                                   self.course,
                                                   model_data_cache)
        return progress_summary
コード例 #22
0
ファイル: receivers.py プロジェクト: askoric/edx-platform
def on_score_changed(sender, **kwargs):
    """
    Listens for a 'score_changed' signal and when observed
    recalculates the specified user's gradebook entry
    """
    from courseware.views import get_course
    user = kwargs['user']
    course_key = kwargs['course_key']
    course_descriptor = get_course(course_key, depth=None)
    request = RequestMockWithoutMiddleware().get('/')
    request.user = user
    progress_summary = grades.progress_summary(user, request, course_descriptor, locators_as_strings=True)
    grade_summary = grades.grade(user, request, course_descriptor)
    grading_policy = course_descriptor.grading_policy
    grade = grade_summary['percent']
    proforma_grade = grades.calculate_proforma_grade(grade_summary, grading_policy)

    try:
        gradebook_entry = StudentGradebook.objects.get(user=user, course_id=course_key)
        if gradebook_entry.grade != grade:
            gradebook_entry.grade = grade
            gradebook_entry.proforma_grade = proforma_grade
            gradebook_entry.progress_summary = json.dumps(progress_summary, cls=EdxJSONEncoder)
            gradebook_entry.grade_summary = json.dumps(grade_summary, cls=EdxJSONEncoder)
            gradebook_entry.grading_policy = json.dumps(grading_policy, cls=EdxJSONEncoder)
            gradebook_entry.save()
    except StudentGradebook.DoesNotExist:
        StudentGradebook.objects.create(
            user=user,
            course_id=course_key,
            grade=grade,
            proforma_grade=proforma_grade,
            progress_summary=json.dumps(progress_summary, cls=EdxJSONEncoder),
            grade_summary=json.dumps(grade_summary, cls=EdxJSONEncoder),
            grading_policy=json.dumps(grading_policy, cls=EdxJSONEncoder)
        )
コード例 #23
0
def student_process(request, course_id, user_id):
    try:
        __, course = _get_locator_and_course(
            course_id, 'draft', None, course_id.split('.')[-1], request.user, depth=None
        )
    except:
        raise Http404('没有找到对应课程!')

    student = User.objects.prefetch_related("groups").get(id=user_id)

    courseware_summary = grades.progress_summary(student, request, course)
    grade_summary = grade.grade(student, request, course)

    if courseware_summary is None:
        raise Http404

    context = {
        'course': course,
        'courseware_summary': courseware_summary,
        'grade_summary': grade_summary,
        'student': student,
    }

    return JsonResponse(context)
コード例 #24
0
def prepare_sections_with_grade(request, course):
    '''
    Create sections with grade details.

    Return format:
    {
        'sections': [
            {
                'display_name': name,
                # in case of cohorts or any other accessibility settings
                'hidden': hidden,
                'url_name': url_name,
                'units': UNITS,
                'rank': rank,
                'badge': bagde status,
                'points': grade points,
                'podium': podium status,
                'week': section_index + 1,
            },
        ],
    }

    where UNITS is a list
    [
        {
            'display_name': name,
            'position': unit position in section,
            'css_class': css class,
        }
        , ...
    ]

    sections with name 'hidden' are skipped.

    NOTE: assumes that if we got this far, user has access to course.  Returns
    [] if this is not the case.
    '''
    # Set the student to request user
    student = request.user

    # Get the field data cache
    field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course.id, student, course, depth=2,
    )
    
    # Get the course module
    with modulestore().bulk_operations(course.id):
        course_module = get_module_for_descriptor(
            student, request, course, field_data_cache, course.id, course=course
        )
        if course_module is None:
            return []

    # Get the field data cache
    staff_user = User.objects.filter(is_staff=1)[0]
    staff_field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
        course.id, staff_user, course, depth=2,
    )

    # Get the course module
    with modulestore().bulk_operations(course.id):
        staff_course_module = get_module_for_descriptor(
            staff_user, request, course, staff_field_data_cache, course.id, course=course
        )

    # staff accessible chapters
    staff_chapters = staff_course_module.get_display_items()

    # find the passing grade for the course
    nonzero_cutoffs = [cutoff for cutoff in course.grade_cutoffs.values() if cutoff > 0]
    success_cutoff = min(nonzero_cutoffs) if nonzero_cutoffs else 0

    # find the course progress
    progress = get_course_progress(student, course.id)

    # prepare a list of discussions participated by user
    discussions_participated = get_discussions_participated(
        request,
        course.id.to_deprecated_string(),
        student.id
    )

    # get courseware summary
    with outer_atomic():
        field_data_cache = grades.field_data_cache_for_grading(course, student)
        scores_client = ScoresClient.from_field_data_cache(field_data_cache)

    courseware_summary = grades.progress_summary(
        student, request, course, field_data_cache=field_data_cache, scores_client=scores_client
    )

    section_grades = {}
    for section in courseware_summary:
        earned = 0
        total = 0
        for sub_section in section['sections']:
            earned += sub_section['section_total'].earned
            total += sub_section['section_total'].possible

        section_score = earned / total if earned > 0 and total > 0 else 0
        section_grades[section['url_name']] = {
            'earned': earned,
            'total': total,
            'css_class': ('text-red', 'text-green')[int(section_score >= 0.6)] if total > 0 else ''
        }

    # Check for content which needs to be completed
    # before the rest of the content is made available
    required_content = milestones_helpers.get_required_content(course, student)

    # Check for gated content
    gated_content = gating_api.get_gated_content(course, student)

    # The user may not actually have to complete the entrance exam, if one is required
    if not user_must_complete_entrance_exam(request, student, course):
        required_content = [content for content in required_content if not content == course.entrance_exam_id]

    # define inner function
    def create_module(descriptor):
        '''creates an XModule instance given a descriptor'''
        return get_module_for_descriptor(
            student, request, descriptor, field_data_cache, course.id, course=course
        )

    with outer_atomic():
        submissions_scores = sub_api.get_scores(
            course.id.to_deprecated_string(),
            anonymous_id_for_user(student, course.id)
        )
        max_scores_cache = grades.MaxScoresCache.create_for_course(course)
        max_scores_cache.fetch_from_remote(field_data_cache.scorable_locations)


    sections = list()
    student_chapters = course_module.get_display_items()
    urlname_chapters = {}
    for student_chap in student_chapters:
        urlname_chapters.update({student_chap.url_name:student_chap})
    final_chapters = OrderedDict()
    for chapter_index, chapter in enumerate(staff_chapters):
        fin_chap = urlname_chapters.get(chapter.url_name)
        if fin_chap:
            final_chapters.update({str(chapter_index+1):{'hidden': False, 'chapter':fin_chap}})
        else:
            final_chapters.update({str(chapter_index+1):{'hidden':True}})

    for section_index, chapter_info in final_chapters.items():
        # Mark as hidden and Skip the current chapter if a hide flag is tripped
        if chapter_info['hidden']:
            sections.append({
                'hidden': True,
                'week': "WEEK {week}: ".format(week=section_index),
                'points': {
                    'total': 0,
                    'earned': 0,
                    'css_class': 'text-disabled'
                },
            })
            continue

        chapter = chapter_info['chapter']
        # get the points
        section_points = section_grades.get(chapter.url_name, {})

        units = list()
        for sequential in chapter.get_display_items():
            # Set hidden status of the sequential if it is gated/hidden from the user
            hidden = (
                gated_content and unicode(sequential.location) in gated_content or
                sequential.hide_from_toc
            )

            if hidden:
                continue

            for index, unit in enumerate(sequential.get_display_items()):
                css_class = 'dark-gray'
                if unit.graded:
                    total_excercises = 0
                    attempted_excercises = 0
                    unit_max_score = 0
                    unit_score = 0
                    for component in unit.get_display_items():
                        if component.category == 'problem':
                            if component.graded:
                                total_excercises += 1
                                attempted_excercises += is_attempted_internal(
                                    str(component.location), progress
                                )
                                (correct, total) = grades.get_score(
                                    student,
                                    component,
                                    create_module,
                                    scores_client,
                                    submissions_scores,
                                    max_scores_cache,
                                )
                                unit_max_score += total
                                unit_score += correct

                    if total_excercises:
                        css_class = 'blue'
                        if attempted_excercises == total_excercises:
                            css_class = 'green'
                            if unit_max_score and unit_score / unit_max_score < success_cutoff:
                                css_class = 'red'

                position = index + 1  # For jumping to the unit directly
                unit_context = {
                    'display_name': unit.display_name_with_default_escaped,
                    'position': position,
                    'css_class': css_class,
                    'courseware_url': reverse(
                        'courseware_position',
                        args=[
                            course.id,
                            chapter.url_name,
                            sequential.url_name,
                            position
                        ]
                    )
                }
                units.append(unit_context)

        competency = None
        if int(section_points.get('total')):
            competency = int(section_points.get('earned')) == int(section_points.get('total'))
        section_context = {
            'display_name': chapter.display_name_with_default_escaped,
            'url_name': chapter.url_name,
            'hidden': False,
            'rank': 1,
            'competency': competency,
            'points': {
                'total': int(section_points.get('total')),
                'earned': int(section_points.get('earned')),
                'css_class': section_points.get('css_class')
            },
            'participation': discussions_participated.get(chapter.url_name),
            'units': units,
            'week': "WEEK {week}: ".format(week=section_index),
        }
        sections.append(section_context)

    return sections
コード例 #25
0
ファイル: views.py プロジェクト: geekaia/edx-platform
def _progress(request, course_key, student_id):
    """
    Unwrapped version of "progress".

    User progress. We show the grade bar and every problem score.

    Course staff are allowed to see the progress of students in their class.
    """
    course = get_course_with_access(request.user, 'load', course_key, depth=None)
    staff_access = has_access(request.user, 'staff', course)

    if student_id is None or student_id == request.user.id:
        # always allowed to see your own profile
        student = request.user
    else:
        # Requesting access to a different student's profile
        if not staff_access:
            raise Http404
        student = User.objects.get(id=int(student_id))

    # NOTE: To make sure impersonation by instructor works, use
    # student instead of request.user in the rest of the function.

    # The pre-fetching of groups is done to make auth checks not require an
    # additional DB lookup (this kills the Progress page in particular).
    student = User.objects.prefetch_related("groups").get(id=student.id)

    courseware_summary = grades.progress_summary(student, request, course)

    if courseware_summary is None:
        #This means the student didn't have access to the course (which the instructor requested)
        raise Http404
    else:
        i=0

        while i < len(courseware_summary):
            need = NeedThread(request.user, course)

            if need:
                print "Precisa de thread"
                mythread = CadVersao(courseware_summary[i]['url_name'], request.user)
                mythread.start()
                mythread.join()
                imprimir = mythread.getResult()
            else:
                print "Nao precisa de thread"
                imprimir = VerABprint(courseware_summary[i]['url_name'], request.user)

            if imprimir == False:
                del courseware_summary[i]
            else:
                i += 1

    studio_url = get_studio_url(course_key, 'settings/grading')
    grade_summary = grades.grade(student, request, course)

    context = {
        'course': course,
        'courseware_summary': courseware_summary,
        'studio_url': studio_url,
        'grade_summary': grade_summary,
        'staff_access': staff_access,
        'student': student,
        'reverifications': fetch_reverify_banner_info(request, course_key)
    }

    with grades.manual_transaction():
        response = render_to_response('courseware/progress.html', context)

    return response
コード例 #26
0
def index(request, course_id, chapter=None, section=None, position=None):
    """
    Displays courseware accordion and associated content.  If course, chapter,
    and section are all specified, renders the page, or returns an error if they
    are invalid.

    If section is not specified, displays the accordion opened to the right chapter.

    If neither chapter or section are specified, redirects to user's most recent
    chapter, or the first chapter if this is the user's first visit.

    Arguments:

     - request    : HTTP request
     - course_id  : course id (str: ORG/course/URL_NAME)
     - chapter    : chapter url_name (str)
     - section    : section url_name (str)
     - position   : position in module, eg of <sequential> module (str)

    Returns:

     - HTTPresponse
    """
    user = User.objects.prefetch_related("groups").get(id=request.user.id)

    request.user = user  # keep just one instance of User
    course = get_course_with_access(user, course_id, "load", depth=2)
    staff_access = has_access(user, course, "staff")
    registered = registered_for_course(course, user)
    if not registered:
        # TODO (vshnayder): do course instructors need to be registered to see course?
        log.debug("User %s tried to view course %s but is not enrolled" % (user, course.location.url()))
        return redirect(reverse("about_course", args=[course.id]))

    masq = setup_masquerade(request, staff_access)

    try:
        model_data_cache = ModelDataCache.cache_for_descriptor_descendents(course.id, user, course, depth=2)

        course_module = get_module_for_descriptor(user, request, course, model_data_cache, course.id)
        if course_module is None:
            log.warning(
                "If you see this, something went wrong: if we got this"
                " far, should have gotten a course module for this user"
            )
            return redirect(reverse("about_course", args=[course.id]))

        if chapter is None:
            return redirect_to_course_position(course_module)

        # check course constraints
        courses = modulestore().get_items(["i4x", None, None, "course", None])

        def course_filter(course):
            return (
                has_access(user, course, "see_exists")
                # TODO remove this condition when templates purged from db
                and course.location.course != "templates"
                and course.location.org != ""
                and course.location.course != ""
                and course.location.name != ""
            )

        courses = filter(course_filter, courses)
        courses_by_id = dict((course.location.url(), course) for course in courses)
        if not is_item_unlocked(course.unlock_term, courses_by_id, lambda course: grade(user, request, course)):
            raise Http404

        context = {
            "csrf": csrf(request)["csrf_token"],
            "accordion": render_accordion(request, course, chapter, section, model_data_cache),
            "COURSE_TITLE": course.display_name_with_default,
            "course": course,
            "init": "",
            "content": "",
            "staff_access": staff_access,
            "masquerade": masq,
            "xqa_server": settings.MITX_FEATURES.get("USE_XQA_SERVER", "http://*****:*****@content-qa.mitx.mit.edu/xqa"),
        }

        # Only show the chat if it's enabled by the course and in the
        # settings.
        show_chat = course.show_chat and settings.MITX_FEATURES["ENABLE_CHAT"]
        if show_chat:
            context["chat"] = chat_settings(course, user)
            # If we couldn't load the chat settings, then don't show
            # the widget in the courseware.
            if context["chat"] is None:
                show_chat = False

        context["show_chat"] = show_chat

        chapter_descriptor = course.get_child_by(lambda m: m.url_name == chapter)
        if chapter_descriptor is not None:
            save_child_position(course_module, chapter)
        else:
            raise Http404("No chapter descriptor found with name {}".format(chapter))

        chapter_module = course_module.get_child_by(lambda m: m.url_name == chapter)
        if chapter_module is None:
            # User may be trying to access a chapter that isn't live yet
            if masq == "student":  # if staff is masquerading as student be kinder, don't 404
                log.debug("staff masq as student: no chapter %s" % chapter)
                return redirect(reverse("courseware", args=[course.id]))
            raise Http404

        if section is not None:
            section_descriptor = chapter_descriptor.get_child_by(lambda m: m.url_name == section)

            if section_descriptor is None:
                # Specifically asked-for section doesn't exist
                if masq == "student":  # if staff is masquerading as student be kinder, don't 404
                    log.debug("staff masq as student: no section %s" % section)
                    return redirect(reverse("courseware", args=[course.id]))
                raise Http404

            # cdodge: this looks silly, but let's refetch the section_descriptor with depth=None
            # which will prefetch the children more efficiently than doing a recursive load
            section_descriptor = modulestore().get_instance(course.id, section_descriptor.location, depth=None)

            # Load all descendants of the section, because we're going to display its
            # html, which in general will need all of its children
            section_model_data_cache = ModelDataCache.cache_for_descriptor_descendents(
                course_id, user, section_descriptor, depth=None
            )
            section_module = get_module(
                request.user,
                request,
                section_descriptor.location,
                section_model_data_cache,
                course_id,
                position,
                depth=None,
            )

            if section_module is None:
                # User may be trying to be clever and access something
                # they don't have access to.
                raise Http404

            model_data_cache_for_check = ModelDataCache.cache_for_descriptor_descendents(
                course_id, user, course, depth=None
            )

            courseware_summary = grades.progress_summary(user, request, course, model_data_cache_for_check)

            is_section_unlocked = grades.return_section_by_id(section_module.url_name, courseware_summary)["unlocked"]

            # Save where we are in the chapter
            save_child_position(chapter_module, section)

            # check here if this section *is* a timed module.
            if section_module.category == "timelimit":
                timer_context = update_timelimit_module(
                    user, course_id, student_module_cache, section_descriptor, section_module
                )
                if "timer_expiration_duration" in timer_context:
                    context.update(timer_context)
                else:
                    # if there is no expiration defined, then we know the timer has expired:
                    return HttpResponseRedirect(timer_context["time_expired_redirect_url"])
            else:
                # check here if this page is within a course that has an active timed module running.  If so, then
                # add in the appropriate timer information to the rendering context:
                context.update(check_for_active_timelimit_module(request, course_id, course))

            # context['content'] = section_module.runtime.render(section_module, None, 'student_view').content

            if not is_section_unlocked:
                context["content"] = u"Раздел вам пока не доступен"
            else:
                context["content"] = section_module.runtime.render(section_module, None, "student_view").content
                # context['content'] = section_module.get_html()

        else:
            # section is none, so display a message
            prev_section = get_current_child(chapter_module)

            if prev_section is None:
                # Something went wrong -- perhaps this chapter has no sections visible to the user
                raise Http404
            prev_section_url = reverse(
                "courseware_section",
                kwargs={
                    "course_id": course_id,
                    "chapter": chapter_descriptor.url_name,
                    "section": prev_section.url_name,
                },
            )
            context["content"] = render_to_string(
                "courseware/welcome-back.html",
                {
                    "course": course,
                    "chapter_module": chapter_module,
                    "prev_section": prev_section,
                    "prev_section_url": prev_section_url,
                },
            )

        result = render_to_response("courseware/courseware.html", context)
    except Exception as e:
        if isinstance(e, Http404):
            # let it propagate
            raise

        # In production, don't want to let a 500 out for any reason
        if settings.DEBUG:
            raise
        else:
            log.exception(
                "Error in index view: user={user}, course={course},"
                " chapter={chapter} section={section}"
                "position={position}".format(
                    user=user, course=course, chapter=chapter, section=section, position=position
                )
            )
            try:
                result = render_to_response(
                    "courseware/courseware-error.html", {"staff_access": staff_access, "course": course}
                )
            except:
                # Let the exception propagate, relying on global config to at
                # at least return a nice error message
                log.exception("Error while rendering courseware-error page")
                raise

    return result
コード例 #27
0
def fullstat(request = None):

    request = DummyRequest()
    

    header = [u'ФИО', u'ФИО (измененное)', u'логин школы', u'email', u'email (измененное)', u'курс', u'зарег. в пакет рег.', u"дата рег. на курс", u'2/3', u'100%', u'Задачи/Задания(Модули)']
    assignments = []
    datatablefull = {'header': header, 'assignments': assignments, 'students': []}
    datafull = []

    for course in modulestore().get_courses():
        
        datarow = [u'-', u'-', u'-', u'-', u'-', course.id, u'-', u'-', u'-']
        
        assignments = []
        
        enrolled_students = User.objects.filter(
            courseenrollment__course_id=course.id,
        ).prefetch_related("groups").order_by('username')
        enrolled_students = [st for st in enrolled_students if not _has_staff_access_to_course_id(st, course.id)]
        
        if len(enrolled_students) <= 0:
            continue
            
        gradeset = student_grades(enrolled_students[0], request, course, keep_raw_scores=True, use_offline=False)
        courseware_summary = grades.progress_summary(enrolled_students[0], request, course);

        if courseware_summary is None:
            continue

        assignments += [score.section for score in gradeset['raw_scores']]
        
        for chapter in courseware_summary:
            for section in chapter['sections']:
                if not section['graded'] or len(section['format']) < 1:
                    continue
                assignments += [section['format']]
            assignments += [chapter['display_name']]

        datarow += assignments
        datafull.append(datarow)
        

    edxdata = gendata(request)


    print("Dumping fullstat")

    f = open("/opt/data.csv")

    if f is None:
        return False;

    ff = UnicodeDictReader(f, delimiter=';', quoting=csv.QUOTE_NONE)

    usermap = {}
    idx = 0
    for row in ff:
        idx += 1
        usermap.setdefault(row['email'],[]).append(row)

    
    for course in modulestore().get_courses():
        enrolled_students = User.objects.filter(
            courseenrollment__course_id=course.id,
            courseenrollment__is_active=1,
        ).prefetch_related("groups").order_by('username')
        enrolled_students = [st for st in enrolled_students if not _has_staff_access_to_course_id(st, course.id)]

        idx = 0
        for user in enrolled_students:
            try:
                idx += 1

                datarow = []

                found = False
                rows = []
                try:
                    for elem in user.profile.get_meta().get('old_emails',[])[::-1]:
                        if usermap[elem[0]]:
                            found = True
                            rows = usermap[elem[0]]
                            break
                    if not found and usermap[user.email]:
                        found = True
                        rows = usermap[user.email]
                except:
                    pass

                off_reg = False
                try:
                    for row in rows:
                        found = False
                        for course_id, course_name in coursemap.iteritems():
                            if course_name in row['subject']:
                                found = True
                                off_reg = True
                                break
                        if found:
                            break
                except:
                    pass
                

                #User
                name = ''
                try:
                    name = rows[0]['second-name'] + ' ' + rows[0]['first-name'] + ' ' + rows[0]['patronymic']
                except:
                    pass
                datarow += [name]
                if user.profile.name != name:
                    datarow += [user.profile.name]
                else:
                    datarow += [u'']
                try:
                    datarow += [rows[0]['login']]
                except:
                    datarow += ['']
                email = ''
                try:
                    datarow += [rows[0]['email']]
                    email = rows[0]['email']
                except:
                    datarow += ['']
                if user.email != email:
                    datarow += [user.email]
                else:
                    datarow += [u'']
                #Course
                datarow += [course.display_name]

                if off_reg:
                    datarow += [u'Да']
                else:
                    datarow += [u'Нет']

                try:
                    courseenrollment = user.courseenrollment_set.filter(course_id = course.id)[0]
                    datarow += [courseenrollment.created.strftime('%d/%m/%Y')]
                except:
                    continue
                
                #Raw statistic by problems
                statprob = edxdata[course.id][user.email]["prob_info"]
                
                #By subsection
                statsec = edxdata[course.id][user.email]["sec_info"]

                if edxdata[course.id][user.email]["0.7"]:
                    datarow += [u"Да"]
                else:
                    datarow += [u"Нет"]
                
                if edxdata[course.id][user.email]["1.0"]:
                    datarow += [u"Да"]
                else:
                    datarow += [u"Нет"]

                if len(statsec) > 0 and len(statprob) > 0:
                    datarow += statprob
                    datarow += statsec
                
                datafull.append(datarow)
            except:
                logging.exception("Something awful happened in fullstat!")
                pass
    datatablefull['data'] = datafull
    return_csv('full_stat.csv',datatablefull, open("/var/www/edx/fullstat.csv", "wb"))


    for course in modulestore().get_courses():

        print("Dumping course {courseid}".format(courseid = course.id))


        assignments = []
        
        enrolled_students = User.objects.filter(
            courseenrollment__course_id=course.id,
        ).prefetch_related("groups").order_by('username')
        enrolled_students = [st for st in enrolled_students if not _has_staff_access_to_course_id(st, course.id)]
        
        if len(enrolled_students) <= 0:
            continue

        gradeset = student_grades(enrolled_students[0], request, course, keep_raw_scores=True, use_offline=False)
        courseware_summary = grades.progress_summary(enrolled_students[0], request, course);

        if courseware_summary is None:
            print "No courseware_summary"
            continue

        assignments += [score.section for score in gradeset['raw_scores']]
        
        for chapter in courseware_summary:
            for section in chapter['sections']:
                if not section['graded'] or len(section['format']) < 1:
                    continue
                assignments += [section['format']]
            assignments += [chapter['display_name']]

        header = [u'ФИО', u'логин школы', u'email', u"дата регистрации на курс", u'2/3', u'100%']
        header += assignments
        datatable = {'header': header, 'assignments': assignments, 'students': []}
        data = []
                
        for user in enrolled_students:
            try:
                datarow = []

                #User
                name = user.profile.name
                datarow += [name]
                datarow += [user.profile.work_login]
                datarow += [user.email]

                courseenrollment = user.courseenrollment_set.filter(course_id = course.id)[0]

                datarow += [courseenrollment.created.strftime('%d/%m/%Y')]
                
                #Raw statistic by problems
                statprob = edxdata[course.id][user.email]["prob_info"]
                
                #By subsection
                statsec = edxdata[course.id][user.email]["sec_info"]

                if edxdata[course.id][user.email]["0.7"]:
                    datarow += [u"Да"]
                else:
                    datarow += [u"Нет"]
                
                if edxdata[course.id][user.email]["1.0"]:
                    datarow += [u"Да"]
                else:
                    datarow += [u"Нет"]


                if len(statsec) > 0 and len(statprob) > 0:
                    datarow += statprob
                    datarow += statsec
                else:
                    datarow += [0] * len(assignments)
                
                data.append(datarow)
            except:
                logging.exception("Something awful happened in {course_id}!".format(course_id = course.id))
                pass
        datatable['data'] = data
        return_csv(course.id,datatable, open("/var/www/edx/" + course.id.replace('/','_') + ".xls", "wb"), encoding="cp1251", dialect="excel-tab")
        return_csv(course.id,datatable, open("/var/www/edx/" + course.id.replace('/','_') + ".csv", "wb"))

    return True
コード例 #28
0
    def handle(self, *args, **options):
        help = "Command to create or update gradebook entries"
        option_list = BaseCommand.option_list + (
            make_option(
                "-c",
                "--course_ids",
                dest="course_ids",
                help="List of courses for which to generate grades",
                metavar="first/course/id,second/course/id"
            ),
            make_option(
                "-u",
                "--user_ids",
                dest="user_ids",
                help="List of users for which to generate grades",
                metavar="1234,2468,3579"
            ),
        )

        course_ids = options.get('course_ids')
        user_ids = options.get('user_ids')

        # Get the list of courses from the system
        courses = modulestore().get_courses()

        # If one or more courses were specified by the caller, just use those ones...
        if course_ids is not None:
            filtered_courses = []
            for course in courses:
                if unicode(course.id) in course_ids.split(','):
                    filtered_courses.append(course)
            courses = filtered_courses

        for course in courses:
            users = CourseEnrollment.objects.users_enrolled_in(course.id)
            # If one or more users were specified by the caller, just use those ones...
            if user_ids is not None:
                filtered_users = []
                for user in users:
                    if str(user.id) in user_ids.split(','):
                        filtered_users.append(user)
                users = filtered_users

            # For each user...
            for user in users:
                request = RequestMockWithoutMiddleware().get('/')
                request.user = user
                grade_data = grades.grade(user, request, course)
                grade = grade_data['percent']
                grading_policy = course.grading_policy
                proforma_grade = grades.calculate_proforma_grade(grade_data, grading_policy)
                progress_summary = grades.progress_summary(user, request, course)
                try:
                    gradebook_entry = StudentGradebook.objects.get(user=user, course_id=course.id)
                    if (gradebook_entry.grade != grade or
                            gradebook_entry.proforma_grade != proforma_grade or
                            gradebook_entry.progress_summary != progress_summary or
                            gradebook_entry.grade_summary != grade_data or
                            gradebook_entry.grading_policy != grading_policy):
                        gradebook_entry.grade = grade
                        gradebook_entry.proforma_grade = proforma_grade
                        gradebook_entry.progress_summary = json.dumps(progress_summary, cls=EdxJSONEncoder)
                        gradebook_entry.grade_summary = json.dumps(grade_data, cls=EdxJSONEncoder)
                        gradebook_entry.grading_policy = json.dumps(grading_policy, cls=EdxJSONEncoder)
                        gradebook_entry.save()
                except StudentGradebook.DoesNotExist:
                    StudentGradebook.objects.create(
                        user=user,
                        course_id=course.id,
                        grade=grade,
                        proforma_grade=proforma_grade,
                        progress_summary=json.dumps(progress_summary, cls=EdxJSONEncoder),
                        grade_summary=json.dumps(grade_data, cls=EdxJSONEncoder),
                        grading_policy=json.dumps(grading_policy, cls=EdxJSONEncoder)
                    )
                log_msg = 'Gradebook entry created -- Course: {}, User: {}  (grade: {}, proforma_grade: {})'.format(course.id, user.id, grade, proforma_grade)
                print log_msg
                log.info(log_msg)
コード例 #29
0
def gendata(request):
    data = {}
    for course in modulestore().get_courses():
        data[course.id] = {}
        print("Loading info for course {courseid}".format(courseid = course.id))
        
        enrolled_students = User.objects.filter(
            courseenrollment__course_id=course.id,
        ).prefetch_related("groups").order_by('username')
        enrolled_students = [st for st in enrolled_students if not _has_staff_access_to_course_id(st, course.id)]
        
        if len(enrolled_students) <= 0:
            continue

        #Category weights
        gradeset = student_grades(enrolled_students[0], request, course, keep_raw_scores=False, use_offline=False)
        category_weights = {}

        for section in gradeset['grade_breakdown']:
            category_weights[section['category']] = section['weight']    

        for user in enrolled_students:
            data[course.id][user.email] = {}

            #User
            data[course.id][user.email]["user"] = user

            #Raw statistic by problems
            gradeset = student_grades(user, request, course, keep_raw_scores=True, use_offline=False)
            statprob = [(getattr(score, 'earned', '') or score[0]) for score in gradeset['raw_scores']]
            
            #By subsection
            statsec = []
            complition = 0
            complition_cnt = 0
                
            try:
                courseware_summary = grades.progress_summary(user, request, course);

                for chapter in courseware_summary:
                    total = 0
                    flag = False
                    for section in chapter['sections']:
                        if not section['graded'] or len(section['format']) < 1:
                            continue
                        flag = True
                        statsec += [((section['section_total'].earned / section['section_total'].possible) if section['section_total'].possible else 0)]
                        total += ((section['section_total'].earned / section['section_total'].possible) if section['section_total'].possible else 0) * category_weights.get(section['format'], 0.0)
                    statsec += [total]
                    if flag:
                        complition += total
                        complition_cnt += 1
            except:
                pass

            if complition_cnt == 0:
                complition = 0
            else:
                complition = complition / complition_cnt
            if complition > 0.7:
                data[course.id][user.email]["0.7"] =  True
            else:
                data[course.id][user.email]["0.7"] =  False
            
            if complition > 0.99:
                data[course.id][user.email]["1.0"] =  True
            else:
                data[course.id][user.email]["1.0"] =  False

            data[course.id][user.email]["prob_info"] = statprob
            data[course.id][user.email]["sec_info"] = statsec
        print("Loading info for course {courseid} - COMPLETE - total {users}".format(courseid = course.id, users = len (data[course.id]) ))
    return data
コード例 #30
0
ファイル: views.py プロジェクト: pelikanchik/edx-platform
def index(request, course_id, chapter=None, section=None,
          position=None):
    """
    Displays courseware accordion and associated content.  If course, chapter,
    and section are all specified, renders the page, or returns an error if they
    are invalid.

    If section is not specified, displays the accordion opened to the right chapter.

    If neither chapter or section are specified, redirects to user's most recent
    chapter, or the first chapter if this is the user's first visit.

    Arguments:

     - request    : HTTP request
     - course_id  : course id (str: ORG/course/URL_NAME)
     - chapter    : chapter url_name (str)
     - section    : section url_name (str)
     - position   : position in module, eg of <sequential> module (str)

    Returns:

     - HTTPresponse
    """
    user = User.objects.prefetch_related("groups").get(id=request.user.id)
    request.user = user	# keep just one instance of User

    # Если пользователь не активен - отправляем на главную страницу

    if not user.is_active and not user.profile.is_demo:
        return redirect('/')

    try:
        course = get_course_with_access(user, course_id, 'load', depth=2)
    except:
        return redirect('/')

    # Если курс помечен, как непубликуемый в LMS - отправляем на главную страницу
    if not course.show_in_lms:
       return redirect('/')


    staff_access = has_access(user, course, 'staff')

    registered = registered_for_course(course, user)
    if not registered:
        # TODO (vshnayder): do course instructors need to be registered to see course?
        log.debug('User %s tried to view course %s but is not enrolled' % (user, course.location.url()))
        return redirect(reverse('about_course', args=[course.id]))

    masq = setup_masquerade(request, staff_access)

    try:
        field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
            course.id, user, course, depth=2)

        course_module = get_module_for_descriptor(user, request, course, field_data_cache, course.id)
        if course_module is None:
            log.warning('If you see this, something went wrong: if we got this'
                        ' far, should have gotten a course module for this user')
            return redirect(reverse('about_course', args=[course.id]))

        if chapter is None:
            return redirect_to_course_position(course_module)

        context = {
            'csrf': csrf(request)['csrf_token'],
            'accordion': render_accordion(request, course, chapter, section, field_data_cache),
            'COURSE_TITLE': course.display_name_with_default,
            'course': course,
            'init': '',
            'fragment': Fragment(),
            'staff_access': staff_access,
            'masquerade': masq,
            'xqa_server': settings.FEATURES.get('USE_XQA_SERVER', 'http://*****:*****@content-qa.mitx.mit.edu/xqa')
            }

        # Only show the chat if it's enabled by the course and in the
        # settings.
        show_chat = course.show_chat and settings.FEATURES['ENABLE_CHAT']
        if show_chat:
            context['chat'] = chat_settings(course, user)
            # If we couldn't load the chat settings, then don't show
            # the widget in the courseware.
            if context['chat'] is None:
                show_chat = False

        context['show_chat'] = show_chat

        chapter_descriptor = course.get_child_by(lambda m: m.url_name == chapter)
        if chapter_descriptor is not None:
            save_child_position(course_module, chapter)
        else:
            raise Http404('No chapter descriptor found with name {}'.format(chapter))

        chapter_module = course_module.get_child_by(lambda m: m.url_name == chapter)
        if chapter_module is None:
            # User may be trying to access a chapter that isn't live yet
            if masq=='student':  # if staff is masquerading as student be kinder, don't 404
                log.debug('staff masq as student: no chapter %s' % chapter)
                return redirect(reverse('courseware', args=[course.id]))
            raise Http404

        if section is not None:
            section_descriptor = chapter_descriptor.get_child_by(lambda m: m.url_name == section)
            if section_descriptor is None:
                # Specifically asked-for section doesn't exist
                if masq=='student':  # if staff is masquerading as student be kinder, don't 404
                    log.debug('staff masq as student: no section %s' % section)
                    return redirect(reverse('courseware', args=[course.id]))
                raise Http404

            # cdodge: this looks silly, but let's refetch the section_descriptor with depth=None
            # which will prefetch the children more efficiently than doing a recursive load
            section_descriptor = modulestore().get_instance(course.id, section_descriptor.location, depth=None)

            # Load all descendants of the section, because we're going to display its
            # html, which in general will need all of its children
            section_field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
                course_id, user, section_descriptor, depth=None)

            section_module = get_module_for_descriptor(request.user,
                request,
                section_descriptor,
                section_field_data_cache,
                course_id,
                position
            )

            if section_module is None:
                # User may be trying to be clever and access something
                # they don't have access to.
                raise Http404

            # model_data_cache_for_check = ModelDataCache.cache_for_descriptor_descendents(course_id, user, course, depth=None)

            courseware_summary = grades.progress_summary(user, request, course)


            is_section_unlocked = grades.return_section_by_id(section_module.url_name, courseware_summary)['unlocked']



            #Контент раздела закрыт для демопользователя
            is_demo = UserProfile.objects.get(user=request.user).is_demo
            if is_demo and not section_module.available_for_demo:
                is_section_unlocked = False

            # Save where we are in the chapter
            save_child_position(chapter_module, section)
            context['fragment'] = section_module.render('student_view', context)

        else:
            # section is none, so display a message
            prev_section = get_current_child(chapter_module)
            if prev_section is None:
                # Something went wrong -- perhaps this chapter has no sections visible to the user
                raise Http404
            prev_section_url = reverse('courseware_section', kwargs={'course_id': course_id,
                                                                     'chapter': chapter_descriptor.url_name,
                                                                     'section': prev_section.url_name})
            context['fragment'] = Fragment(content=render_to_string(
                'courseware/welcome-back.html',
                {
                    'course': course,
                    'chapter_module': chapter_module,
                    'prev_section': prev_section,
                    'prev_section_url': prev_section_url
                }
            ))

        result = render_to_response('courseware/courseware.html', context)
    except Exception as e:
        if isinstance(e, Http404):
            # let it propagate
            raise

        # In production, don't want to let a 500 out for any reason
        if settings.DEBUG:
            raise
        else:
            log.exception("Error in index view: user={user}, course={course},"
                          " chapter={chapter} section={section}"
                          "position={position}".format(
                              user=user,
                              course=course,
                              chapter=chapter,
                              section=section,
                              position=position
                              ))
            try:
                result = render_to_response('courseware/courseware-error.html',
                                            {'staff_access': staff_access,
                                            'course': course})
            except:
                # Let the exception propagate, relying on global config to at
                # at least return a nice error message
                log.exception("Error while rendering courseware-error page")
                raise

    return result
コード例 #31
0
def course_data(request, course_id):
    """
    Get course's data(title, short description), Total Points/Earned Points
    or 404 if there is no such course.

    Assumes the course_id is in a valid format.
    """
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    with modulestore().bulk_operations(course_key):
        course = get_course_with_access(request.user, 'load', course_key, depth=None, check_if_enrolled=True)
        access_response = has_access(request.user, 'load', course, course_key)

        context={}
        if course.has_started():
            staff_access = bool(has_access(request.user, 'staff', course))

            student = request.user

            # NOTE: To make sure impersonation by instructor works, use
            # student instead of request.user in the rest of the function.

            # The pre-fetching of groups is done to make auth checks not require an
            # additional DB lookup (this kills the Progress page in particular).
            student = User.objects.prefetch_related("groups").get(id=student.id)

            with outer_atomic():
                field_data_cache = grades.field_data_cache_for_grading(course, student)
                scores_client = ScoresClient.from_field_data_cache(field_data_cache)

            title = course.display_name_with_default
            loc = course.location.replace(category='about', name='short_description')
            about_module = get_module(
                        request.user,
                        request,
                        loc,
                        field_data_cache,
                        log_if_not_found=False,
                        wrap_xmodule_display=False,
                        static_asset_path=course.static_asset_path,
                        course=course
                    )
            short_description = about_module.render(STUDENT_VIEW).content

            courseware_summary = grades.progress_summary(
                student, request, course, field_data_cache=field_data_cache, scores_client=scores_client
            )

            grade_summary = grades.grade(
                student, request, course, field_data_cache=field_data_cache, scores_client=scores_client
            )

            total_points = 0
            earned_points = 0
            for chapter in courseware_summary:
                for section in chapter['sections']:
                    total_points += section['section_total'].possible
                    earned_points += section['section_total'].earned

            percentage_points = float(earned_points)*(100.0/float(total_points))

            context = {
                "started": course.has_started(),
                "course_image": course_image_url(course),
                "total": total_points,
                "earned": earned_points,
                "percentage": percentage_points,
                'title': title,
                'short_description' : short_description,
                'staff_access': staff_access,
                'student': student.id,
                'passed': is_course_passed(course, grade_summary),
            }
        else:
            context={
                "started": course.has_started(),
            }

        return JsonResponse(context)