Merge branch 'master' into feature/tomg/fall-design
This commit is contained in:
@@ -3,6 +3,7 @@ import time
|
||||
import logging
|
||||
import requests
|
||||
from lxml import etree
|
||||
from path import path # NOTE (THK): Only used for detecting presence of syllabus
|
||||
|
||||
from xmodule.util.decorators import lazyproperty
|
||||
from xmodule.graders import load_grading_policy
|
||||
@@ -77,6 +78,10 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
# NOTE: relies on the modulestore to call set_grading_policy() right after
|
||||
# init. (Modulestore is in charge of figuring out where to load the policy from)
|
||||
|
||||
# NOTE (THK): This is a last-minute addition for Fall 2012 launch to dynamically
|
||||
# disable the syllabus content for courses that do not provide a syllabus
|
||||
self.syllabus_present = self.system.resources_fs.exists(path('syllabus'))
|
||||
|
||||
|
||||
def set_grading_policy(self, policy_str):
|
||||
"""Parse the policy specified in policy_str, and save it"""
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Wikipath Extension for Python-Markdown
|
||||
======================================
|
||||
|
||||
Converts [Link Name](wiki:ArticleName) to relative links pointing to article. Requires Python-Markdown 2.0+
|
||||
|
||||
Basic usage:
|
||||
|
||||
>>> import markdown
|
||||
>>> text = "Some text with a [Link Name](wiki:ArticleName)."
|
||||
>>> html = markdown.markdown(text, ['wikipath(base_url="/wiki/view/")'])
|
||||
>>> html
|
||||
u'<p>Some text with a <a class="wikipath" href="/wiki/view/ArticleName/">Link Name</a>.</p>'
|
||||
|
||||
Dependencies:
|
||||
* [Python 2.3+](http://python.org)
|
||||
* [Markdown 2.0+](http://www.freewisdom.org/projects/python-markdown/)
|
||||
'''
|
||||
|
||||
|
||||
import markdown
|
||||
try:
|
||||
# Markdown 2.1.0 changed from 2.0.3. We try importing the new version first,
|
||||
# but import the 2.0.3 version if it fails
|
||||
from markdown.util import etree
|
||||
except:
|
||||
from markdown import etree
|
||||
|
||||
|
||||
class WikiPathExtension(markdown.Extension):
|
||||
def __init__(self, configs):
|
||||
# set extension defaults
|
||||
self.config = {
|
||||
'base_url' : ['/', 'String to append to beginning of URL.'],
|
||||
'html_class' : ['wikipath', 'CSS hook. Leave blank for none.']
|
||||
}
|
||||
|
||||
# Override defaults with user settings
|
||||
for key, value in configs :
|
||||
# self.config[key][0] = value
|
||||
self.setConfig(key, value)
|
||||
|
||||
|
||||
def extendMarkdown(self, md, md_globals):
|
||||
self.md = md
|
||||
|
||||
# append to end of inline patterns
|
||||
WIKI_RE = r'\[(?P<linkTitle>.+?)\]\(wiki:(?P<wikiTitle>[a-zA-Z\d/_-]*)\)'
|
||||
wikiPathPattern = WikiPath(WIKI_RE, self.config)
|
||||
wikiPathPattern.md = md
|
||||
md.inlinePatterns.add('wikipath', wikiPathPattern, "<reference")
|
||||
|
||||
class WikiPath(markdown.inlinepatterns.Pattern):
|
||||
def __init__(self, pattern, config):
|
||||
markdown.inlinepatterns.Pattern.__init__(self, pattern)
|
||||
self.config = config
|
||||
|
||||
def handleMatch(self, m) :
|
||||
article_title = m.group('wikiTitle')
|
||||
if article_title.startswith("/"):
|
||||
article_title = article_title[1:]
|
||||
|
||||
url = self.config['base_url'][0] + article_title
|
||||
label = m.group('linkTitle')
|
||||
a = etree.Element('a')
|
||||
a.set('href', url)
|
||||
a.text = label
|
||||
|
||||
if self.config['html_class'][0]:
|
||||
a.set('class', self.config['html_class'][0])
|
||||
|
||||
return a
|
||||
|
||||
def _getMeta(self):
|
||||
""" Return meta data or config data. """
|
||||
base_url = self.config['base_url'][0]
|
||||
html_class = self.config['html_class'][0]
|
||||
if hasattr(self.md, 'Meta'):
|
||||
if self.md.Meta.has_key('wiki_base_url'):
|
||||
base_url = self.md.Meta['wiki_base_url'][0]
|
||||
if self.md.Meta.has_key('wiki_html_class'):
|
||||
html_class = self.md.Meta['wiki_html_class'][0]
|
||||
return base_url, html_class
|
||||
|
||||
def makeExtension(configs=None) :
|
||||
return WikiPathExtension(configs=configs)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
@@ -5,18 +5,15 @@ from django.core.urlresolvers import reverse_lazy
|
||||
from wiki.core.plugins.base import BasePlugin
|
||||
from wiki.core.plugins import registry as plugin_registry
|
||||
|
||||
from course_wiki.plugins.markdownedx import mdx_circuit, mdx_wikipath, mdx_mathjax, mdx_video
|
||||
from course_wiki.plugins.markdownedx import mdx_circuit, mdx_mathjax, mdx_video
|
||||
|
||||
class ExtendMarkdownPlugin(BasePlugin):
|
||||
"""
|
||||
This plugin simply loads all of the markdown extensions we use in edX.
|
||||
"""
|
||||
|
||||
wiki_base_url = reverse_lazy("wiki:get", kwargs={'path' : ""})
|
||||
|
||||
|
||||
markdown_extensions = [mdx_circuit.CircuitExtension(configs={}),
|
||||
#mdx_image.ImageExtension() , #This one doesn't work. Tries to import simplewiki.settings
|
||||
mdx_wikipath.WikiPathExtension(configs={'base_url' : wiki_base_url}.iteritems() ) ,
|
||||
mdx_mathjax.MathJaxExtension(configs={}) ,
|
||||
mdx_video.VideoExtension(configs={})]
|
||||
|
||||
|
||||
@@ -393,3 +393,44 @@ def instructor_dashboard(request, course_id):
|
||||
context = {'course': course,
|
||||
'staff_access': True,}
|
||||
return render_to_response('courseware/instructor_dashboard.html', context)
|
||||
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
def enroll_students(request, course_id):
|
||||
''' Allows a staff member to enroll students in a course.
|
||||
|
||||
This is a short-term hack for Berkeley courses launching fall
|
||||
2012. In the long term, we would like functionality like this, but
|
||||
we would like both the instructor and the student to agree. Right
|
||||
now, this allows any instructor to add students to their course,
|
||||
which we do not want.
|
||||
|
||||
It is poorly written and poorly tested, but it's designed to be
|
||||
stripped out.
|
||||
'''
|
||||
|
||||
course = get_course_with_access(request.user, course_id, 'staff')
|
||||
existing_students = [ce.user.email for ce in CourseEnrollment.objects.filter(course_id = course_id)]
|
||||
|
||||
if 'new_students' in request.POST:
|
||||
new_students = request.POST['new_students'].split('\n')
|
||||
else:
|
||||
new_students = []
|
||||
new_students = [s.strip() for s in new_students]
|
||||
|
||||
added_students = []
|
||||
rejected_students = []
|
||||
|
||||
for student in new_students:
|
||||
try:
|
||||
nce = CourseEnrollment(user=User.objects.get(email = student), course_id = course_id)
|
||||
nce.save()
|
||||
added_students.append(student)
|
||||
except:
|
||||
rejected_students.append(student)
|
||||
|
||||
return render_to_response("enroll_students.html", {'course':course_id,
|
||||
'existing_students': existing_students,
|
||||
'added_students': added_students,
|
||||
'rejected_students': rejected_students,
|
||||
'debug':new_students})
|
||||
|
||||
@@ -60,10 +60,6 @@ MITX_FEATURES = {
|
||||
# university to use for branding purposes
|
||||
'SUBDOMAIN_BRANDING': False,
|
||||
|
||||
# TODO: This will be removed once course-specific tabs are in place. see
|
||||
# courseware/courses.py
|
||||
'ENABLE_SYLLABUS' : True,
|
||||
|
||||
'ENABLE_TEXTBOOK' : True,
|
||||
'ENABLE_DISCUSSION' : False,
|
||||
'ENABLE_DISCUSSION_SERVICE': True,
|
||||
@@ -595,6 +591,7 @@ INSTALLED_APPS = (
|
||||
'mptt',
|
||||
'sekizai',
|
||||
#'wiki.plugins.attachments',
|
||||
'wiki.plugins.links',
|
||||
'wiki.plugins.notifications',
|
||||
'course_wiki.plugins.markdownedx',
|
||||
|
||||
|
||||
@@ -394,7 +394,6 @@ section.wiki {
|
||||
.CodeMirror {
|
||||
background: #fafafa;
|
||||
border: 1px solid #c8c8c8;
|
||||
@include border-radius(3px);
|
||||
@include box-shadow(0 1px 0 0 rgba(255, 255, 255, 0.6), inset 0 0 3px 0 rgba(0, 0, 0, 0.1));
|
||||
}
|
||||
|
||||
@@ -694,6 +693,28 @@ section.wiki {
|
||||
margin-top: 9px;
|
||||
}
|
||||
|
||||
.error {
|
||||
font-size: 1em;
|
||||
color: $pink;
|
||||
|
||||
.help-block {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
input {
|
||||
border-color: $pink;
|
||||
}
|
||||
}
|
||||
|
||||
.back {
|
||||
float: right;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------
|
||||
|
||||
Directory
|
||||
@@ -740,6 +761,7 @@ section.wiki {
|
||||
th, td {
|
||||
border-bottom: 1px solid $light-gray;
|
||||
padding: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
@@ -843,6 +865,10 @@ section.wiki {
|
||||
}
|
||||
}
|
||||
|
||||
section.delete {
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ def url_class(url):
|
||||
<ol class="course-tabs">
|
||||
<li class="courseware"><a href="${reverse('courseware', args=[course.id])}" class="${url_class('courseware')}">Courseware</a></li>
|
||||
<li class="info"><a href="${reverse('info', args=[course.id])}" class="${url_class('info')}">Course Info</a></li>
|
||||
% if settings.MITX_FEATURES.get('ENABLE_SYLLABUS'):
|
||||
% if course.syllabus_present:
|
||||
<li class="syllabus"><a href="${reverse('syllabus', args=[course.id])}" class="${url_class('syllabus')}">Syllabus</a></li>
|
||||
% endif
|
||||
% if user.is_authenticated():
|
||||
|
||||
29
lms/templates/enroll_students.html
Normal file
29
lms/templates/enroll_students.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<h1>Student Enrollment Form </h1>
|
||||
|
||||
<p> Course: ${ course }
|
||||
|
||||
<form method="POST">
|
||||
<input type="hidden" name="csrfmiddlewaretoken" value="${ csrf_token }">
|
||||
<h2> Add new students </h2>
|
||||
<textarea name="new_students">
|
||||
</textarea>
|
||||
<input type="submit">
|
||||
</form>
|
||||
|
||||
<p> Existing students:
|
||||
|
||||
<p> ${ existing_students }
|
||||
|
||||
<p> New students added:
|
||||
${ added_students }
|
||||
|
||||
<p> Students rejected:
|
||||
${ rejected_students }
|
||||
|
||||
<p> Debug:
|
||||
<p> ${ debug }
|
||||
|
||||
|
||||
<p> foo
|
||||
<p> bar
|
||||
<p> biff
|
||||
@@ -32,14 +32,15 @@
|
||||
<form method="POST" class="form-horizontal">
|
||||
{% wiki_form create_form %}
|
||||
<div class="form-actions">
|
||||
<a href="{% url 'wiki:get' path=parent_urlpath.path %}" class="btn btn-large">
|
||||
<span class="icon-circle-arrow-left"></span>
|
||||
{% trans "Go back" %}
|
||||
</a>
|
||||
<button type="submit" name="save_changes" class="btn btn-primary btn-large">
|
||||
<span class="icon-plus"></span>
|
||||
{% trans "Create article" %}
|
||||
</button>
|
||||
|
||||
<a href="{% url 'wiki:get' path=parent_urlpath.path %}" class="btn btn-large back">
|
||||
<span class="icon-circle-arrow-left"></span>
|
||||
{% trans "Go back" %}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
64
lms/templates/wiki/delete.html
Normal file
64
lms/templates/wiki/delete.html
Normal file
@@ -0,0 +1,64 @@
|
||||
{% extends "wiki/base.html" %}
|
||||
{% load wiki_tags i18n sekizai_tags %}
|
||||
{% load url from future %}
|
||||
|
||||
{% block pagetitle %}{% trans "Delete article" %}{% endblock %}
|
||||
|
||||
{% block wiki_contents %}
|
||||
<section class="delete">
|
||||
<h1 class="page-header">{% trans "Delete" %} "{{ article.current_revision.title }}"</h1>
|
||||
|
||||
{% if cannot_delete_root %}
|
||||
<p class="lead">{% trans "You cannot delete a root article." %}</p>
|
||||
<p><a href="{% url 'wiki:get' path=urlpath.path article_id=article.id %}">{% trans "Go back" %}</a></p>
|
||||
{% else %}
|
||||
|
||||
{% if cannot_delete_children %}
|
||||
|
||||
<p class="alert alert-error"><strong>{% trans "You cannot delete this article because you do not have permission to delete articles with children. Try to remove the children manually one-by-one." %}</strong></p>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if delete_children %}
|
||||
|
||||
<p class="lead">{% trans "You are deleting an article. This means that its children will be deleted as well. If you choose to purge, children will also be purged!" %}</p>
|
||||
|
||||
<h2>{% trans "Articles that will be deleted" %}</h2>
|
||||
|
||||
<ul>
|
||||
{% for child in delete_children %}
|
||||
<li><a href="{% url 'wiki:get' article_id=child.article.id %}" target="_blank">{{ child.article }}</a></li>
|
||||
{% if delete_children_more %}
|
||||
<li><em>{% trans "...and more!" %}</em></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if not cannot_delete_children %}
|
||||
<p class="lead">{% trans "You are deleting an article. Please confirm." %}</p>
|
||||
|
||||
<form method="POST" class="form-horizontal">
|
||||
{% wiki_form delete_form %}
|
||||
<script type="text/javascript">
|
||||
$('#id_revision').val('{{ article.current_revision.id }}');
|
||||
</script>
|
||||
<div class="form-actions">
|
||||
<button type="submit" name="save_changes" class="btn btn-danger btn-large">
|
||||
<span class="icon-plus"></span>
|
||||
{% trans "Delete article" %}
|
||||
</button>
|
||||
<a href="{% url 'wiki:get' path=urlpath.path article_id=article.id %}" class="btn btn-large back">
|
||||
<span class="icon-circle-arrow-left"></span>
|
||||
{% trans "Go back" %}
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
<form method="POST" class="form-horizontal" id="article_edit_form" enctype="multipart/form-data">
|
||||
{% include "wiki/includes/editor.html" %}
|
||||
<div class="form-actions">
|
||||
<button type="submit" name="preview" value="1" class="btn btn-large" onclick="$('#previewModal').modal('show'); this.form.target = 'previewWindow'; this.form.action = '{% url 'wiki:preview' path=urlpath.path article_id=article.id %}';">
|
||||
<span class="icon-eye-open"></span>
|
||||
{% trans "Preview" %}
|
||||
</button>
|
||||
<button type="submit" name="save" value="1" class="btn btn-large btn-primary" onclick="this.form.target=''; this.form.action='{% url 'wiki:edit' path=urlpath.path article_id=article.id %}'">
|
||||
<span class="icon-ok"></span>
|
||||
{% trans "Save changes" %}
|
||||
</button>
|
||||
<button type="submit" name="preview" value="1" class="btn btn-large" onclick="$('#previewModal').modal('show'); this.form.target = 'previewWindow'; this.form.action = '{% url 'wiki:preview' path=urlpath.path article_id=article.id %}';">
|
||||
<span class="icon-eye-open"></span>
|
||||
{% trans "Preview" %}
|
||||
</button>
|
||||
|
||||
<a href="{% url 'wiki:delete' path=urlpath.path article_id=article.id %}" class="pull-right btn btn-danger">
|
||||
<span class="icon-trash"></span>
|
||||
@@ -29,16 +29,17 @@
|
||||
<iframe name="previewWindow" frameborder="0"></iframe>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn btn-large" data-dismiss="modal">
|
||||
<span class="icon-circle-arrow-left"></span>
|
||||
{% trans "Back to editor" %}
|
||||
</a>
|
||||
<button type="submit" name="save" value="1" class="btn btn-large btn-primary" onclick="this.form.target=''; this.form.action='{% url 'wiki:edit' path=urlpath.path article_id=article.id %}'">
|
||||
<span class="icon-ok"></span>
|
||||
{% trans "Save changes" %}
|
||||
</button>
|
||||
|
||||
<a href="#" class="btn btn-large" data-dismiss="modal">
|
||||
<span class="icon-circle-arrow-left"></span>
|
||||
{% trans "Back to editor" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -154,7 +154,8 @@ if settings.COURSEWARE_ENABLED:
|
||||
'courseware.views.gradebook', name='gradebook'),
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/grade_summary$',
|
||||
'courseware.views.grade_summary', name='grade_summary'),
|
||||
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/enroll_students$',
|
||||
'courseware.views.enroll_students', name='enroll_students'),
|
||||
)
|
||||
|
||||
# discussion forums live within courseware, so courseware must be enabled first
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles
|
||||
-e git://github.com/MITx/django-pipeline.git#egg=django-pipeline
|
||||
-e git://github.com/benjaoming/django-wiki.git@63003aa#egg=django-wiki
|
||||
-e git://github.com/benjaoming/django-wiki.git@3576a2d#egg=django-wiki
|
||||
-e git://github.com/dementrock/pystache_custom.git@776973740bdaad83a3b029f96e415a7d1e8bec2f#egg=pystache_custom-dev
|
||||
-e common/lib/capa
|
||||
-e common/lib/xmodule
|
||||
|
||||
Reference in New Issue
Block a user