Commit 9f84d9b6 by Bridger Maxwell

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

parents 1a8d9996 04b8dbe0
...@@ -23,6 +23,7 @@ from django.core.urlresolvers import reverse ...@@ -23,6 +23,7 @@ from django.core.urlresolvers import reverse
from BeautifulSoup import BeautifulSoup from BeautifulSoup import BeautifulSoup
from django.core.cache import cache from django.core.cache import cache
from courseware.courses import check_course
from django_future.csrf import ensure_csrf_cookie from django_future.csrf import ensure_csrf_cookie
from student.models import Registration, UserProfile, PendingNameChange, PendingEmailChange, CourseEnrollment from student.models import Registration, UserProfile, PendingNameChange, PendingEmailChange, CourseEnrollment
from util.cache import cache_if_anonymous from util.cache import cache_if_anonymous
...@@ -511,10 +512,9 @@ def accept_name_change(request): ...@@ -511,10 +512,9 @@ def accept_name_change(request):
@ensure_csrf_cookie @ensure_csrf_cookie
@cache_if_anonymous @cache_if_anonymous
def course_info(request, course_id): def course_info(request, course_id):
course = check_course(course_id, course_must_be_open=False)
# This is the advertising page for a student to look at the course before signing up # This is the advertising page for a student to look at the course before signing up
csrf_token = csrf(request)['csrf_token'] csrf_token = csrf(request)['csrf_token']
course_loc = CourseDescriptor.id_to_location(course_id)
course = modulestore().get_item(course_loc)
# TODO: Couse should be a model # TODO: Couse should be a model
return render_to_response('portal/course_about.html', {'course': course}) return render_to_response('portal/course_about.html', {'course': course})
...@@ -522,8 +522,10 @@ def course_info(request, course_id): ...@@ -522,8 +522,10 @@ def course_info(request, course_id):
@login_required @login_required
@ensure_csrf_cookie @ensure_csrf_cookie
def enroll(request, course_id): def enroll(request, course_id):
course = check_course(course_id, course_must_be_open=False)
user = request.user user = request.user
enrollment = CourseEnrollment(user=user, enrollment = CourseEnrollment(user=user,
course_id=course_id) course_id=course.id)
enrollment.save() enrollment.save()
return redirect(reverse('dashboard')) return redirect(reverse('dashboard'))
import time
import dateutil.parser
from fs.errors import ResourceNotFoundError from fs.errors import ResourceNotFoundError
import logging import logging
from path import path from path import path
...@@ -13,6 +15,21 @@ log = logging.getLogger(__name__) ...@@ -13,6 +15,21 @@ log = logging.getLogger(__name__)
class CourseDescriptor(SequenceDescriptor): class CourseDescriptor(SequenceDescriptor):
module_class = SequenceModule module_class = SequenceModule
def __init__(self, system, definition=None, **kwargs):
super(CourseDescriptor, self).__init__(system, definition, **kwargs)
try:
self.start = time.strptime(self.metadata["start"], "%Y-%m-%dT%H:%M")
except KeyError:
self.start = time.gmtime(0) #The epoch
log.critical("Course loaded without a start date. " + str(self.id))
except ValueError, e:
self.start = time.gmtime(0) #The epoch
log.critical("Course loaded with a bad start date. " + str(self.id) + " '" + str(e) + "'")
def has_started(self):
return time.gmtime() > self.start
@classmethod @classmethod
def id_to_location(cls, course_id): def id_to_location(cls, course_id):
org, course, name = course_id.split('/') org, course, name = course_id.split('/')
...@@ -25,7 +42,7 @@ class CourseDescriptor(SequenceDescriptor): ...@@ -25,7 +42,7 @@ class CourseDescriptor(SequenceDescriptor):
@property @property
def title(self): def title(self):
return self.metadata['display_name'] return self.metadata['display_name']
@property @property
def number(self): def number(self):
return self.location.course return self.location.course
......
...@@ -214,7 +214,7 @@ class XModuleDescriptor(Plugin): ...@@ -214,7 +214,7 @@ class XModuleDescriptor(Plugin):
# A list of metadata that this module can inherit from its parent module # A list of metadata that this module can inherit from its parent module
inheritable_metadata = ( inheritable_metadata = (
'graded', 'due', 'graceperiod', 'showanswer', 'rerandomize', 'graded', 'start', 'due', 'graceperiod', 'showanswer', 'rerandomize',
# This is used by the XMLModuleStore to provide for locations for static files, # This is used by the XMLModuleStore to provide for locations for static files,
# and will need to be removed when that code is removed # and will need to be removed when that code is removed
...@@ -251,6 +251,7 @@ class XModuleDescriptor(Plugin): ...@@ -251,6 +251,7 @@ class XModuleDescriptor(Plugin):
display_name: The name to use for displaying this module to the user display_name: The name to use for displaying this module to the user
format: The format of this module ('Homework', 'Lab', etc) format: The format of this module ('Homework', 'Lab', etc)
graded (bool): Whether this module is should be graded or not graded (bool): Whether this module is should be graded or not
start (string): The date for which this module will be available
due (string): The due date for this module due (string): The due date for this module
graceperiod (string): The amount of grace period to allow when enforcing the due date graceperiod (string): The amount of grace period to allow when enforcing the due date
showanswer (string): When to show answers for this module showanswer (string): When to show answers for this module
......
...@@ -88,7 +88,7 @@ class XmlDescriptor(XModuleDescriptor): ...@@ -88,7 +88,7 @@ class XmlDescriptor(XModuleDescriptor):
# The attributes will be removed from the definition xml passed # The attributes will be removed from the definition xml passed
# to definition_from_xml, and from the xml returned by definition_to_xml # to definition_from_xml, and from the xml returned by definition_to_xml
metadata_attributes = ('format', 'graceperiod', 'showanswer', 'rerandomize', metadata_attributes = ('format', 'graceperiod', 'showanswer', 'rerandomize',
'due', 'graded', 'name', 'slug') 'start', 'due', 'graded', 'name', 'slug')
# A dictionary mapping xml attribute names to functions of the value # A dictionary mapping xml attribute names to functions of the value
# that return the metadata key and value # that return the metadata key and value
......
from collections import namedtuple from functools import wraps
import logging
import os
from path import path from django.http import Http404
import yaml
log = logging.getLogger('mitx.courseware.courses') from xmodule.course_module import CourseDescriptor
from xmodule.modulestore.django import modulestore
_FIELDS = ['number', # 6.002x
'title', # Circuits and Electronics
'short_title', # Circuits
'run_id', # Spring 2012
'path', # /some/absolute/filepath/6.002x --> course.xml is in here.
'instructors', # ['Anant Agarwal']
'institution', # "MIT"
'wiki_namespace',
'grader', # a courseware.graders.CourseGrader object
#'start', # These should be datetime fields def check_course(course_id, course_must_be_open=True, course_required=True):
#'end'
]
class CourseInfoLoadError(Exception):
pass
class Course(namedtuple('Course', _FIELDS)):
"""Course objects encapsulate general information about a given run of a
course. This includes things like name, grading policy, etc.
""" """
Given a course_id, this returns the course object. By default,
def load_courses(courses_path): if the course is not found or the course is not open yet, this
"""Given a directory of courses, returns a list of Course objects. For the method will raise a 404.
sake of backwards compatibility, if you point it at the top level of a
specific course, it will return a list with one Course object in it. If course_must_be_open is False, the course will be returned
without a 404 even if it is not open.
If course_required is False, a course_id of None is acceptable. The
course returned will be None. Even if the course is not required,
if a course_id is given that does not exist a 404 will be raised.
""" """
courses_path = path(courses_path) course = None
def _is_course_path(p): if course_required or course_id:
return os.path.exists(p / "course_info.yaml") try:
course_loc = CourseDescriptor.id_to_location(course_id)
log.info("Loading courses from {0}".format(courses_path)) course = modulestore().get_item(course_loc)
except KeyError:
# Compatibility: courses_path is the path for a single course raise Http404("Course not found.")
if _is_course_path(courses_path):
log.warning("course_info.yaml found in top-level ({0})" if course_must_be_open and not course.has_started():
.format(courses_path) + raise Http404("This course has not yet started.")
" -- assuming there is only a single course.")
return [Course.load_from_path(courses_path)] return course
# Default: Each dir in courses_path is a separate course
courses = []
log.info("Reading courses from {0}".format(courses_path))
for course_dir_name in os.listdir(courses_path):
course_path = courses_path / course_dir_name
if _is_course_path(course_path):
log.info("Initializing course {0}".format(course_path))
courses.append(Course.load_from_path(course_path))
return courses
def create_lookup_table(courses):
return dict((c.id, c) for c in courses)
...@@ -16,18 +16,17 @@ from module_render import toc_for_course, get_module, get_section ...@@ -16,18 +16,17 @@ from module_render import toc_for_course, get_module, get_section
from models import StudentModuleCache from models import StudentModuleCache
from student.models import UserProfile from student.models import UserProfile
from multicourse import multicourse_settings from multicourse import multicourse_settings
from xmodule.modulestore.django import modulestore
from xmodule.course_module import CourseDescriptor
from util.cache import cache, cache_if_anonymous from util.cache import cache, cache_if_anonymous
from student.models import UserTestGroup from student.models import UserTestGroup
from courseware import grades from courseware import grades
from courseware.courses import check_course
from xmodule.modulestore.django import modulestore
log = logging.getLogger("mitx.courseware") log = logging.getLogger("mitx.courseware")
template_imports = {'urllib': urllib} template_imports = {'urllib': urllib}
def user_groups(user): def user_groups(user):
if not user.is_authenticated(): if not user.is_authenticated():
return [] return []
...@@ -57,20 +56,19 @@ def courses(request): ...@@ -57,20 +56,19 @@ def courses(request):
context = {'courses': modulestore().get_courses()} context = {'courses': modulestore().get_courses()}
return render_to_response("courses.html", context) return render_to_response("courses.html", context)
@cache_control(no_cache=True, no_store=True, must_revalidate=True) @cache_control(no_cache=True, no_store=True, must_revalidate=True)
def gradebook(request, course_id): def gradebook(request, course_id):
if 'course_admin' not in user_groups(request.user): if 'course_admin' not in user_groups(request.user):
raise Http404 raise Http404
course = check_course(course_id)
course_location = CourseDescriptor.id_to_location(course_id)
student_objects = User.objects.all()[:100] student_objects = User.objects.all()[:100]
student_info = [] student_info = []
for student in student_objects: for student in student_objects:
student_module_cache = StudentModuleCache(student, modulestore().get_item(course_location)) student_module_cache = StudentModuleCache(student, course)
course, _, _, _ = get_module(request.user, request, course_location, student_module_cache) course, _, _, _ = get_module(request.user, request, course.location, student_module_cache)
student_info.append({ student_info.append({
'username': student.username, 'username': student.username,
'id': student.id, 'id': student.id,
...@@ -87,8 +85,8 @@ def gradebook(request, course_id): ...@@ -87,8 +85,8 @@ def gradebook(request, course_id):
def profile(request, course_id, student_id=None): def profile(request, course_id, student_id=None):
''' User profile. Show username, location, etc, as well as grades . ''' User profile. Show username, location, etc, as well as grades .
We need to allow the user to change some of these settings .''' We need to allow the user to change some of these settings .'''
course = check_course(course_id)
course_location = CourseDescriptor.id_to_location(course_id)
if student_id is None: if student_id is None:
student = request.user student = request.user
else: else:
...@@ -98,8 +96,8 @@ def profile(request, course_id, student_id=None): ...@@ -98,8 +96,8 @@ def profile(request, course_id, student_id=None):
user_info = UserProfile.objects.get(user=student) user_info = UserProfile.objects.get(user=student)
student_module_cache = StudentModuleCache(request.user, modulestore().get_item(course_location)) student_module_cache = StudentModuleCache(request.user, course)
course, _, _, _ = get_module(request.user, request, course_location, student_module_cache) course, _, _, _ = get_module(request.user, request, course.location, student_module_cache)
context = {'name': user_info.name, context = {'name': user_info.name,
'username': student.username, 'username': student.username,
...@@ -142,7 +140,7 @@ def render_accordion(request, course, chapter, section): ...@@ -142,7 +140,7 @@ def render_accordion(request, course, chapter, section):
@ensure_csrf_cookie @ensure_csrf_cookie
@cache_control(no_cache=True, no_store=True, must_revalidate=True) @cache_control(no_cache=True, no_store=True, must_revalidate=True)
def index(request, course_id=None, chapter=None, section=None, def index(request, course_id, chapter=None, section=None,
position=None): position=None):
''' Displays courseware accordion, and any associated content. ''' Displays courseware accordion, and any associated content.
If course, chapter, and section aren't all specified, just returns If course, chapter, and section aren't all specified, just returns
...@@ -161,6 +159,8 @@ def index(request, course_id=None, chapter=None, section=None, ...@@ -161,6 +159,8 @@ def index(request, course_id=None, chapter=None, section=None,
- HTTPresponse - HTTPresponse
''' '''
course = check_course(course_id)
def clean(s): def clean(s):
''' Fixes URLs -- we convert spaces to _ in URLs to prevent ''' Fixes URLs -- we convert spaces to _ in URLs to prevent
funny encoding characters and keep the URLs readable. This undoes funny encoding characters and keep the URLs readable. This undoes
...@@ -168,9 +168,6 @@ def index(request, course_id=None, chapter=None, section=None, ...@@ -168,9 +168,6 @@ def index(request, course_id=None, chapter=None, section=None,
''' '''
return s.replace('_', ' ') if s is not None else None return s.replace('_', ' ') if s is not None else None
course_location = CourseDescriptor.id_to_location(course_id)
course = modulestore().get_item(course_location)
chapter = clean(chapter) chapter = clean(chapter)
section = clean(section) section = clean(section)
...@@ -249,12 +246,6 @@ def jump_to(request, probname=None): ...@@ -249,12 +246,6 @@ def jump_to(request, probname=None):
@ensure_csrf_cookie @ensure_csrf_cookie
def course_info(request, course_id): def course_info(request, course_id):
csrf_token = csrf(request)['csrf_token'] course = check_course(course_id)
try:
course_location = CourseDescriptor.id_to_location(course_id)
course = modulestore().get_item(course_location)
except KeyError:
raise Http404("Course not found")
return render_to_response('info.html', {'csrf': csrf_token, 'course': course}) return render_to_response('info.html', {'course': course})
...@@ -9,20 +9,12 @@ from django.utils import simplejson ...@@ -9,20 +9,12 @@ from django.utils import simplejson
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from mitxmako.shortcuts import render_to_response from mitxmako.shortcuts import render_to_response
from courseware.courses import check_course
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from models import Revision, Article, Namespace, CreateArticleForm, RevisionFormWithTitle, RevisionForm from models import Revision, Article, Namespace, CreateArticleForm, RevisionFormWithTitle, RevisionForm
import wiki_settings import wiki_settings
def get_course(course_id):
if course_id == None:
return None
course_loc = CourseDescriptor.id_to_location(course_id)
course = modulestore().get_item(course_loc)
# raise Http404("Course not found")
return course
def wiki_reverse(wiki_page, article = None, course = None, namespace=None, args=[], kwargs={}): def wiki_reverse(wiki_page, article = None, course = None, namespace=None, args=[], kwargs={}):
kwargs = dict(kwargs) # TODO: Figure out why if I don't do this kwargs sometimes contains {'article_path'} kwargs = dict(kwargs) # TODO: Figure out why if I don't do this kwargs sometimes contains {'article_path'}
...@@ -55,10 +47,9 @@ def update_template_dictionary(dictionary, request = None, course = None, articl ...@@ -55,10 +47,9 @@ def update_template_dictionary(dictionary, request = None, course = None, articl
if request: if request:
dictionary.update(csrf(request)) dictionary.update(csrf(request))
def view(request, article_path, course_id=None): def view(request, article_path, course_id=None):
course = get_course(course_id) course = check_course(course_id, course_required=False)
(article, err) = get_article(request, article_path, course ) (article, err) = get_article(request, article_path, course )
if err: if err:
return err return err
...@@ -72,7 +63,8 @@ def view(request, article_path, course_id=None): ...@@ -72,7 +63,8 @@ def view(request, article_path, course_id=None):
return render_to_response('simplewiki/simplewiki_view.html', d) return render_to_response('simplewiki/simplewiki_view.html', d)
def view_revision(request, revision_number, article_path, course_id=None): def view_revision(request, revision_number, article_path, course_id=None):
course = get_course(course_id) course = check_course(course_id, course_required=False)
(article, err) = get_article(request, article_path, course ) (article, err) = get_article(request, article_path, course )
if err: if err:
return err return err
...@@ -93,24 +85,26 @@ def view_revision(request, revision_number, article_path, course_id=None): ...@@ -93,24 +85,26 @@ def view_revision(request, revision_number, article_path, course_id=None):
return render_to_response('simplewiki/simplewiki_view.html', d) return render_to_response('simplewiki/simplewiki_view.html', d)
def root_redirect(request, course_id=None): def root_redirect(request, course_id=None):
course = get_course(course_id) course = check_course(course_id, course_required=False)
#TODO: Add a default namespace to settings.
namespace = course.wiki_namespace if course else "edX"
try: try:
root = Article.get_root(course.wiki_namespace) root = Article.get_root(namespace)
return HttpResponseRedirect(reverse('wiki_view', kwargs={'course_id' : course_id, 'article_path' : root.get_path()} ))
except: except:
# If the root is not found, we probably are loading this class for the first time # If the root is not found, we probably are loading this class for the first time
# We should make sure the namespace exists so the root article can be created. # We should make sure the namespace exists so the root article can be created.
Namespace.ensure_namespace(course.wiki_namespace) Namespace.ensure_namespace(namespace)
err = not_found(request, course.wiki_namespace + '/', course) err = not_found(request, namespace + '/', course)
return err return err
return HttpResponseRedirect(reverse('wiki_view', kwargs={'course_id' : course_id, 'article_path' : root.get_path()} ))
def create(request, article_path, course_id=None): def create(request, article_path, course_id=None):
course = get_course(course_id) course = check_course(course_id, course_required=False)
article_path_components = article_path.split('/') article_path_components = article_path.split('/')
# Ensure the namespace exists # Ensure the namespace exists
...@@ -169,7 +163,8 @@ def create(request, article_path, course_id=None): ...@@ -169,7 +163,8 @@ def create(request, article_path, course_id=None):
return render_to_response('simplewiki/simplewiki_edit.html', d) return render_to_response('simplewiki/simplewiki_edit.html', d)
def edit(request, article_path, course_id=None): def edit(request, article_path, course_id=None):
course = get_course(course_id) course = check_course(course_id, course_required=False)
(article, err) = get_article(request, article_path, course ) (article, err) = get_article(request, article_path, course )
if err: if err:
return err return err
...@@ -215,7 +210,8 @@ def edit(request, article_path, course_id=None): ...@@ -215,7 +210,8 @@ def edit(request, article_path, course_id=None):
return render_to_response('simplewiki/simplewiki_edit.html', d) return render_to_response('simplewiki/simplewiki_edit.html', d)
def history(request, article_path, page=1, course_id=None): def history(request, article_path, page=1, course_id=None):
course = get_course(course_id) course = check_course(course_id, course_required=False)
(article, err) = get_article(request, article_path, course ) (article, err) = get_article(request, article_path, course )
if err: if err:
return err return err
...@@ -295,9 +291,8 @@ def history(request, article_path, page=1, course_id=None): ...@@ -295,9 +291,8 @@ def history(request, article_path, page=1, course_id=None):
return render_to_response('simplewiki/simplewiki_history.html', d) return render_to_response('simplewiki/simplewiki_history.html', d)
def revision_feed(request, page=1, namespace=None, course_id=None): def revision_feed(request, page=1, namespace=None, course_id=None):
course = get_course(course_id) course = check_course(course_id, course_required=False)
page_size = 10 page_size = 10
...@@ -329,6 +324,8 @@ def revision_feed(request, page=1, namespace=None, course_id=None): ...@@ -329,6 +324,8 @@ def revision_feed(request, page=1, namespace=None, course_id=None):
return render_to_response('simplewiki/simplewiki_revision_feed.html', d) return render_to_response('simplewiki/simplewiki_revision_feed.html', d)
def search_articles(request, namespace=None, course_id = None): def search_articles(request, namespace=None, course_id = None):
course = check_course(course_id, course_required=False)
# blampe: We should check for the presence of other popular django search # blampe: We should check for the presence of other popular django search
# apps and use those if possible. Only fall back on this as a last resort. # apps and use those if possible. Only fall back on this as a last resort.
# Adding some context to results (eg where matches were) would also be nice. # Adding some context to results (eg where matches were) would also be nice.
...@@ -339,9 +336,7 @@ def search_articles(request, namespace=None, course_id = None): ...@@ -339,9 +336,7 @@ def search_articles(request, namespace=None, course_id = None):
querystring = request.GET.get('value', '').strip() querystring = request.GET.get('value', '').strip()
else: else:
querystring = "" querystring = ""
course = get_course(course_id)
results = Article.objects.all() results = Article.objects.all()
if namespace: if namespace:
results = results.filter(namespace__name__exact = namespace) results = results.filter(namespace__name__exact = namespace)
...@@ -377,8 +372,9 @@ def search_articles(request, namespace=None, course_id = None): ...@@ -377,8 +372,9 @@ def search_articles(request, namespace=None, course_id = None):
update_template_dictionary(d, request, course) update_template_dictionary(d, request, course)
return render_to_response('simplewiki/simplewiki_searchresults.html', d) return render_to_response('simplewiki/simplewiki_searchresults.html', d)
def search_add_related(request, course_id, slug, namespace): def search_add_related(request, course_id, slug, namespace):
course = check_course(course_id, course_required=False)
(article, err) = get_article(request, slug, namespace if namespace else course_id ) (article, err) = get_article(request, slug, namespace if namespace else course_id )
if err: if err:
return err return err
...@@ -409,6 +405,8 @@ def search_add_related(request, course_id, slug, namespace): ...@@ -409,6 +405,8 @@ def search_add_related(request, course_id, slug, namespace):
return HttpResponse(json, mimetype='application/json') return HttpResponse(json, mimetype='application/json')
def add_related(request, course_id, slug, namespace): def add_related(request, course_id, slug, namespace):
course = check_course(course_id, course_required=False)
(article, err) = get_article(request, slug, namespace if namespace else course_id ) (article, err) = get_article(request, slug, namespace if namespace else course_id )
if err: if err:
return err return err
...@@ -430,6 +428,8 @@ def add_related(request, course_id, slug, namespace): ...@@ -430,6 +428,8 @@ def add_related(request, course_id, slug, namespace):
return HttpResponseRedirect(reverse('wiki_view', args=(article.get_url(),))) return HttpResponseRedirect(reverse('wiki_view', args=(article.get_url(),)))
def remove_related(request, course_id, namespace, slug, related_id): def remove_related(request, course_id, namespace, slug, related_id):
course = check_course(course_id, course_required=False)
(article, err) = get_article(request, slug, namespace if namespace else course_id ) (article, err) = get_article(request, slug, namespace if namespace else course_id )
if err: if err:
...@@ -449,8 +449,9 @@ def remove_related(request, course_id, namespace, slug, related_id): ...@@ -449,8 +449,9 @@ def remove_related(request, course_id, namespace, slug, related_id):
finally: finally:
return HttpResponseRedirect(reverse('wiki_view', args=(article.get_url(),))) return HttpResponseRedirect(reverse('wiki_view', args=(article.get_url(),)))
def random_article(request, course_id): def random_article(request, course_id=None):
course = get_course(course_id) course = check_course(course_id, course_required=False)
from random import randint from random import randint
num_arts = Article.objects.count() num_arts = Article.objects.count()
article = Article.objects.all()[randint(0, num_arts-1)] article = Article.objects.all()[randint(0, num_arts-1)]
......
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from mitxmako.shortcuts import render_to_response from mitxmako.shortcuts import render_to_response
from xmodule.modulestore.django import modulestore
from xmodule.course_module import CourseDescriptor from courseware.courses import check_course
@login_required @login_required
def index(request, course_id=None, page=0): def index(request, course_id, page=0):
course_location = CourseDescriptor.id_to_location(course_id) course = check_course(course_id)
course = modulestore().get_item(course_location)
return render_to_response('staticbook.html',{'page':int(page), 'course': course}) return render_to_response('staticbook.html',{'page':int(page), 'course': course})
def index_shifted(request, page): def index_shifted(request, course_id, page):
return index(request, int(page)+24) return index(request, course_id=course_id, page=int(page)+24)
...@@ -126,6 +126,8 @@ COURSE_TITLE = "Circuits and Electronics" ...@@ -126,6 +126,8 @@ COURSE_TITLE = "Circuits and Electronics"
ENABLE_MULTICOURSE = False # set to False to disable multicourse display (see lib.util.views.mitxhome) ENABLE_MULTICOURSE = False # set to False to disable multicourse display (see lib.util.views.mitxhome)
QUICKEDIT = False QUICKEDIT = False
WIKI_ENABLED = False
### ###
COURSE_DEFAULT = '6.002x_Fall_2012' COURSE_DEFAULT = '6.002x_Fall_2012'
......
...@@ -13,6 +13,8 @@ from .logsettings import get_logger_config ...@@ -13,6 +13,8 @@ from .logsettings import get_logger_config
DEBUG = True DEBUG = True
TEMPLATE_DEBUG = True TEMPLATE_DEBUG = True
WIKI_ENABLED = True
LOGGING = get_logger_config(ENV_ROOT / "log", LOGGING = get_logger_config(ENV_ROOT / "log",
logging_env="dev", logging_env="dev",
tracking_filename="tracking.log", tracking_filename="tracking.log",
......
...@@ -15,6 +15,8 @@ Dir structure: ...@@ -15,6 +15,8 @@ Dir structure:
""" """
from .dev import * from .dev import *
WIKI_ENABLED = True
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.mysql', 'ENGINE': 'django.db.backends.mysql',
...@@ -42,3 +44,26 @@ CACHES = { ...@@ -42,3 +44,26 @@ CACHES = {
} }
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
################################ DEBUG TOOLBAR #################################
INSTALLED_APPS += ('debug_toolbar',)
MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
INTERNAL_IPS = ('127.0.0.1',)
DEBUG_TOOLBAR_PANELS = (
'debug_toolbar.panels.version.VersionDebugPanel',
'debug_toolbar.panels.timer.TimerDebugPanel',
'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
'debug_toolbar.panels.headers.HeaderDebugPanel',
'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
'debug_toolbar.panels.sql.SQLDebugPanel',
'debug_toolbar.panels.signals.SignalDebugPanel',
'debug_toolbar.panels.logger.LoggingPanel',
# Enabling the profiler has a weird bug as of django-debug-toolbar==0.9.4 and
# Django=1.3.1/1.4 where requests to views get duplicated (your method gets
# hit twice). So you can uncomment when you need to diagnose performance
# problems, but you shouldn't leave it on.
# 'debug_toolbar.panels.profiling.ProfilingDebugPanel',
)
...@@ -98,9 +98,6 @@ if settings.COURSEWARE_ENABLED: ...@@ -98,9 +98,6 @@ if settings.COURSEWARE_ENABLED:
url(r'^xqueue/(?P<username>[^/]*)/(?P<id>.*?)/(?P<dispatch>[^/]*)$', 'courseware.module_render.xqueue_callback'), url(r'^xqueue/(?P<username>[^/]*)/(?P<id>.*?)/(?P<dispatch>[^/]*)$', 'courseware.module_render.xqueue_callback'),
url(r'^change_setting$', 'student.views.change_setting'), url(r'^change_setting$', 'student.views.change_setting'),
url(r'^s/(?P<template>[^/]*)$', 'static_template_view.views.auth_index'), url(r'^s/(?P<template>[^/]*)$', 'static_template_view.views.auth_index'),
url(r'^book/(?P<page>[^/]*)$', 'staticbook.views.index'),
url(r'^book-shifted/(?P<page>[^/]*)$', 'staticbook.views.index_shifted'),
url(r'^book*$', 'staticbook.views.index'),
# url(r'^course_info/$', 'student.views.courseinfo'), # url(r'^course_info/$', 'student.views.courseinfo'),
# url(r'^show_circuit/(?P<circuit>[^/]*)$', 'circuit.views.show_circuit'), # url(r'^show_circuit/(?P<circuit>[^/]*)$', 'circuit.views.show_circuit'),
url(r'^edit_circuit/(?P<circuit>[^/]*)$', 'circuit.views.edit_circuit'), url(r'^edit_circuit/(?P<circuit>[^/]*)$', 'circuit.views.edit_circuit'),
...@@ -109,29 +106,34 @@ if settings.COURSEWARE_ENABLED: ...@@ -109,29 +106,34 @@ if settings.COURSEWARE_ENABLED:
url(r'^heartbeat$', include('heartbeat.urls')), url(r'^heartbeat$', include('heartbeat.urls')),
# Multicourse related: # Multicourse related:
url(r'^courses/?$', 'courseware.views.courses', name="courses"), url(r'^courses/?$', 'courseware.views.courses', name="courses"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/info$', #About the course
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/about$',
'student.views.course_info', name="about_course"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/enroll$',
'student.views.enroll', name="enroll"),
#Inside the course
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/info$',
'courseware.views.course_info', name="info"), 'courseware.views.course_info', name="info"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book$',
'staticbook.views.index', name="book"), 'staticbook.views.index', name="book"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/enroll$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book/(?P<page>[^/]*)$',
'student.views.enroll', name="enroll"), 'staticbook.views.index'),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/?$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book-shifted/(?P<page>[^/]*)$',
'staticbook.views.index_shifted'),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/?$',
'courseware.views.index', name="courseware"), 'courseware.views.index', name="courseware"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/(?P<chapter>[^/]*)/(?P<section>[^/]*)/$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/(?P<chapter>[^/]*)/(?P<section>[^/]*)/$',
'courseware.views.index', name="courseware_section"), 'courseware.views.index', name="courseware_section"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/profile$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/profile$',
'courseware.views.profile', name="profile"), 'courseware.views.profile', name="profile"),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/profile/(?P<student_id>[^/]*)/$', url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/profile/(?P<student_id>[^/]*)/$',
'courseware.views.profile'), 'courseware.views.profile'),
# TODO (vshnayder): there is no student.views.course_info.
# Where should this point instead? same as the info view?
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)$',
'student.views.course_info', name="about_course"),
) )
# Multicourse wiki # Multicourse wiki
if settings.WIKI_ENABLED:
urlpatterns += ( urlpatterns += (
url(r'^wiki/', include('simplewiki.urls')), url(r'^wiki/', include('simplewiki.urls')),
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/wiki/', include('simplewiki.urls')), url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/wiki/', include('simplewiki.urls')),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment