instructor_dashboard.py 5.83 KB
Newer Older
1 2 3 4
"""
Instructor Dashboard Views
"""

Miles Steele committed
5
from django.utils.translation import ugettext as _
6 7 8 9 10
from django_future.csrf import ensure_csrf_cookie
from django.views.decorators.cache import cache_control
from mitxmako.shortcuts import render_to_response
from django.core.urlresolvers import reverse
from django.utils.html import escape
11
from django.http import Http404
12

13
from courseware.access import has_access
14
from courseware.courses import get_course_by_id
15
from django_comment_client.utils import has_forum_access
Miles Steele committed
16
from django_comment_common.models import FORUM_ROLE_ADMINISTRATOR
17 18 19 20 21 22 23
from xmodule.modulestore.django import modulestore
from student.models import CourseEnrollment


@ensure_csrf_cookie
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
def instructor_dashboard_2(request, course_id):
24
    """ Display the instructor dashboard for a course. """
25

26 27
    course = get_course_by_id(course_id, depth=None)

Miles Steele committed
28
    access = {
29
        'admin': request.user.is_staff,
30 31 32 33 34
        'instructor': has_access(request.user, course, 'instructor'),
        'staff': has_access(request.user, course, 'staff'),
        'forum_admin': has_forum_access(
            request.user, course_id, FORUM_ROLE_ADMINISTRATOR
        ),
Miles Steele committed
35 36
    }

37
    if not access['staff']:
38
        raise Http404()
39

40 41
    sections = [
        _section_course_info(course_id),
Miles Steele committed
42
        _section_membership(course_id, access),
43
        _section_student_admin(course_id, access),
44 45 46
        _section_data_download(course_id),
        _section_analytics(course_id),
    ]
47 48 49

    context = {
        'course': course,
50
        'old_dashboard_url': reverse('instructor_dashboard', kwargs={'course_id': course_id}),
51
        'sections': sections,
52 53
    }

54
    return render_to_response('instructor/instructor_dashboard_2/instructor_dashboard_2.html', context)
55 56


57 58 59 60 61 62 63 64
"""
Section functions starting with _section return a dictionary of section data.

The dictionary must include at least {
    'section_key': 'circus_expo'
    'section_display_name': 'Circus Expo'
}

Miles Steele committed
65
section_key will be used as a css attribute, javascript tie-in, and template import filename.
66
section_display_name will be used to generate link titles in the nav bar.
Miles Steele committed
67
"""  # pylint: disable=W0105
68 69 70


def _section_course_info(course_id):
71
    """ Provide data for the corresponding dashboard section """
72
    course = get_course_by_id(course_id, depth=None)
73 74

    section_data = {}
75
    section_data['section_key'] = 'course_info'
Miles Steele committed
76
    section_data['section_display_name'] = _('Course Info')
77
    section_data['course_id'] = course_id
78
    section_data['course_display_name'] = course.display_name
79 80 81
    section_data['enrollment_count'] = CourseEnrollment.objects.filter(course_id=course_id).count()
    section_data['has_started'] = course.has_started()
    section_data['has_ended'] = course.has_ended()
Miles Steele committed
82

Miles Steele committed
83
    try:
Miles Steele committed
84 85 86
        advance = lambda memo, (letter, score): "{}: {}, ".format(letter, score) + memo
        section_data['grade_cutoffs'] = reduce(advance, course.grade_cutoffs.items(), "")[:-2]
    except Exception:
Miles Steele committed
87 88
        section_data['grade_cutoffs'] = "Not Available"
    # section_data['offline_grades'] = offline_grades_available(course_id)
89 90

    try:
Miles Steele committed
91
        section_data['course_errors'] = [(escape(a), '') for (a, _unused) in modulestore().get_item_errors(course.location)]
92 93 94 95 96 97
    except Exception:
        section_data['course_errors'] = [('Error fetching errors', '')]

    return section_data


Miles Steele committed
98
def _section_membership(course_id, access):
99
    """ Provide data for the corresponding dashboard section """
100
    section_data = {
101
        'section_key': 'membership',
Miles Steele committed
102
        'section_display_name': _('Membership'),
Miles Steele committed
103
        'access': access,
104 105
        'enroll_button_url': reverse('students_update_enrollment', kwargs={'course_id': course_id}),
        'unenroll_button_url': reverse('students_update_enrollment', kwargs={'course_id': course_id}),
106
        'list_course_role_members_url': reverse('list_course_role_members', kwargs={'course_id': course_id}),
107
        'modify_access_url': reverse('modify_access', kwargs={'course_id': course_id}),
Miles Steele committed
108 109
        'list_forum_members_url': reverse('list_forum_members', kwargs={'course_id': course_id}),
        'update_forum_role_membership_url': reverse('update_forum_role_membership', kwargs={'course_id': course_id}),
110
    }
111 112 113
    return section_data


114
def _section_student_admin(course_id, access):
115
    """ Provide data for the corresponding dashboard section """
116 117
    section_data = {
        'section_key': 'student_admin',
Miles Steele committed
118
        'section_display_name': _('Student Admin'),
119
        'access': access,
120
        'get_student_progress_url_url': reverse('get_student_progress_url', kwargs={'course_id': course_id}),
121
        'enrollment_url': reverse('students_update_enrollment', kwargs={'course_id': course_id}),
122
        'reset_student_attempts_url': reverse('reset_student_attempts', kwargs={'course_id': course_id}),
Miles Steele committed
123 124
        'rescore_problem_url': reverse('rescore_problem', kwargs={'course_id': course_id}),
        'list_instructor_tasks_url': reverse('list_instructor_tasks', kwargs={'course_id': course_id}),
125
    }
126 127 128 129 130 131
    return section_data


def _section_data_download(course_id):
    """ Provide data for the corresponding dashboard section """
    section_data = {
132
        'section_key': 'data_download',
Miles Steele committed
133
        'section_display_name': _('Data Download'),
134 135
        'get_grading_config_url': reverse('get_grading_config', kwargs={'course_id': course_id}),
        'get_students_features_url': reverse('get_students_features', kwargs={'course_id': course_id}),
136 137 138 139 140 141 142
    }
    return section_data


def _section_analytics(course_id):
    """ Provide data for the corresponding dashboard section """
    section_data = {
143
        'section_key': 'analytics',
Miles Steele committed
144
        'section_display_name': _('Analytics'),
145
        'get_distribution_url': reverse('get_distribution', kwargs={'course_id': course_id}),
146
        'proxy_legacy_analytics_url': reverse('proxy_legacy_analytics', kwargs={'course_id': course_id}),
147 148
    }
    return section_data