Files
edx-platform/common/djangoapps/course_groups/views.py
2014-05-22 12:11:48 -04:00

243 lines
7.4 KiB
Python

from django_future.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_POST
from django.contrib.auth.models import User
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse
from django.http import HttpResponse
import json
import logging
import re
from xmodule.modulestore.locations import SlashSeparatedCourseKey
from courseware.courses import get_course_with_access
from edxmako.shortcuts import render_to_response
from . import cohorts
log = logging.getLogger(__name__)
def json_http_response(data):
"""
Return an HttpResponse with the data json-serialized and the right content
type header.
"""
return HttpResponse(json.dumps(data), content_type="application/json")
def split_by_comma_and_whitespace(s):
"""
Split a string both by commas and whitespice. Returns a list.
"""
return re.split(r'[\s,]+', s)
@ensure_csrf_cookie
def list_cohorts(request, course_key):
"""
Return json dump of dict:
{'success': True,
'cohorts': [{'name': name, 'id': id}, ...]}
"""
# this is a string when we get it here
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key)
get_course_with_access(request.user, 'staff', course_key)
all_cohorts = [{'name': c.name, 'id': c.id}
for c in cohorts.get_course_cohorts(course_key)]
return json_http_response({'success': True,
'cohorts': all_cohorts})
@ensure_csrf_cookie
@require_POST
def add_cohort(request, course_key):
"""
Return json of dict:
{'success': True,
'cohort': {'id': id,
'name': name}}
or
{'success': False,
'msg': error_msg} if there's an error
"""
# this is a string when we get it here
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key)
get_course_with_access(request.user, 'staff', course_key)
name = request.POST.get("name")
if not name:
return json_http_response({'success': False,
'msg': "No name specified"})
try:
cohort = cohorts.add_cohort(course_key, name)
except ValueError as err:
return json_http_response({'success': False,
'msg': str(err)})
return json_http_response({'success': 'True',
'cohort': {
'id': cohort.id,
'name': cohort.name
}})
@ensure_csrf_cookie
def users_in_cohort(request, course_key, cohort_id):
"""
Return users in the cohort. Show up to 100 per page, and page
using the 'page' GET attribute in the call. Format:
Returns:
Json dump of dictionary in the following format:
{'success': True,
'page': page,
'num_pages': paginator.num_pages,
'users': [{'username': ..., 'email': ..., 'name': ...}]
}
"""
# this is a string when we get it here
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key)
get_course_with_access(request.user, 'staff', course_key)
# this will error if called with a non-int cohort_id. That's ok--it
# shoudn't happen for valid clients.
cohort = cohorts.get_cohort_by_id(course_key, int(cohort_id))
paginator = Paginator(cohort.users.all(), 100)
page = request.GET.get('page')
try:
users = paginator.page(page)
except PageNotAnInteger:
# return the first page
page = 1
users = paginator.page(page)
except EmptyPage:
# Page is out of range. Return last page
page = paginator.num_pages
contacts = paginator.page(page)
user_info = [{'username': u.username,
'email': u.email,
'name': '{0} {1}'.format(u.first_name, u.last_name)}
for u in users]
return json_http_response({'success': True,
'page': page,
'num_pages': paginator.num_pages,
'users': user_info})
@ensure_csrf_cookie
@require_POST
def add_users_to_cohort(request, course_key, cohort_id):
"""
Return json dict of:
{'success': True,
'added': [{'username': ...,
'name': ...,
'email': ...}, ...],
'changed': [{'username': ...,
'name': ...,
'email': ...,
'previous_cohort': ...}, ...],
'present': [str1, str2, ...], # already there
'unknown': [str1, str2, ...]}
"""
# this is a string when we get it here
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key)
get_course_with_access(request.user, 'staff', course_key)
cohort = cohorts.get_cohort_by_id(course_key, cohort_id)
users = request.POST.get('users', '')
added = []
changed = []
present = []
unknown = []
for username_or_email in split_by_comma_and_whitespace(users):
if not username_or_email:
continue
try:
(user, previous_cohort) = cohorts.add_user_to_cohort(cohort, username_or_email)
info = {
'username': user.username,
'name': user.profile.name,
'email': user.email,
}
if previous_cohort:
info['previous_cohort'] = previous_cohort
changed.append(info)
else:
added.append(info)
except ValueError:
present.append(username_or_email)
except User.DoesNotExist:
unknown.append(username_or_email)
return json_http_response({'success': True,
'added': added,
'changed': changed,
'present': present,
'unknown': unknown})
@ensure_csrf_cookie
@require_POST
def remove_user_from_cohort(request, course_key, cohort_id):
"""
Expects 'username': username in POST data.
Return json dict of:
{'success': True} or
{'success': False,
'msg': error_msg}
"""
# this is a string when we get it here
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key)
get_course_with_access(request.user, 'staff', course_key)
username = request.POST.get('username')
if username is None:
return json_http_response({'success': False,
'msg': 'No username specified'})
cohort = cohorts.get_cohort_by_id(course_key, cohort_id)
try:
user = User.objects.get(username=username)
cohort.users.remove(user)
return json_http_response({'success': True})
except User.DoesNotExist:
log.debug('no user')
return json_http_response({'success': False,
'msg': "No user '{0}'".format(username)})
def debug_cohort_mgmt(request, course_key):
"""
Debugging view for dev.
"""
# this is a string when we get it here
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_key)
# add staff check to make sure it's safe if it's accidentally deployed.
get_course_with_access(request.user, 'staff', course_key)
context = {'cohorts_ajax_url': reverse(
'cohorts',
kwargs={'course_key': course_key.to_deprecated_string()}
)}
return render_to_response('/course_groups/debug.html', context)