Commit eb95ea9e by Lyla Fischer

Merge branch 'master' into MC

parents 13a095fc 6ebb521d
......@@ -106,8 +106,9 @@ def grade_histogram(module_id):
cursor.execute("select courseware_studentmodule.grade,COUNT(courseware_studentmodule.student_id) from courseware_studentmodule where courseware_studentmodule.module_id=%s group by courseware_studentmodule.grade", [module_id])
grades = list(cursor.fetchall())
print grades
grades.sort(key=lambda x:x[0]) # Probably not necessary
if (len(grades) == 1 and grades[0][0] == None):
return []
return grades
def render_x_module(user, request, xml_module, module_object_preload):
......@@ -147,12 +148,21 @@ def render_x_module(user, request, xml_module, module_object_preload):
module_object_preload.append(smod)
# Grab content
content = instance.get_html()
init_js = instance.get_init_js()
destory_js = instance.get_destroy_js()
if user.is_staff:
histogram = grade_histogram(module_id)
render_histogram = len(histogram) > 0
content=content+render_to_string("staff_problem_info.html", {'xml':etree.tostring(xml_module),
'histogram':grade_histogram(module_id)})
'module_id' : module_id,
'render_histogram' : render_histogram})
if render_histogram:
init_js = init_js+render_to_string("staff_problem_histogram.js", {'histogram' : histogram,
'module_id' : module_id})
content = {'content':content,
"destroy_js":instance.get_destroy_js(),
'init_js':instance.get_init_js(),
"destroy_js":destory_js,
'init_js':init_js,
'type':module_type}
return content
......
......@@ -42,7 +42,8 @@ class Module(XModule):
return render_to_string('video.html',{'streams':self.video_list(),
'id':self.item_id,
'position':self.position,
'name':self.name})
'name':self.name,
'annotations':self.annotations})
def get_init_js(self):
'''JavaScript code to be run when problem is shown. Be aware
......@@ -52,19 +53,23 @@ class Module(XModule):
log.debug(u"INIT POSITION {0}".format(self.position))
return render_to_string('video_init.js',{'streams':self.video_list(),
'id':self.item_id,
'position':self.position})
'position':self.position})+self.annotations_init
def get_destroy_js(self):
return "videoDestroy(\"{0}\");".format(self.item_id)
return "videoDestroy(\"{0}\");".format(self.item_id)+self.annotations_destroy
def __init__(self, xml, item_id, ajax_url=None, track_url=None, state=None, track_function=None, render_function = None):
XModule.__init__(self, xml, item_id, ajax_url, track_url, state, track_function, render_function)
self.youtube = etree.XML(xml).get('youtube')
self.name = etree.XML(xml).get('name')
xmltree=etree.fromstring(xml)
self.youtube = xmltree.get('youtube')
self.name = xmltree.get('name')
self.position = 0
if state != None:
state = json.loads(state)
if 'position' in state:
self.position = int(float(state['position']))
#log.debug("POSITION IN STATE")
#log.debug(u"LOAD POSITION {0}".format(self.position))
self.annotations=[(e.get("name"),self.render_function(e)) \
for e in xmltree]
self.annotations_init="".join([e[1]['init_js'] for e in self.annotations if 'init_js' in e[1]])
self.annotations_destroy="".join([e[1]['destroy_js'] for e in self.annotations if 'destroy_js' in e[1]])
......@@ -13,7 +13,7 @@ from django.contrib.auth.models import User
from django.core.context_processors import csrf
from django.core.mail import send_mail
from django.core.validators import validate_email, validate_slug, ValidationError
from django.db import connection
from django.db import IntegrityError
from django.http import HttpResponse, Http404
from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string
......@@ -162,15 +162,6 @@ def create_account(request, post_override=None):
# Confirm username and e-mail are unique. TODO: This should be in a transaction
if len(User.objects.filter(username=post_vars['username']))>0:
js['value']="An account with this username already exists."
return HttpResponse(json.dumps(js))
if len(User.objects.filter(email=post_vars['email']))>0:
js['value']="An account with this e-mail already exists."
return HttpResponse(json.dumps(js))
u=User(username=post_vars['username'],
email=post_vars['email'],
is_active=False)
......@@ -178,7 +169,20 @@ def create_account(request, post_override=None):
r=Registration()
# TODO: Rearrange so that if part of the process fails, the whole process fails.
# Right now, we can have e.g. no registration e-mail sent out and a zombie account
u.save()
try:
u.save()
except IntegrityError:
# Figure out the cause of the integrity error
if len(User.objects.filter(username=post_vars['username']))>0:
js['value']="An account with this username already exists."
return HttpResponse(json.dumps(js))
if len(User.objects.filter(email=post_vars['email']))>0:
js['value']="An account with this e-mail already exists."
return HttpResponse(json.dumps(js))
raise
r.register(u)
up = UserProfile(user=u)
......
......@@ -24,7 +24,6 @@ with open(ENV_ROOT / "env.json") as env_file:
ENV_TOKENS = json.load(env_file)
SITE_NAME = ENV_TOKENS['SITE_NAME']
CSRF_COOKIE_DOMAIN = ENV_TOKENS['CSRF_COOKIE_DOMAIN']
BOOK_URL = ENV_TOKENS['BOOK_URL']
MEDIA_URL = ENV_TOKENS['MEDIA_URL']
......@@ -47,4 +46,4 @@ SECRET_KEY = AUTH_TOKENS['SECRET_KEY']
AWS_ACCESS_KEY_ID = AUTH_TOKENS["AWS_ACCESS_KEY_ID"]
AWS_SECRET_ACCESS_KEY = AUTH_TOKENS["AWS_SECRET_ACCESS_KEY"]
DATABASES = AUTH_TOKENS['DATABASES']
\ No newline at end of file
DATABASES = AUTH_TOKENS['DATABASES']
......@@ -114,7 +114,6 @@ TEMPLATE_DEBUG = False
# Site info
SITE_ID = 1
SITE_NAME = "localhost:8000"
CSRF_COOKIE_DOMAIN = '127.0.0.1'
HTTPS = 'on'
ROOT_URLCONF = 'mitx.urls'
IGNORABLE_404_ENDS = ('favicon.ico')
......@@ -135,13 +134,13 @@ STATIC_ROOT = ENV_ROOT / "staticfiles" # We don't run collectstatic -- this is t
# FIXME: We should iterate through the courses we have, adding the static
# contents for each of them. (Right now we just use symlinks.)
STATICFILES_DIRS = (
STATICFILES_DIRS = [
PROJECT_ROOT / "static",
ASKBOT_ROOT / "askbot" / "skins",
# This is how you would use the textbook images locally
# ("book", ENV_ROOT / "book_images")
)
]
# Locale/Internationalization
TIME_ZONE = 'America/New_York' # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
......
......@@ -73,7 +73,8 @@ DEBUG_TOOLBAR_PANELS = (
############################ FILE UPLOADS (ASKBOT) #############################
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
MEDIA_ROOT = ENV_ROOT / "uploads"
MEDIA_URL = "/discussion/upfiles/"
MEDIA_URL = "/static/uploads/"
STATICFILES_DIRS.append(("uploads", MEDIA_ROOT))
FILE_UPLOAD_TEMP_DIR = ENV_ROOT / "uploads"
FILE_UPLOAD_HANDLERS = (
'django.core.files.uploadhandler.MemoryFileUploadHandler',
......
"""
This config file runs the simplest dev environment using sqlite, and db-based
sessions. Assumes structure:
/envroot/
/db # This is where it'll write the database file
/mitx # The location of this repo
/log # Where we're going to write log files
"""
from common import *
STATIC_GRAB = True
LOGGING = logsettings.get_logger_config(ENV_ROOT / "log",
logging_env="dev",
tracking_filename="tracking.log",
debug=False)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ENV_ROOT / "db" / "mitx.db",
}
}
CACHES = {
# This is the cache used for most things. Askbot will not work without a
# functioning cache -- it relies on caching to load its settings in places.
# In staging/prod envs, the sessions also live here.
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'mitx_loc_mem_cache'
},
# The general cache is what you get if you use our util.cache. It's used for
# things like caching the course.xml file for different A/B test groups.
# We set it to be a DummyCache to force reloading of course.xml in dev.
# In staging environments, we would grab VERSION from data uploaded by the
# push process.
'general': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
'KEY_PREFIX': 'general',
'VERSION': 4,
}
}
# Dummy secret key for dev
SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
############################ FILE UPLOADS (ASKBOT) #############################
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
MEDIA_ROOT = ENV_ROOT / "uploads"
MEDIA_URL = "/discussion/upfiles/"
FILE_UPLOAD_TEMP_DIR = ENV_ROOT / "uploads"
FILE_UPLOAD_HANDLERS = (
'django.core.files.uploadhandler.MemoryFileUploadHandler',
'django.core.files.uploadhandler.TemporaryFileUploadHandler',
)
......@@ -28,7 +28,6 @@ sys.path.append(BASE_DIR + "/mitx/lib")
COURSEWARE_ENABLED = True
ASKBOT_ENABLED = True
CSRF_COOKIE_DOMAIN = '127.0.0.1'
# Defaults to be overridden
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
......@@ -116,6 +115,7 @@ MIDDLEWARE_CLASSES = (
'django.middleware.csrf.CsrfViewMiddleware',
#'django.contrib.auth.middleware.AuthenticationMiddleware',
'cache_toolbox.middleware.CacheBackedAuthenticationMiddleware',
'masquerade.middleware.MasqueradeMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'track.middleware.TrackMiddleware',
'mitxmako.middleware.MakoMiddleware',
......@@ -146,6 +146,7 @@ INSTALLED_APPS = (
'circuit',
'perfstats',
'util',
'masquerade',
# Uncomment the next line to enable the admin:
# 'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
......
......@@ -734,10 +734,12 @@ li.calc-main {
-ms-transition-delay: 0;
-o-transition-delay: 0;
transition-delay: 0;
z-index: 9999;
z-index: 99;
-webkit-appearance: none; }
li.calc-main.open {
bottom: -36px; }
li.calc-main.open div#calculator_wrapper form div.input-wrapper div.help-wrapper dl {
display: block; }
li.calc-main a.calc {
text-indent: -9999px;
overflow: hidden;
......@@ -869,6 +871,7 @@ li.calc-main div#calculator_wrapper form div.input-wrapper div.help-wrapper dl {
right: -40px;
top: -110px;
width: 500px;
display: none;
-webkit-transition-property: all;
-moz-transition-property: all;
-ms-transition-property: all;
......@@ -3751,27 +3754,30 @@ nav.sequence-nav ul li.next a {
nav.sequence-nav ul li.next a:hover {
background-color: none; }
section.course-content div#seq_content {
margin-bottom: 60px; }
section.course-content nav.sequence-bottom {
bottom: -22.652px;
section.course-content {
position: relative; }
section.course-content nav.sequence-bottom {
margin: 45.304px 0 0;
text-align: center; }
section.course-content nav.sequence-bottom ul {
background-color: #f2e7bf;
background-color: #f2e7bf;
border: 1px solid #e4d080;
border-bottom: 0;
-webkit-border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
-ms-border-radius: 3px 3px 0 0;
-o-border-radius: 3px 3px 0 0;
border-radius: 3px 3px 0 0;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: inset 0 0 0 1px #faf7e9;
-moz-box-shadow: inset 0 0 0 1px #faf7e9;
box-shadow: inset 0 0 0 1px #faf7e9;
margin: 0 auto;
overflow: hidden;
width: 106px; }
display: -moz-inline-box;
-moz-box-orient: vertical;
display: inline-block;
vertical-align: baseline;
zoom: 1;
*display: inline;
*vertical-align: auto; }
section.course-content nav.sequence-bottom ul li {
float: left; }
section.course-content nav.sequence-bottom ul li.prev, section.course-content nav.sequence-bottom ul li.next {
......@@ -3781,8 +3787,7 @@ section.course-content nav.sequence-bottom ul li.prev a, section.course-content
background-repeat: no-repeat;
border-bottom: none;
display: block;
display: block;
padding: 16.989px 4px;
padding: 11.326px 4px;
text-indent: -9999px;
-webkit-transition-property: all;
-moz-transition-property: all;
......@@ -3808,14 +3813,14 @@ section.course-content nav.sequence-bottom ul li.prev a, section.course-content
section.course-content nav.sequence-bottom ul li.prev a:hover, section.course-content nav.sequence-bottom ul li.next a:hover {
background-color: #eddfaa;
color: #7e691a;
color: #7e691a;
opacity: .5;
text-decoration: none; }
section.course-content nav.sequence-bottom ul li.prev a.disabled, section.course-content nav.sequence-bottom ul li.next a.disabled {
background-color: #fffffe;
opacity: .4; }
section.course-content nav.sequence-bottom ul li.prev a {
background-image: url("/static/images/sequence-nav/previous-icon.png"); }
background-image: url("/static/images/sequence-nav/previous-icon.png");
border-right: 1px solid #e4d080; }
section.course-content nav.sequence-bottom ul li.prev a:hover {
background-color: none; }
section.course-content nav.sequence-bottom ul li.next a {
......
/* line 1, sass/marketing-ie.scss */
body {
margin: 0;
padding: 0; }
/* line 6, sass/marketing-ie.scss */
.wrapper, .subpage, section.copyright, section.tos, section.privacy-policy, section.honor-code, header.announcement div, section.index-content, footer {
margin: 0;
overflow: hidden; }
/* line 12, sass/marketing-ie.scss */
div#enroll form {
display: none; }
......@@ -7,21 +7,12 @@
<ul>
% for section in chapter['sections']:
<li
% if 'active' in section and section['active']:
class="active"
% endif
>
<li${' class="active"' if 'active' in section and section['active'] else ''}>
<a href="${reverse('courseware_section', args=format_url_params([course_name, chapter['name'], section['name']]))}">
<p>${section['name']}</p>
<p class="subtitle">
${section['format']}
% if 'due' in section and section['due']!="":
due ${section['due']}
% endif
${section['format']} ${"due " + section['due'] if 'due' in section and section['due'] != '' else ''}
</p>
</a>
% endfor
......
......@@ -2,7 +2,12 @@
<%block name="bodyclass">courseware</%block>
<%block name="title"><title>Courseware – MITx 6.002x</title></%block>
<%block name="headextra">
<script type="text/javascript" src="/static/js/flot/jquery.flot.js"></script>
</%block>
<%block name="js_extra">
##Is there a reason this isn't in header_extra? Is it important that the javascript is at the bottom of the generated document?
<!-- TODO: http://docs.jquery.com/Plugins/Validation -->
<script type="text/javascript">
$(function() {
......
......@@ -6,9 +6,7 @@
<p class="ie-warning"> Enrollment requires a modern web browser with JavaScript enabled. You don't have this. You can&rsquo;t enroll without upgrading, since you couldn&rsquo;t take the course without upgrading. Feel free to download the latest version of <a href="http://www.mozilla.org/en-US/firefox/new/">Mozilla Firefox</a> or <a href="http://support.google.com/chrome/bin/answer.py?hl=en&answer=95346">Google Chrome</a>, for free, to enroll and take this course.</p>
<![endif]-->
<p class="disclaimer">
Please note that 6.002x has already started.
Several assignment due dates for 6.002x have already passed. It is now impossible for newly enrolled students to get 100% of the points in the course, although new students can still earn points for assignments whose due dates have not passed, and students have access to all of the course material that has been released for the course.
</p>
Please note that 6.002x has now passed its half-way point. The midterm exam and several assignment due dates for 6.002x have already passed. It is now impossible for newly enrolled students to earn a passing grade and a completion certificate for the course. However, new students have access to all of the course material that has been released for the course, so you are welcome to enroll and browse the course. </p>
<form name="enroll" id="enroll_form" method="get">
<fieldset><% if 'error' in locals(): e = error %>
......
MITx's prototype offering, 6.002x, is now open. To log in, visit
MITx's prototype offering, 6.002x, is open. To log in, visit
% if is_secure:
https://6002x.mitx.mit.edu
......@@ -16,7 +16,7 @@ place to reset it.
Once you log in, we recommend that you start the course by reviewing
the "System Usage Sequence" in the Overview section, and the "6.002x
At-a-Glance (Calendar)" handout under the Course Info tab. After you
familiarize yourself with the various features of the MITx platform,
familiarize yourself with the features of the MITx platform,
you can jump right into the coursework by working on "Administrivia
and Circuit Elements", the first Lecture Sequence in Week 1.
......
......@@ -11,7 +11,7 @@
<h2>6.002x</h2>
<a class="enroll" rel="leanModal" href="#enroll"><noscript>In order to</noscript> Enroll in 6.002x Circuits <span>&amp;</span> Electronics <noscript>you need to have javascript enabled</noscript></a>
</section>
<p>6.002x (Circuits and Electronics) is an experimental on-line adaptation of MIT&rsquo;s first undergraduate analog design course: 6.002. This course will run, free of charge, for students worldwide from March 5, 2012 through June 8, 2012.</p>
<p>6.002x (Circuits and Electronics) is an experimental on-line adaptation of MIT&rsquo;s first undergraduate analog design course: 6.002. This course is running, free of charge, for students worldwide from March 5, 2012 through June 8, 2012.</p>
</section>
</%block>
......
......@@ -4,7 +4,7 @@
<%block name="title"><title>MITx 6.002x</title></%block>
<link rel="stylesheet" href="${ settings.LIB_URL }jquery.treeview.css" type="text/css" media="all" />
<link rel="stylesheet" href="/static/css/application.css?v2" type="text/css" media="all" />
<link rel="stylesheet" href="/static/css/application.css?v3" type="text/css" media="all" />
<script type="text/javascript" src="${ settings.LIB_URL }jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="${ settings.LIB_URL }jquery-ui-1.8.16.custom.min.js"></script>
......
......@@ -8,7 +8,7 @@
<section class="intro">
<section class="intro-text">
<p><em>MITx</em> will offer a portfolio of MIT courses for free to a virtual community of learners around the world. It will also enhance the educational experience of its on-campus students, offering them online tools that supplement and enrich their classroom and laboratory experiences.</p>
<p>The first <em>MITx</em> course, 6.002x (Circuits and Electronics), will be launched in an experimental prototype form. Watch this space for further upcoming courses, which will become available in Fall 2012.</p>
<p>The first <em>MITx</em> course, 6.002x (Circuits and Electronics), was launched in an experimental prototype form. Watch this space for further upcoming courses, which will become available in Fall 2012.</p>
</section>
<section class="intro-video">
......@@ -33,17 +33,29 @@
</section>
<section class="course">
<hgroup>
<h1>Spring 2012 Course offering</h1>
<h2>Circuits and Electronics</h2>
<h3>6.002x</h3>
</hgroup>
<div class="announcement">
<h1> Announcement </h1>
<img src="/static/images/marketing/edx-logo.png" alt="" />
<p>
On May 2, it was announced that Harvard University will join MIT as a partner in edX. MITx, which offers online versions of MIT courses, will be a core offering of edX, as will Harvardx, a set of course offerings from Harvard.
</p>
<p class="announcement-button">
<a href="http://edxonline.org">Read more details here <span class="arrow">&#8227;</span></a>
</p>
</div>
<hgroup>
<h1>Spring 2012 Course offering</h1>
<h2>Circuits and Electronics</h2>
<h3>6.002x</h3>
</hgroup>
<p>
<a href="http://6002x.mitx.mit.edu/" class="more-info">More information <span>&amp;</span> Enroll <span class="arrow">&#8227;</span></a>
</p>
<p>Taught by Anant Agarwal, with Gerald Sussman and Piotr Mitros, 6.002x (Circuits and Electronics) is an on-line adaption of 6.002, MIT&rsquo;s first undergraduate analog design course. This prototype course will run, free of charge, for students worldwide from March 5, 2012 through June 8, 2012. Students will be given the opportunity to demonstrate their mastery of the material and earn a certificate from <em>MITx</em>.</p>
<p>Taught by Anant Agarwal, with Gerald Sussman and Piotr Mitros, 6.002x (Circuits and Electronics) is an on-line adaption of 6.002, MIT&rsquo;s first undergraduate analog design course. This prototype course is running, free of charge, for students worldwide from March 5, 2012 through June 8, 2012. Students are given the opportunity to demonstrate their mastery of the material and earn a certificate from <em>MITx</em>.</p>
</section>
</section>
......
......@@ -235,26 +235,20 @@ nav.sequence-nav {
section.course-content {
div#seq_content {
margin-bottom: 60px;
}
position: relative;
nav.sequence-bottom {
bottom: (-(lh()));
position: relative;
margin: lh(2) 0 0;
text-align: center;
ul {
@extend .clearfix;
background-color: darken(#F6EFD4, 5%);
background-color: darken($cream, 5%);
border: 1px solid darken(#f6efd4, 20%);
border-bottom: 0;
@include border-radius(3px 3px 0 0);
@include border-radius(3px);
@include box-shadow(inset 0 0 0 1px lighten(#f6efd4, 5%));
margin: 0 auto;
overflow: hidden;
width: 106px;
@include inline-block();
li {
float: left;
......@@ -267,15 +261,13 @@ section.course-content {
background-repeat: no-repeat;
border-bottom: none;
display: block;
display: block;
padding: lh(.75) 4px;
padding: lh(.5) 4px;
text-indent: -9999px;
@include transition(all, .4s, $ease-in-out-quad);
width: 45px;
&:hover {
background-color: darken($cream, 10%);
color: darken(#F6EFD4, 60%);
color: darken($cream, 60%);
opacity: .5;
text-decoration: none;
......@@ -291,6 +283,7 @@ section.course-content {
&.prev {
a {
background-image: url('/static/images/sequence-nav/previous-icon.png');
border-right: 1px solid darken(#f6efd4, 20%);
&:hover {
background-color: none;
......
......@@ -20,6 +20,7 @@ section.index-content {
p {
line-height: lh();
margin-bottom: lh();
}
ul {
......@@ -237,6 +238,19 @@ section.index-content {
padding-top: lh(8);
}
}
div.announcement {
p.announcement-button {
a {
margin-top: 0;
}
}
img {
max-width: 100%;
margin-bottom: lh();
}
}
}
......
......@@ -4,11 +4,15 @@ li.calc-main {
position: fixed;
width: 100%;
@include transition(bottom);
z-index: 9999;
z-index: 99;
-webkit-appearance: none;
&.open {
bottom: -36px;
div#calculator_wrapper form div.input-wrapper div.help-wrapper dl {
display: block;
}
}
a.calc {
......@@ -128,6 +132,7 @@ li.calc-main {
right: -40px;
top: -110px;
width: 500px;
display: none;
@include transition();
&.shown {
......
<%!
import json
import math
%>
var rawData = ${json.dumps(histogram)};
var maxx = 1;
var maxy = 1.5;
var xticks = Array();
var yticks = Array();
var data = Array();
for (var i = 0; i < rawData.length; i++) {
var score = rawData[i][0];
var count = rawData[i][1];
var log_count = Math.log(count + 1);
data.push( [score, log_count] );
xticks.push( [score, score.toString()] );
yticks.push( [log_count, count.toString()] );
maxx = Math.max( score + 1, maxx );
maxy = Math.max(log_count*1.1, maxy );
}
$.plot($("#histogram_${module_id}"), [{
data: data,
bars: { show: true,
align: 'center',
lineWidth: 0,
fill: 1.0 },
color: "#b72121",
}],
{
xaxis: {min: -1, max: maxx, ticks: xticks, tickLength: 0},
yaxis: {min: 0.0, max: maxy, ticks: yticks, labelWidth: 50},
}
);
<div class="staff_info">
${xml | h}
</div>
<div>
${ str(histogram) }
</div>
%if render_histogram:
<div id="histogram_${module_id}" style="width:200px;height:150px"></div>
%endif
......@@ -122,3 +122,11 @@
});
</script>
</%block>
<ol class="video-mod">
% for t in annotations:
<li id="video-${annotations.index(t)}">
${t[1]['content']}
</li>
% endfor
</ol>
......@@ -49,6 +49,7 @@ if settings.COURSEWARE_ENABLED:
url(r'^courseware/$', 'courseware.views.index', name="courseware"),
url(r'^info$', 'util.views.info'),
url(r'^wiki/', include('simplewiki.urls')),
url(r'^masquerade/', include('masquerade.urls')),
url(r'^courseware/(?P<course>[^/]*)/(?P<chapter>[^/]*)/(?P<section>[^/]*)/$', 'courseware.views.index', name="courseware_section"),
url(r'^courseware/(?P<course>[^/]*)/(?P<chapter>[^/]*)/$', 'courseware.views.index', name="courseware_chapter"),
url(r'^courseware/(?P<course>[^/]*)/$', 'courseware.views.index', name="courseware_course"),
......
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