Merge remote-tracking branch 'origin/release/1.0'

Conflicts:
	common/djangoapps/student/views.py
This commit is contained in:
Calen Pennington
2012-07-23 13:55:20 -04:00
262 changed files with 3550 additions and 2243 deletions

View File

@@ -1,10 +1,16 @@
from fs.errors import ResourceNotFoundError
from functools import wraps
import logging
from path import path
from django.conf import settings
from django.http import Http404
from xmodule.course_module import CourseDescriptor
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError
log = logging.getLogger(__name__)
def check_course(course_id, course_must_be_open=True, course_required=True):
"""
@@ -24,10 +30,88 @@ def check_course(course_id, course_must_be_open=True, course_required=True):
try:
course_loc = CourseDescriptor.id_to_location(course_id)
course = modulestore().get_item(course_loc)
except KeyError:
except (KeyError, ItemNotFoundError):
raise Http404("Course not found.")
if course_must_be_open and not course.has_started():
raise Http404("This course has not yet started.")
return course
### These methods look like they should be on the course_module object itself, but they rely
### on the lms. Maybe they should be added dynamically to the class?
def course_static_url(course):
return settings.STATIC_URL + "/" + course.metadata['data_dir'] + "/"
def course_image_url(course):
return course_static_url(course) + "images/course_image.png"
def get_course_about_section(course, section_key):
"""
This returns the snippet of html to be rendered on the course about page, given the key for the section.
Valid keys:
- overview
- title
- university
- number
- short_description
- description
- key_dates (includes start, end, exams, etc)
- video
- course_staff_short
- course_staff_extended
- requirements
- syllabus
- textbook
- faq
- more_info
"""
# Many of these are stored as html files instead of some semantic markup. This can change without effecting
# this interface when we find a good format for defining so many snippets of text/html.
# TODO: Remove number, instructors from this list
if section_key in ['short_description', 'description', 'key_dates', 'video', 'course_staff_short', 'course_staff_extended',
'requirements', 'syllabus', 'textbook', 'faq', 'more_info', 'number', 'instructors', 'overview',
'effort', 'end_date', 'prerequisites']:
try:
with course.system.resources_fs.open(path("about") / section_key + ".html") as htmlFile:
return htmlFile.read().decode('utf-8').format(COURSE_STATIC_URL = course_static_url(course) )
except ResourceNotFoundError:
log.warning("Missing about section {key} in course {url}".format(key=section_key, url=course.location.url()))
return None
elif section_key == "title":
return course.metadata.get('display_name', course.name)
elif section_key == "university":
return course.location.org
elif section_key == "number":
return course.number
raise KeyError("Invalid about key " + str(section_key))
def get_course_info_section(course, section_key):
"""
This returns the snippet of html to be rendered on the course info page, given the key for the section.
Valid keys:
- handouts
- guest_handouts
- updates
- guest_updates
"""
# Many of these are stored as html files instead of some semantic markup. This can change without effecting
# this interface when we find a good format for defining so many snippets of text/html.
if section_key in ['handouts', 'guest_handouts', 'updates', 'guest_updates']:
try:
with course.system.resources_fs.open(path("info") / section_key + ".html") as htmlFile:
return htmlFile.read().decode('utf-8')
except ResourceNotFoundError:
log.exception("Missing info section {key} in course {url}".format(key=section_key, url=course.location.url()))
return "! Info section missing !"
raise KeyError("Invalid about key " + str(section_key))

View File

@@ -1,11 +1,15 @@
from collections import defaultdict
import json
import logging
import urllib
import itertools
from django.conf import settings
from django.core.context_processors import csrf
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.http import Http404, HttpResponse
from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string
#from django.views.decorators.csrf import ensure_csrf_cookie
@@ -18,7 +22,7 @@ from student.models import UserProfile
from multicourse import multicourse_settings
from util.cache import cache, cache_if_anonymous
from student.models import UserTestGroup
from student.models import UserTestGroup, CourseEnrollment
from courseware import grades
from courseware.courses import check_course
from xmodule.modulestore.django import modulestore
@@ -53,8 +57,12 @@ def format_url_params(params):
@cache_if_anonymous
def courses(request):
# TODO: Clean up how 'error' is done.
context = {'courses': modulestore().get_courses()}
return render_to_response("courses.html", context)
courses = sorted(modulestore().get_courses(), key=lambda course: course.number)
universities = defaultdict(list)
for course in courses:
universities[course.org].append(course)
return render_to_response("courses.html", { 'universities': universities })
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
def gradebook(request, course_id):
@@ -249,3 +257,32 @@ def course_info(request, course_id):
course = check_course(course_id)
return render_to_response('info.html', {'course': course})
@ensure_csrf_cookie
@cache_if_anonymous
def course_about(request, course_id):
def registered_for_course(course, user):
if user.is_authenticated():
return CourseEnrollment.objects.filter(user = user, course_id=course.id).exists()
else:
return False
course = check_course(course_id, course_must_be_open=False)
registered = registered_for_course(course, request.user)
return render_to_response('portal/course_about.html', {'course': course, 'registered': registered})
@ensure_csrf_cookie
@cache_if_anonymous
def university_profile(request, org_id):
all_courses = sorted(modulestore().get_courses(), key=lambda course: course.number)
valid_org_ids = set(c.org for c in all_courses)
if org_id not in valid_org_ids:
raise Http404("University Profile not found for {0}".format(org_id))
# Only grab courses for this org...
courses=[c for c in all_courses if c.org == org_id]
context = dict(courses=courses, org_id=org_id)
template_file = "university_profile/{0}.html".format(org_id).lower()
return render_to_response(template_file, context)