fix pep8 violations, fix pylint violations
This commit is contained in:
@@ -9,7 +9,8 @@ import xmodule.graders as xmgraders
|
||||
|
||||
|
||||
STUDENT_FEATURES = ('username', 'first_name', 'last_name', 'is_staff', 'email')
|
||||
PROFILE_FEATURES = ('name', 'language', 'location', 'year_of_birth', 'gender', 'level_of_education', 'mailing_address', 'goals')
|
||||
PROFILE_FEATURES = ('name', 'language', 'location', 'year_of_birth', 'gender',
|
||||
'level_of_education', 'mailing_address', 'goals')
|
||||
AVAILABLE_FEATURES = STUDENT_FEATURES + PROFILE_FEATURES
|
||||
|
||||
|
||||
@@ -19,17 +20,19 @@ def enrolled_students_profiles(course_id, features):
|
||||
"""
|
||||
# enrollments = CourseEnrollment.objects.filter(course_id=course_id)
|
||||
# students = [enrollment.user for enrollment in enrollments]
|
||||
students = User.objects.filter(courseenrollment__course_id=course_id).order_by('username').select_related('profile')
|
||||
print len(students)
|
||||
print students
|
||||
students = User.objects.filter(courseenrollment__course_id=course_id)\
|
||||
.order_by('username').select_related('profile')
|
||||
|
||||
def extract_student(student):
|
||||
student_features = [feature for feature in features if feature in STUDENT_FEATURES]
|
||||
profile_features = [feature for feature in features if feature in PROFILE_FEATURES]
|
||||
""" convert student to dictionary """
|
||||
student_features = [x for x in STUDENT_FEATURES if x in features]
|
||||
profile_features = [x for x in PROFILE_FEATURES if x in features]
|
||||
|
||||
student_dict = dict((feature, getattr(student, feature)) for feature in student_features)
|
||||
student_dict = dict((feature, getattr(student, feature))
|
||||
for feature in student_features)
|
||||
profile = student.profile
|
||||
profile_dict = dict((feature, getattr(profile, feature)) for feature in profile_features)
|
||||
profile_dict = dict((feature, getattr(profile, feature))
|
||||
for feature in profile_features)
|
||||
student_dict.update(profile_dict)
|
||||
return student_dict
|
||||
|
||||
@@ -38,12 +41,14 @@ def enrolled_students_profiles(course_id, features):
|
||||
|
||||
def dump_grading_context(course):
|
||||
"""
|
||||
Render information about course grading context (eg which problems are graded in what assignments)
|
||||
Render information about course grading context
|
||||
(e.g. which problems are graded in what assignments)
|
||||
Useful for debugging grading_policy.json and policy.json
|
||||
|
||||
Returns HTML string
|
||||
"""
|
||||
msg = "-----------------------------------------------------------------------------\n"
|
||||
hbar = "{}\n".format("-" * 77)
|
||||
msg = hbar
|
||||
msg += "Course grader:\n"
|
||||
|
||||
msg += '%s\n' % course.grader.__class__
|
||||
@@ -52,34 +57,36 @@ def dump_grading_context(course):
|
||||
msg += '\n'
|
||||
msg += "Graded sections:\n"
|
||||
for subgrader, category, weight in course.grader.sections:
|
||||
msg += " subgrader=%s, type=%s, category=%s, weight=%s\n" % (subgrader.__class__, subgrader.type, category, weight)
|
||||
msg += " subgrader=%s, type=%s, category=%s, weight=%s\n"\
|
||||
% (subgrader.__class__, subgrader.type, category, weight)
|
||||
subgrader.index = 1
|
||||
graders[subgrader.type] = subgrader
|
||||
msg += "-----------------------------------------------------------------------------\n"
|
||||
msg += hbar
|
||||
msg += "Listing grading context for course %s\n" % course.id
|
||||
|
||||
gc = course.grading_context
|
||||
gcontext = course.grading_context
|
||||
msg += "graded sections:\n"
|
||||
|
||||
msg += '%s\n' % gc['graded_sections'].keys()
|
||||
for (gs, gsvals) in gc['graded_sections'].items():
|
||||
msg += "--> Section %s:\n" % (gs)
|
||||
msg += '%s\n' % gcontext['graded_sections'].keys()
|
||||
for (gsomething, gsvals) in gcontext['graded_sections'].items():
|
||||
msg += "--> Section %s:\n" % (gsomething)
|
||||
for sec in gsvals:
|
||||
s = sec['section_descriptor']
|
||||
format = getattr(s.lms, 'format', None)
|
||||
sdesc = sec['section_descriptor']
|
||||
frmat = getattr(sdesc.lms, 'format', None)
|
||||
aname = ''
|
||||
if format in graders:
|
||||
g = graders[format]
|
||||
aname = '%s %02d' % (g.short_label, g.index)
|
||||
g.index += 1
|
||||
elif s.display_name in graders:
|
||||
g = graders[s.display_name]
|
||||
aname = '%s' % g.short_label
|
||||
if frmat in graders:
|
||||
gform = graders[frmat]
|
||||
aname = '%s %02d' % (gform.short_label, gform.index)
|
||||
gform.index += 1
|
||||
elif sdesc.display_name in graders:
|
||||
gform = graders[sdesc.display_name]
|
||||
aname = '%s' % gform.short_label
|
||||
notes = ''
|
||||
if getattr(s, 'score_by_attempt', False):
|
||||
if getattr(sdesc, 'score_by_attempt', False):
|
||||
notes = ', score by attempt!'
|
||||
msg += " %s (format=%s, Assignment=%s%s)\n" % (s.display_name, format, aname, notes)
|
||||
msg += " %s (format=%s, Assignment=%s%s)\n"\
|
||||
% (sdesc.display_name, frmat, aname, notes)
|
||||
msg += "all descriptors:\n"
|
||||
msg += "length=%d\n" % len(gc['all_descriptors'])
|
||||
msg = '<pre>%s</pre>' % msg.replace('<','<')
|
||||
msg += "length=%d\n" % len(gcontext['all_descriptors'])
|
||||
msg = '<pre>%s</pre>' % msg.replace('<', '<')
|
||||
return msg
|
||||
|
||||
@@ -16,8 +16,14 @@ def create_csv_response(filename, header, datarows):
|
||||
datarows e.g. [['Jim', 'jim@edy.org'], ['Jake', 'jake@edy.org'], ...]
|
||||
"""
|
||||
response = HttpResponse(mimetype='text/csv')
|
||||
response['Content-Disposition'] = 'attachment; filename={0}'.format(filename)
|
||||
csvwriter = csv.writer(response, dialect='excel', quotechar='"', quoting=csv.QUOTE_ALL)
|
||||
response['Content-Disposition'] = 'attachment; filename={0}'\
|
||||
.format(filename)
|
||||
csvwriter = csv.writer(
|
||||
response,
|
||||
dialect='excel',
|
||||
quotechar='"',
|
||||
quoting=csv.QUOTE_ALL)
|
||||
|
||||
csvwriter.writerow(header)
|
||||
for datarow in datarows:
|
||||
encoded_row = [unicode(s).encode('utf-8') for s in datarow]
|
||||
@@ -56,14 +62,15 @@ def format_dictlist(dictlist):
|
||||
else:
|
||||
header = []
|
||||
|
||||
def dict_to_entry(d):
|
||||
ordered = sorted(d.items(), key=lambda (k, v): header.index(k))
|
||||
vals = map(lambda (k, v): v, ordered)
|
||||
def dict_to_entry(dct):
|
||||
""" Convert dictionary to list for a csv row """
|
||||
ordered = sorted(dct.items(), key=lambda (k, v): header.index(k))
|
||||
vals = [v for (_, v) in ordered]
|
||||
return vals
|
||||
|
||||
datarows = map(dict_to_entry, dictlist)
|
||||
|
||||
return {
|
||||
'header': header,
|
||||
'header': header,
|
||||
'datarows': datarows,
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ Profile Distributions
|
||||
"""
|
||||
|
||||
from django.db.models import Count
|
||||
from django.contrib.auth.models import User, Group
|
||||
from student.models import CourseEnrollment, UserProfile
|
||||
|
||||
AVAILABLE_PROFILE_FEATURES = ['gender', 'level_of_education', 'year_of_birth']
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
"""
|
||||
Tests for instructor.basic
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
from django.contrib.auth.models import User, Group
|
||||
from student.models import CourseEnrollment
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from student.tests.factories import UserFactory
|
||||
|
||||
from analytics.basic import enrolled_students_profiles, AVAILABLE_FEATURES, STUDENT_FEATURES, PROFILE_FEATURES
|
||||
|
||||
|
||||
class TestAnalyticsBasic(TestCase):
|
||||
'''Test basic analytics functions.'''
|
||||
""" Test basic analytics functions. """
|
||||
|
||||
def setUp(self):
|
||||
self.course_id = 'some/robot/course/id'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
""" Tests for analytics.csvs """
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from analytics.csvs import create_csv_response, format_dictlist
|
||||
@@ -57,7 +59,6 @@ class TestAnalyticsCSVS(TestCase):
|
||||
|
||||
self.assertEqual(format_dictlist(data_in), data_out)
|
||||
|
||||
|
||||
def test_format_dictlist_empty(self):
|
||||
self.assertEqual(format_dictlist([]), {
|
||||
'header': [],
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
""" Tests for analytics.distributions """
|
||||
|
||||
from django.test import TestCase
|
||||
from nose.tools import raises
|
||||
from django.contrib.auth.models import User, Group
|
||||
from student.models import CourseEnrollment
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from student.tests.factories import UserFactory
|
||||
|
||||
from analytics.distributions import profile_distribution, AVAILABLE_PROFILE_FEATURES
|
||||
|
||||
@@ -9,12 +9,13 @@ TODO sync instructor and staff flags
|
||||
{instructor: true, staff: true}
|
||||
"""
|
||||
|
||||
from django.contrib.auth.models import User, Group
|
||||
from courseware.access import get_access_group_name, course_beta_test_group_name
|
||||
from django_comment_common.models import (Role,
|
||||
FORUM_ROLE_ADMINISTRATOR,
|
||||
FORUM_ROLE_MODERATOR,
|
||||
FORUM_ROLE_COMMUNITY_TA)
|
||||
from django.contrib.auth.models import Group
|
||||
from courseware.access import (get_access_group_name,
|
||||
course_beta_test_group_name)
|
||||
from django_comment_common.models import Role
|
||||
# FORUM_ROLE_ADMINISTRATOR,
|
||||
# FORUM_ROLE_MODERATOR,
|
||||
# FORUM_ROLE_COMMUNITY_TA)
|
||||
|
||||
|
||||
def list_with_level(course, level):
|
||||
|
||||
@@ -28,10 +28,10 @@ def enroll_emails(course_id, student_emails, auto_enroll=False):
|
||||
auto_string = {False: 'allowed', True: 'willautoenroll'}[auto_enroll]
|
||||
|
||||
status_map = {
|
||||
'user/ce/alreadyenrolled': [],
|
||||
'user/!ce/enrolled': [],
|
||||
'user/!ce/rejected': [],
|
||||
'!user/cea/' + auto_string: [],
|
||||
'user/ce/alreadyenrolled': [],
|
||||
'user/!ce/enrolled': [],
|
||||
'user/!ce/rejected': [],
|
||||
'!user/cea/' + auto_string: [],
|
||||
'!user/!cea/' + auto_string: [],
|
||||
}
|
||||
|
||||
@@ -48,11 +48,11 @@ def enroll_emails(course_id, student_emails, auto_enroll=False):
|
||||
except CourseEnrollment.DoesNotExist:
|
||||
# status: user/!ce/enrolled
|
||||
try:
|
||||
ce = CourseEnrollment(user=user, course_id=course_id)
|
||||
ce.save()
|
||||
cenr = CourseEnrollment(user=user, course_id=course_id)
|
||||
cenr.save()
|
||||
status_map['user/!ce/enrolled'].append(student_email)
|
||||
# status: user/!ce/rejected
|
||||
except:
|
||||
except Exception:
|
||||
status_map['user/!ce/rejected'].append(student_email)
|
||||
# status: !user
|
||||
except User.DoesNotExist:
|
||||
@@ -106,9 +106,9 @@ def unenroll_emails(course_id, student_emails):
|
||||
|
||||
# delete CourseEnrollment
|
||||
try:
|
||||
ce = CourseEnrollment.objects.get(course_id=course_id, user__email=student_email)
|
||||
cenr = CourseEnrollment.objects.get(course_id=course_id, user__email=student_email)
|
||||
try:
|
||||
ce.delete()
|
||||
cenr.delete()
|
||||
status_map['ce/unenrolled'].append(student_email)
|
||||
except Exception:
|
||||
status_map['ce/rejected'].append(student_email)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
from django.test import TestCase
|
||||
"""
|
||||
Test instructor.access
|
||||
"""
|
||||
|
||||
from nose.tools import raises
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.contrib.auth.models import Group
|
||||
from student.tests.factories import UserFactory
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
@@ -9,10 +12,9 @@ from django.test.utils import override_settings
|
||||
from django.conf import settings
|
||||
from uuid import uuid4
|
||||
|
||||
from student.models import CourseEnrollment, CourseEnrollmentAllowed
|
||||
from courseware.access import get_access_group_name
|
||||
from django_comment_common.models import (Role,
|
||||
FORUM_ROLE_ADMINISTRATOR,
|
||||
# FORUM_ROLE_ADMINISTRATOR,
|
||||
FORUM_ROLE_MODERATOR,
|
||||
FORUM_ROLE_COMMUNITY_TA)
|
||||
from instructor.access import allow_access, revoke_access, list_with_level, update_forum_role_membership
|
||||
@@ -24,11 +26,11 @@ from instructor.access import allow_access, revoke_access, list_with_level, upda
|
||||
# moved here from old courseware/tests/tests.py
|
||||
# when it disappeared this test broke.
|
||||
def mongo_store_config(data_dir):
|
||||
'''
|
||||
"""
|
||||
Defines default module store using MongoModuleStore
|
||||
|
||||
Use of this config requires mongo to be running
|
||||
'''
|
||||
"""
|
||||
store = {
|
||||
'default': {
|
||||
'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
|
||||
@@ -52,7 +54,7 @@ TEST_DATA_MONGO_MODULESTORE = mongo_store_config(TEST_DATA_DIR)
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
|
||||
class TestInstructorAccessControlDB(ModuleStoreTestCase):
|
||||
'''Test instructor access administration against database effects'''
|
||||
""" Test instructor access administration against database effects """
|
||||
|
||||
def setUp(self):
|
||||
# self.course_id = 'jus:/a/fake/c::rse/id'
|
||||
@@ -132,12 +134,16 @@ class TestInstructorAccessControlDB(ModuleStoreTestCase):
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
|
||||
class TestInstructorAccessControlPrefilledDB(ModuleStoreTestCase):
|
||||
"""
|
||||
Test access with existing users.
|
||||
"""
|
||||
def setUp(self):
|
||||
self.course = CourseFactory.create()
|
||||
|
||||
# setup instructors
|
||||
self.instructors = set([UserFactory.create(), UserFactory.create()])
|
||||
[allow_access(self.course, user, 'instructor') for user in self.instructors]
|
||||
for user in self.instructors:
|
||||
allow_access(self.course, user, 'instructor')
|
||||
|
||||
def test_list_with_level(self):
|
||||
instructors = set(list_with_level(self.course, 'instructor'))
|
||||
@@ -155,63 +161,68 @@ class TestInstructorAccessControlPrefilledDB(ModuleStoreTestCase):
|
||||
self.assertEqual(set(), beta_testers_result)
|
||||
|
||||
beta_testers = set([UserFactory.create(), UserFactory.create()])
|
||||
[allow_access(self.course, user, 'beta') for user in beta_testers]
|
||||
for user in beta_testers:
|
||||
allow_access(self.course, user, 'beta')
|
||||
beta_testers_result = set(list_with_level(self.course, 'beta'))
|
||||
self.assertEqual(beta_testers, beta_testers_result)
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
|
||||
class TestInstructorAccessForumDB(ModuleStoreTestCase):
|
||||
"""
|
||||
Test forum access control.
|
||||
"""
|
||||
def setUp(self):
|
||||
self.course = CourseFactory.create()
|
||||
|
||||
self.moderators = set([UserFactory.create() for _ in xrange(4)])
|
||||
self.mod_role = Role.objects.create(course_id=self.course.id, name=FORUM_ROLE_MODERATOR)
|
||||
[self.mod_role.users.add(user) for user in self.moderators]
|
||||
for user in self.moderators:
|
||||
self.mod_role.users.add(user)
|
||||
|
||||
def test_update_forum_role_membership_allow_existing_role(self):
|
||||
def test_update_forum_membership_allow_existing_role(self):
|
||||
user = UserFactory.create()
|
||||
update_forum_role_membership(self.course.id, user, FORUM_ROLE_MODERATOR, 'allow')
|
||||
self.assertIn(user, self.mod_role.users.all())
|
||||
|
||||
def test_update_forum_role_membership_allow_existing_role_allowed_user(self):
|
||||
def test_update_forum_membership_allow_existing_role_allowed_user(self):
|
||||
user = UserFactory.create()
|
||||
update_forum_role_membership(self.course.id, user, FORUM_ROLE_MODERATOR, 'allow')
|
||||
update_forum_role_membership(self.course.id, user, FORUM_ROLE_MODERATOR, 'allow')
|
||||
self.assertIn(user, self.mod_role.users.all())
|
||||
|
||||
@raises(Role.DoesNotExist)
|
||||
def test_update_forum_role_membership_allow_not_existing_role(self):
|
||||
def test_update_forum_membership_allow_not_existing_role(self):
|
||||
user = UserFactory.create()
|
||||
update_forum_role_membership(self.course.id, user, FORUM_ROLE_COMMUNITY_TA, 'allow')
|
||||
|
||||
def test_update_forum_role_membership_revoke_existing_role(self):
|
||||
def test_update_forum_membership_revoke_existing_role(self):
|
||||
user = iter(self.moderators).next()
|
||||
update_forum_role_membership(self.course.id, user, FORUM_ROLE_MODERATOR, 'revoke')
|
||||
self.assertNotIn(user, self.mod_role.users.all())
|
||||
|
||||
def test_update_forum_role_membership_revoke_existing_role_revoked_user(self):
|
||||
def test_update_forum_membership_existing_role_revoked_user(self):
|
||||
user = iter(self.moderators).next()
|
||||
update_forum_role_membership(self.course.id, user, FORUM_ROLE_MODERATOR, 'revoke')
|
||||
update_forum_role_membership(self.course.id, user, FORUM_ROLE_MODERATOR, 'revoke')
|
||||
self.assertNotIn(user, self.mod_role.users.all())
|
||||
|
||||
@raises(Role.DoesNotExist)
|
||||
def test_update_forum_role_membership_revoke_not_existing_role(self):
|
||||
def test_update_forum_membership_revoke_not_existing_role(self):
|
||||
user = iter(self.moderators).next()
|
||||
update_forum_role_membership(self.course.id, user, FORUM_ROLE_COMMUNITY_TA, 'revoke')
|
||||
|
||||
@raises(Role.DoesNotExist)
|
||||
def test_update_forum_role_membership_bad_role_allow(self):
|
||||
def test_update_forum_membership_bad_role_allow(self):
|
||||
user = UserFactory.create()
|
||||
update_forum_role_membership(self.course.id, user, 'robot-definitely-not-a-forum-role', 'allow')
|
||||
|
||||
@raises(Role.DoesNotExist)
|
||||
def test_update_forum_role_membership_bad_role_revoke(self):
|
||||
def test_update_forum_membership_bad_role_revoke(self):
|
||||
user = UserFactory.create()
|
||||
update_forum_role_membership(self.course.id, user, 'robot-definitely-not-a-forum-role', 'revoke')
|
||||
|
||||
@raises(ValueError)
|
||||
def test_update_forum_role_membership_bad_mode(self):
|
||||
def test_update_forum_membership_bad_mode(self):
|
||||
user = iter(self.moderators).next()
|
||||
update_forum_role_membership(self.course.id, user, FORUM_ROLE_MODERATOR, 'robot-not-a-mode')
|
||||
|
||||
@@ -3,7 +3,7 @@ Unit tests for instructor.enrollment methods.
|
||||
"""
|
||||
|
||||
import json
|
||||
from django.contrib.auth.models import Group, User
|
||||
from django.contrib.auth.models import User
|
||||
# from courseware.access import _course_staff_group_name
|
||||
from courseware.models import StudentModule
|
||||
from django.test import TestCase
|
||||
@@ -25,13 +25,13 @@ class TestInstructorEnrollmentDB(TestCase):
|
||||
strings.append("Lorem@ipsum.dolor, sit@amet.consectetur\nadipiscing@elit.Aenean\r convallis@at.lacus\r, ut@lacinia.Sed")
|
||||
lists.append(['Lorem@ipsum.dolor', 'sit@amet.consectetur', 'adipiscing@elit.Aenean', 'convallis@at.lacus', 'ut@lacinia.Sed'])
|
||||
|
||||
for (s, l) in zip(strings, lists):
|
||||
self.assertEqual(split_input_list(s), l)
|
||||
for (stng, lst) in zip(strings, lists):
|
||||
self.assertEqual(split_input_list(stng), lst)
|
||||
|
||||
def test_enroll_emails_userexists_alreadyenrolled(self):
|
||||
user = UserFactory()
|
||||
ce = CourseEnrollment(course_id=self.course_id, user=user)
|
||||
ce.save()
|
||||
cenr = CourseEnrollment(course_id=self.course_id, user=user)
|
||||
cenr.save()
|
||||
|
||||
self.assertEqual(CourseEnrollment.objects.filter(course_id=self.course_id, user__email=user.email).count(), 1)
|
||||
|
||||
@@ -49,7 +49,7 @@ class TestInstructorEnrollmentDB(TestCase):
|
||||
self.assertEqual(CourseEnrollment.objects.filter(course_id=self.course_id, user__email=user.email).count(), 1)
|
||||
|
||||
def test_enroll_emails_nouser_alreadyallowed(self):
|
||||
email_without_user = 'test_enroll_emails_nouser_alreadyallowed@test.org'
|
||||
email_without_user = 'robot_enroll_emails_nouser_alreadyallowed@test.org'
|
||||
|
||||
self.assertEqual(User.objects.filter(email=email_without_user).count(), 0)
|
||||
self.assertEqual(CourseEnrollment.objects.filter(course_id=self.course_id, user__email=email_without_user).count(), 0)
|
||||
@@ -65,7 +65,7 @@ class TestInstructorEnrollmentDB(TestCase):
|
||||
self.assertEqual(CourseEnrollmentAllowed.objects.get(course_id=self.course_id, email=email_without_user).auto_enroll, False)
|
||||
|
||||
def test_enroll_emails_nouser_suceedallow(self):
|
||||
email_without_user = 'test_enroll_emails_nouser_suceedallow@test.org'
|
||||
email_without_user = 'robot_enroll_emails_nouser_suceedallow@test.org'
|
||||
|
||||
self.assertEqual(User.objects.filter(email=email_without_user).count(), 0)
|
||||
self.assertEqual(CourseEnrollment.objects.filter(course_id=self.course_id, user__email=email_without_user).count(), 0)
|
||||
@@ -81,9 +81,9 @@ class TestInstructorEnrollmentDB(TestCase):
|
||||
user1 = UserFactory()
|
||||
user2 = UserFactory()
|
||||
user3 = UserFactory()
|
||||
email_without_user1 = 'test_enroll_emails_nouser_suceedallow_1@test.org'
|
||||
email_without_user2 = 'test_enroll_emails_nouser_suceedallow_2@test.org'
|
||||
email_without_user3 = 'test_enroll_emails_nouser_suceedallow_3@test.org'
|
||||
email_without_user1 = 'robot_enroll_emails_nouser_suceedallow_1@test.org'
|
||||
email_without_user2 = 'robot_enroll_emails_nouser_suceedallow_2@test.org'
|
||||
email_without_user3 = 'robot_enroll_emails_nouser_suceedallow_3@test.org'
|
||||
|
||||
def test_db(auto_enroll):
|
||||
for user in [user1, user2, user3]:
|
||||
@@ -101,7 +101,7 @@ class TestInstructorEnrollmentDB(TestCase):
|
||||
test_db(False)
|
||||
|
||||
def test_unenroll_alreadyallowed(self):
|
||||
email_without_user = 'test_unenroll_alreadyallowed@test.org'
|
||||
email_without_user = 'robot_unenroll_alreadyallowed@test.org'
|
||||
cea = CourseEnrollmentAllowed(course_id=self.course_id, email=email_without_user, auto_enroll=False)
|
||||
cea.save()
|
||||
|
||||
@@ -113,8 +113,8 @@ class TestInstructorEnrollmentDB(TestCase):
|
||||
|
||||
def test_unenroll_alreadyenrolled(self):
|
||||
user = UserFactory()
|
||||
ce = CourseEnrollment(course_id=self.course_id, user=user)
|
||||
ce.save()
|
||||
cenr = CourseEnrollment(course_id=self.course_id, user=user)
|
||||
cenr.save()
|
||||
|
||||
unenroll_emails(self.course_id, [user.email])
|
||||
|
||||
@@ -130,7 +130,7 @@ class TestInstructorEnrollmentDB(TestCase):
|
||||
self.assertEqual(CourseEnrollmentAllowed.objects.filter(course_id=self.course_id, email=user.email).count(), 0)
|
||||
|
||||
def test_unenroll_nosuchuser(self):
|
||||
email_without_user = 'test_unenroll_nosuchuser@test.org'
|
||||
email_without_user = 'robot_unenroll_nosuchuser@test.org'
|
||||
|
||||
unenroll_emails(self.course_id, [email_without_user])
|
||||
|
||||
|
||||
@@ -52,7 +52,9 @@ def students_update_enrollment_email(request, course_id):
|
||||
- emails is string containing a list of emails separated by anything split_input_list can handle.
|
||||
- auto_enroll is a boolean (defaults to false)
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'staff', depth=None
|
||||
)
|
||||
|
||||
action = request.GET.get('action')
|
||||
emails = split_input_list(request.GET.get('emails'))
|
||||
@@ -66,11 +68,13 @@ def students_update_enrollment_email(request, course_id):
|
||||
raise ValueError("unrecognized action '{}'".format(action))
|
||||
|
||||
response_payload = {
|
||||
'action': action,
|
||||
'results': results,
|
||||
'action': action,
|
||||
'results': results,
|
||||
'auto_enroll': auto_enroll,
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -87,7 +91,9 @@ def access_allow_revoke(request, course_id):
|
||||
rolename is one of ['instructor', 'staff', 'beta']
|
||||
mode is one of ['allow', 'revoke']
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'instructor', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'instructor', depth=None
|
||||
)
|
||||
|
||||
email = request.GET.get('email')
|
||||
rolename = request.GET.get('rolename')
|
||||
@@ -105,7 +111,9 @@ def access_allow_revoke(request, course_id):
|
||||
response_payload = {
|
||||
'DONE': 'YES',
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -118,7 +126,9 @@ def list_course_role_members(request, course_id):
|
||||
|
||||
rolename is one of ['instructor', 'staff', 'beta']
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'staff', depth=None
|
||||
)
|
||||
|
||||
rolename = request.GET.get('rolename')
|
||||
|
||||
@@ -134,10 +144,14 @@ def list_course_role_members(request, course_id):
|
||||
}
|
||||
|
||||
response_payload = {
|
||||
'course_id': course_id,
|
||||
rolename: map(extract_user_info, access.list_with_level(course, rolename)),
|
||||
'course_id': course_id,
|
||||
rolename: map(extract_user_info, access.list_with_level(
|
||||
course, rolename
|
||||
)),
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -149,14 +163,18 @@ def grading_config(request, course_id):
|
||||
|
||||
TODO maybe this shouldn't be html already
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'staff', depth=None
|
||||
)
|
||||
grading_config_summary = analytics.basic.dump_grading_context(course)
|
||||
|
||||
response_payload = {
|
||||
'course_id': course_id,
|
||||
'grading_config_summary': grading_config_summary,
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -170,7 +188,9 @@ def enrolled_students_profiles(request, course_id, csv=False):
|
||||
|
||||
TODO accept requests for different attribute sets
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'staff', depth=None
|
||||
)
|
||||
|
||||
available_features = analytics.basic.AVAILABLE_FEATURES
|
||||
query_features = ['username', 'name', 'email', 'language', 'location', 'year_of_birth', 'gender',
|
||||
@@ -180,13 +200,15 @@ def enrolled_students_profiles(request, course_id, csv=False):
|
||||
|
||||
if not csv:
|
||||
response_payload = {
|
||||
'course_id': course_id,
|
||||
'students': student_data,
|
||||
'students_count': len(student_data),
|
||||
'queried_features': query_features,
|
||||
'course_id': course_id,
|
||||
'students': student_data,
|
||||
'students_count': len(student_data),
|
||||
'queried_features': query_features,
|
||||
'available_features': available_features,
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
else:
|
||||
formatted = analytics.csvs.format_dictlist(student_data)
|
||||
@@ -213,7 +235,9 @@ def profile_distribution(request, course_id):
|
||||
TODO how should query parameter interpretation work?
|
||||
TODO respond to csv requests as well
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'staff', depth=None
|
||||
)
|
||||
|
||||
try:
|
||||
features = json.loads(request.GET.get('features'))
|
||||
@@ -230,17 +254,19 @@ def profile_distribution(request, course_id):
|
||||
raise e
|
||||
|
||||
response_payload = {
|
||||
'course_id': course_id,
|
||||
'queried_features': features,
|
||||
'course_id': course_id,
|
||||
'queried_features': features,
|
||||
'available_features': analytics.distributions.AVAILABLE_PROFILE_FEATURES,
|
||||
'display_names': {
|
||||
'display_names': {
|
||||
'gender': 'Gender',
|
||||
'level_of_education': 'Level of Education',
|
||||
'year_of_birth': 'Year Of Birth',
|
||||
},
|
||||
'feature_results': feature_results,
|
||||
'feature_results': feature_results,
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -256,7 +282,9 @@ def get_student_progress_url(request, course_id):
|
||||
'progress_url': '/../...'
|
||||
}
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'staff', depth=None
|
||||
)
|
||||
|
||||
student_email = request.GET.get('student_email')
|
||||
if not student_email:
|
||||
@@ -267,10 +295,12 @@ def get_student_progress_url(request, course_id):
|
||||
progress_url = reverse('student_progress', kwargs={'course_id': course_id, 'student_id': user.id})
|
||||
|
||||
response_payload = {
|
||||
'course_id': course_id,
|
||||
'course_id': course_id,
|
||||
'progress_url': progress_url,
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -284,7 +314,9 @@ def redirect_to_student_progress(request, course_id):
|
||||
|
||||
Takes query parameter student_email
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'staff', depth=None
|
||||
)
|
||||
|
||||
student_email = request.GET.get('student_email')
|
||||
if not student_email:
|
||||
@@ -295,10 +327,12 @@ def redirect_to_student_progress(request, course_id):
|
||||
progress_url = reverse('student_progress', kwargs={'course_id': course_id, 'student_id': user.id})
|
||||
|
||||
response_payload = {
|
||||
'course_id': course_id,
|
||||
'course_id': course_id,
|
||||
'progress_url': progress_url,
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -316,7 +350,9 @@ def reset_student_attempts(request, course_id):
|
||||
- all_students is a boolean
|
||||
- delete_module is a boolean
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'staff', depth=None
|
||||
)
|
||||
|
||||
problem_to_reset = request.GET.get('problem_to_reset')
|
||||
student_email = request.GET.get('student_email')
|
||||
@@ -345,7 +381,9 @@ def reset_student_attempts(request, course_id):
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -364,7 +402,9 @@ def rescore_problem(request, course_id):
|
||||
|
||||
all_students will be ignored if student_email is present
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'staff', depth=None
|
||||
)
|
||||
|
||||
problem_to_reset = request.GET.get('problem_to_reset')
|
||||
student_email = request.GET.get('student_email', False)
|
||||
@@ -389,7 +429,9 @@ def rescore_problem(request, course_id):
|
||||
else:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -404,7 +446,9 @@ def list_instructor_tasks(request, course_id):
|
||||
- (optional) problem_urlname (same format as problem_to_reset in other api methods)
|
||||
- (optional) student_email
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'instructor', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'instructor', depth=None
|
||||
)
|
||||
|
||||
problem_urlname = request.GET.get('problem_urlname', False)
|
||||
student_email = request.GET.get('student_email', False)
|
||||
@@ -429,7 +473,9 @@ def list_instructor_tasks(request, course_id):
|
||||
response_payload = {
|
||||
'tasks': map(extract_task_features, tasks),
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -442,7 +488,9 @@ def list_forum_members(request, course_id):
|
||||
|
||||
Takes query parameter rolename
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'staff', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'staff', depth=None
|
||||
)
|
||||
|
||||
rolename = request.GET.get('rolename')
|
||||
|
||||
@@ -465,9 +513,11 @@ def list_forum_members(request, course_id):
|
||||
|
||||
response_payload = {
|
||||
'course_id': course_id,
|
||||
rolename: map(extract_user_info, users),
|
||||
rolename: map(extract_user_info, users),
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@@ -483,7 +533,9 @@ def update_forum_role_membership(request, course_id):
|
||||
rolename is one of [FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA]
|
||||
mode is one of ['allow', 'revoke']
|
||||
"""
|
||||
course = get_course_with_access(request.user, course_id, 'instructor', depth=None)
|
||||
course = get_course_with_access(
|
||||
request.user, course_id, 'instructor', depth=None
|
||||
)
|
||||
|
||||
email = request.GET.get('email')
|
||||
rolename = request.GET.get('rolename')
|
||||
@@ -500,10 +552,12 @@ def update_forum_role_membership(request, course_id):
|
||||
|
||||
response_payload = {
|
||||
'course_id': course_id,
|
||||
'mode': mode,
|
||||
'mode': mode,
|
||||
'DONE': 'YES',
|
||||
}
|
||||
response = HttpResponse(json.dumps(response_payload), content_type="application/json")
|
||||
response = HttpResponse(
|
||||
json.dumps(response_payload), content_type="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
|
||||
@@ -4,12 +4,6 @@ Instructor Dashboard Views
|
||||
TODO add tracking
|
||||
"""
|
||||
|
||||
import csv
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
from django_future.csrf import ensure_csrf_cookie
|
||||
from django.views.decorators.cache import cache_control
|
||||
from mitxmako.shortcuts import render_to_response
|
||||
@@ -17,12 +11,13 @@ from django.core.urlresolvers import reverse
|
||||
from django.utils.html import escape
|
||||
from django.http import Http404
|
||||
|
||||
from django.conf import settings
|
||||
from courseware.access import has_access, get_access_group_name, course_beta_test_group_name
|
||||
from courseware.access import has_access
|
||||
from courseware.courses import get_course_by_id
|
||||
from django_comment_client.utils import has_forum_access
|
||||
from instructor.offline_gradecalc import student_grades, offline_grades_available
|
||||
from django_comment_common.models import Role, FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_MODERATOR, FORUM_ROLE_COMMUNITY_TA
|
||||
from django_comment_common.models import (Role,
|
||||
FORUM_ROLE_ADMINISTRATOR,
|
||||
FORUM_ROLE_MODERATOR,
|
||||
FORUM_ROLE_COMMUNITY_TA)
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from student.models import CourseEnrollment
|
||||
|
||||
@@ -36,9 +31,12 @@ def instructor_dashboard_2(request, course_id):
|
||||
|
||||
access = {
|
||||
'admin': request.user.is_staff,
|
||||
'instructor': has_access(request.user, course, 'instructor'), # an instructor can manage staff lists
|
||||
'staff': has_access(request.user, course, 'staff'),
|
||||
'forum_admin': has_forum_access(request.user, course_id, FORUM_ROLE_ADMINISTRATOR),
|
||||
# an instructor can manage staff lists
|
||||
'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
|
||||
),
|
||||
}
|
||||
|
||||
if not access['staff']:
|
||||
@@ -107,7 +105,7 @@ def _section_membership(course_id, access):
|
||||
'section_key': 'membership',
|
||||
'section_display_name': 'Membership',
|
||||
'access': access,
|
||||
'enroll_button_url': reverse('students_update_enrollment_email', kwargs={'course_id': course_id}),
|
||||
'enroll_button_url': reverse('students_update_enrollment_email', kwargs={'course_id': course_id}),
|
||||
'unenroll_button_url': reverse('students_update_enrollment_email', kwargs={'course_id': course_id}),
|
||||
'list_course_role_members_url': reverse('list_course_role_members', kwargs={'course_id': course_id}),
|
||||
'access_allow_revoke_url': reverse('access_allow_revoke', kwargs={'course_id': course_id}),
|
||||
@@ -136,7 +134,7 @@ def _section_data_download(course_id):
|
||||
section_data = {
|
||||
'section_key': 'data_download',
|
||||
'section_display_name': 'Data Download',
|
||||
'grading_config_url': reverse('grading_config', kwargs={'course_id': course_id}),
|
||||
'grading_config_url': reverse('grading_config', kwargs={'course_id': course_id}),
|
||||
'enrolled_students_profiles_url': reverse('enrolled_students_profiles', kwargs={'course_id': course_id}),
|
||||
}
|
||||
return section_data
|
||||
|
||||
Reference in New Issue
Block a user