Merge branch 'master' of github.com:MITx/mitx into jarv/add-local-logging
This commit is contained in:
@@ -4,9 +4,12 @@ from django.utils.encoding import force_unicode
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from wiki.editors.base import BaseEditor
|
||||
from wiki.editors.markitup import MarkItUpAdminWidget
|
||||
|
||||
|
||||
class CodeMirrorWidget(forms.Widget):
|
||||
def __init__(self, attrs=None):
|
||||
# The 'rows' and 'cols' attributes are required for HTML correctness.
|
||||
@@ -18,9 +21,15 @@ class CodeMirrorWidget(forms.Widget):
|
||||
|
||||
def render(self, name, value, attrs=None):
|
||||
if value is None: value = ''
|
||||
|
||||
final_attrs = self.build_attrs(attrs, name=name)
|
||||
return mark_safe(u'<div><textarea%s>%s</textarea></div>' % (flatatt(final_attrs),
|
||||
conditional_escape(force_unicode(value))))
|
||||
|
||||
# TODO use the help_text field of edit form instead of rendering a template
|
||||
|
||||
return render_to_string('wiki/includes/editor_widget.html',
|
||||
{'attrs': mark_safe(flatatt(final_attrs)),
|
||||
'content': conditional_escape(force_unicode(value)),
|
||||
})
|
||||
|
||||
|
||||
class CodeMirror(BaseEditor):
|
||||
@@ -50,5 +59,6 @@ class CodeMirror(BaseEditor):
|
||||
"js/vendor/CodeMirror/xml.js",
|
||||
"js/vendor/CodeMirror/mitx_markdown.js",
|
||||
"js/wiki/CodeMirror.init.js",
|
||||
"js/wiki/cheatsheet.js",
|
||||
)
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ log = logging.getLogger("mitx.courseware")
|
||||
|
||||
def yield_module_descendents(module):
|
||||
stack = module.get_display_items()
|
||||
stack.reverse()
|
||||
|
||||
while len(stack) > 0:
|
||||
next_module = stack.pop()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
@@ -143,8 +144,9 @@ def get_module(user, request, location, student_module_cache, course_id, positio
|
||||
exists.
|
||||
|
||||
Arguments:
|
||||
- user : current django User
|
||||
- request : current django HTTPrequest
|
||||
- user : User for whom we're getting the module
|
||||
- request : current django HTTPrequest. Note: request.user isn't used for anything--all auth
|
||||
and such works based on user.
|
||||
- location : A Location-like object identifying the module to load
|
||||
- student_module_cache : a StudentModuleCache
|
||||
- course_id : the course_id in the context of which to load module
|
||||
@@ -173,7 +175,13 @@ def _get_module(user, request, location, student_module_cache, course_id, positi
|
||||
if not has_access(user, descriptor, 'load'):
|
||||
return None
|
||||
|
||||
#TODO Only check the cache if this module can possibly have state
|
||||
# Anonymized student identifier
|
||||
h = hashlib.md5()
|
||||
h.update(settings.SECRET_KEY)
|
||||
h.update(str(user.id))
|
||||
anonymous_student_id = h.hexdigest()
|
||||
|
||||
# Only check the cache if this module can possibly have state
|
||||
instance_module = None
|
||||
shared_module = None
|
||||
if user.is_authenticated():
|
||||
@@ -197,6 +205,8 @@ def _get_module(user, request, location, student_module_cache, course_id, positi
|
||||
location=descriptor.location.url(),
|
||||
dispatch=''),
|
||||
)
|
||||
# Intended use is as {ajax_url}/{dispatch_command}, so get rid of the trailing slash.
|
||||
ajax_url = ajax_url.rstrip('/')
|
||||
|
||||
# Fully qualified callback URL for external queueing system
|
||||
xqueue_callback_url = '{proto}://{host}'.format(
|
||||
@@ -217,7 +227,9 @@ def _get_module(user, request, location, student_module_cache, course_id, positi
|
||||
|
||||
xqueue = {'interface': xqueue_interface,
|
||||
'callback_url': xqueue_callback_url,
|
||||
'default_queuename': xqueue_default_queuename.replace(' ', '_')}
|
||||
'default_queuename': xqueue_default_queuename.replace(' ', '_'),
|
||||
'waittime': settings.XQUEUE_WAITTIME_BETWEEN_REQUESTS
|
||||
}
|
||||
|
||||
def inner_get_module(location):
|
||||
"""
|
||||
@@ -241,7 +253,8 @@ def _get_module(user, request, location, student_module_cache, course_id, positi
|
||||
# a module is coming through get_html and is therefore covered
|
||||
# by the replace_static_urls code below
|
||||
replace_urls=replace_urls,
|
||||
node_path=settings.NODE_PATH
|
||||
node_path=settings.NODE_PATH,
|
||||
anonymous_student_id=anonymous_student_id
|
||||
)
|
||||
# pass position specified in URL to module through ModuleSystem
|
||||
system.set('position', position)
|
||||
@@ -409,6 +422,10 @@ def modx_dispatch(request, dispatch, location, course_id):
|
||||
'''
|
||||
# ''' (fix emacs broken parsing)
|
||||
|
||||
# Check parameters and fail fast if there's a problem
|
||||
if not Location.is_valid(location):
|
||||
raise Http404("Invalid location")
|
||||
|
||||
# Check for submitted files and basic file size checks
|
||||
p = request.POST.copy()
|
||||
if request.FILES:
|
||||
|
||||
@@ -411,8 +411,6 @@ class TestViewAuth(PageLoader):
|
||||
"""list of urls that only instructors/staff should be able to see"""
|
||||
urls = reverse_urls(['instructor_dashboard','gradebook','grade_summary'],
|
||||
course)
|
||||
urls.append(reverse('student_progress', kwargs={'course_id': course.id,
|
||||
'student_id': user(self.student).id}))
|
||||
return urls
|
||||
|
||||
def check_non_staff(course):
|
||||
@@ -435,6 +433,17 @@ class TestViewAuth(PageLoader):
|
||||
print 'checking for 200 on {0}'.format(url)
|
||||
self.check_for_get_code(200, url)
|
||||
|
||||
# The student progress tab is not accessible to a student
|
||||
# before launch, so the instructor view-as-student feature should return a 404 as well.
|
||||
# TODO (vshnayder): If this is not the behavior we want, will need
|
||||
# to make access checking smarter and understand both the effective
|
||||
# user (the student), and the requesting user (the prof)
|
||||
url = reverse('student_progress', kwargs={'course_id': course.id,
|
||||
'student_id': user(self.student).id})
|
||||
print 'checking for 404 on view-as-student: {0}'.format(url)
|
||||
self.check_for_get_code(404, url)
|
||||
|
||||
|
||||
# First, try with an enrolled student
|
||||
print '=== Testing student access....'
|
||||
self.login(self.student, self.password)
|
||||
|
||||
@@ -325,14 +325,21 @@ def progress(request, course_id, student_id=None):
|
||||
raise Http404
|
||||
student = User.objects.get(id=int(student_id))
|
||||
|
||||
# NOTE: To make sure impersonation by instructor works, use
|
||||
# student instead of request.user in the rest of the function.
|
||||
|
||||
student_module_cache = StudentModuleCache.cache_for_descriptor_descendents(
|
||||
course_id, request.user, course)
|
||||
course_module = get_module(request.user, request, course.location,
|
||||
course_id, student, course)
|
||||
course_module = get_module(student, request, course.location,
|
||||
student_module_cache, course_id)
|
||||
|
||||
# The course_module should be accessible, but check anyway just in case something went wrong:
|
||||
if course_module is None:
|
||||
raise Http404("Course does not exist")
|
||||
|
||||
courseware_summary = grades.progress_summary(student, course_module,
|
||||
course.grader, student_module_cache)
|
||||
grade_summary = grades.grade(request.user, request, course, student_module_cache)
|
||||
grade_summary = grades.grade(student, request, course, student_module_cache)
|
||||
|
||||
context = {'course': course,
|
||||
'courseware_summary': courseware_summary,
|
||||
|
||||
@@ -21,11 +21,17 @@ def dashboard(request):
|
||||
if not request.user.is_staff:
|
||||
raise Http404
|
||||
|
||||
query = "select count(user_id) as students, course_id from student_courseenrollment group by course_id order by students desc"
|
||||
|
||||
queries=[]
|
||||
queries.append("select count(user_id) as students, course_id from student_courseenrollment group by course_id order by students desc;")
|
||||
queries.append("select count(distinct user_id) as unique_students from student_courseenrollment;")
|
||||
queries.append("select registrations, count(registrations) from (select count(user_id) as registrations from student_courseenrollment group by user_id) as registrations_per_user group by registrations;")
|
||||
|
||||
from django.db import connection
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(query)
|
||||
results = dictfetchall(cursor)
|
||||
results =[]
|
||||
|
||||
for query in queries:
|
||||
cursor.execute(query)
|
||||
results.append(dictfetchall(cursor))
|
||||
|
||||
return HttpResponse(json.dumps(results, indent=4))
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# File: manage_course_groups
|
||||
#
|
||||
# interactively list and edit membership in course staff and instructor groups
|
||||
|
||||
import os, sys, string, re
|
||||
import datetime
|
||||
from getpass import getpass
|
||||
import json
|
||||
import readline
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User, Group
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# get all staff groups
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Manage course group membership, interactively."
|
||||
|
||||
def handle(self, *args, **options):
|
||||
|
||||
gset = Group.objects.all()
|
||||
|
||||
print "Groups:"
|
||||
for cnt,g in zip(range(len(gset)), gset):
|
||||
print "%d. %s" % (cnt,g)
|
||||
|
||||
gnum = int(raw_input('Choose group to manage (enter #): '))
|
||||
|
||||
group = gset[gnum]
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# users in group
|
||||
|
||||
uall = User.objects.all()
|
||||
if uall.count()<50:
|
||||
print "----"
|
||||
print "List of All Users: %s" % [str(x.username) for x in uall]
|
||||
print "----"
|
||||
else:
|
||||
print "----"
|
||||
print "There are %d users, which is too many to list" % uall.count()
|
||||
print "----"
|
||||
|
||||
while True:
|
||||
|
||||
print "Users in the group:"
|
||||
|
||||
uset = group.user_set.all()
|
||||
for cnt, u in zip(range(len(uset)), uset):
|
||||
print "%d. %s" % (cnt, u)
|
||||
|
||||
action = raw_input('Choose user to delete (enter #) or enter usernames (comma delim) to add: ')
|
||||
|
||||
m = re.match('^[0-9]+$',action)
|
||||
if m:
|
||||
unum = int(action)
|
||||
u = uset[unum]
|
||||
print "Deleting user %s" % u
|
||||
u.groups.remove(group)
|
||||
|
||||
else:
|
||||
for uname in action.split(','):
|
||||
try:
|
||||
user = User.objects.get(username=action)
|
||||
except Exception as err:
|
||||
print "Error %s" % err
|
||||
continue
|
||||
print "adding %s to group %s" % (user, group)
|
||||
user.groups.add(group)
|
||||
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ def gitreload(request, reload_dir=None):
|
||||
|
||||
ALLOWED_IPS = [] # allow none by default
|
||||
if hasattr(settings,'ALLOWED_GITRELOAD_IPS'): # allow override in settings
|
||||
ALLOWED_IPS = ALLOWED_GITRELOAD_IPS
|
||||
ALLOWED_IPS = settings.ALLOWED_GITRELOAD_IPS
|
||||
|
||||
if not (ip in ALLOWED_IPS or 'any' in ALLOWED_IPS):
|
||||
if request.user and request.user.is_staff:
|
||||
|
||||
@@ -86,6 +86,9 @@ DEFAULT_GROUPS = []
|
||||
# If this is true, random scores will be generated for the purpose of debugging the profile graphs
|
||||
GENERATE_PROFILE_SCORES = False
|
||||
|
||||
# Used with XQueue
|
||||
XQUEUE_WAITTIME_BETWEEN_REQUESTS = 5 # seconds
|
||||
|
||||
############################# SET PATH INFORMATION #############################
|
||||
PROJECT_ROOT = path(__file__).abspath().dirname().dirname() # /mitx/lms
|
||||
REPO_ROOT = PROJECT_ROOT.dirname()
|
||||
|
||||
@@ -15,7 +15,7 @@ TEMPLATE_DEBUG = True
|
||||
|
||||
MITX_FEATURES['DISABLE_START_DATES'] = True
|
||||
MITX_FEATURES['ENABLE_SQL_TRACKING_LOGS'] = True
|
||||
MITX_FEATURES['SUBDOMAIN_COURSE_LISTINGS'] = True
|
||||
MITX_FEATURES['SUBDOMAIN_COURSE_LISTINGS'] = False # Enable to test subdomains--otherwise, want all courses to show up
|
||||
MITX_FEATURES['SUBDOMAIN_BRANDING'] = True
|
||||
|
||||
WIKI_ENABLED = True
|
||||
@@ -78,10 +78,10 @@ COURSE_LISTINGS = {
|
||||
'MITx/3.091x/2012_Fall',
|
||||
'MITx/6.002x/2012_Fall',
|
||||
'MITx/6.00x/2012_Fall'],
|
||||
'berkeley': ['BerkeleyX/CS169.1x/Cal_2012_Fall',
|
||||
'BerkeleyX/CS188.1x/Cal_2012_Fall'],
|
||||
'berkeley': ['BerkeleyX/CS169/fa12',
|
||||
'BerkeleyX/CS188/fa12'],
|
||||
'harvard': ['HarvardX/CS50x/2012H'],
|
||||
'mit': [],
|
||||
'mit': ['MITx/3.091/MIT_2012_Fall'],
|
||||
'sjsu': ['MITx/6.002x-EE98/2012_Fall_SJSU'],
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ LMS_MIGRATION_ALLOWED_IPS = ['127.0.0.1']
|
||||
MITX_FEATURES['AUTH_USE_OPENID'] = True
|
||||
MITX_FEATURES['BYPASS_ACTIVATION_EMAIL_FOR_EXTAUTH'] = True
|
||||
|
||||
INSTALLED_APPS += ('external_auth',)
|
||||
INSTALLED_APPS += ('external_auth',)
|
||||
INSTALLED_APPS += ('django_openid_auth',)
|
||||
|
||||
OPENID_CREATE_USERS = False
|
||||
|
||||
@@ -58,7 +58,7 @@ XQUEUE_INTERFACE = {
|
||||
},
|
||||
"basic_auth": ('anant', 'agarwal'),
|
||||
}
|
||||
|
||||
XQUEUE_WAITTIME_BETWEEN_REQUESTS = 5 # seconds
|
||||
|
||||
# TODO (cpennington): We need to figure out how envs/test.py can inject things
|
||||
# into common.py so that we don't have to repeat this sort of thing
|
||||
|
||||
@@ -124,7 +124,7 @@ if Backbone?
|
||||
url = @model.urlFor('retrieve')
|
||||
DiscussionUtil.safeAjax
|
||||
$elem: $elem
|
||||
$loading: $(event.target) if event
|
||||
$loading: @$(".discussion-show-comments")
|
||||
type: "GET"
|
||||
url: url
|
||||
success: (response, textStatus) =>
|
||||
|
||||
@@ -169,7 +169,7 @@ if Backbone?
|
||||
url = URI($elem.attr("action")).addSearch({text: @$(".search-input").val()})
|
||||
@reload($elem, url)
|
||||
|
||||
sort: ->
|
||||
sort: (event) ->
|
||||
$elem = $(event.target)
|
||||
url = $elem.attr("sort-url")
|
||||
@reload($elem, url)
|
||||
|
||||
@@ -3,9 +3,6 @@ $ ->
|
||||
window.$$contents = {}
|
||||
window.$$discussions = {}
|
||||
|
||||
$(".discussion-module").each (index, elem) ->
|
||||
view = new DiscussionModuleView(el: elem)
|
||||
|
||||
$("section.discussion").each (index, elem) ->
|
||||
discussionData = DiscussionUtil.getDiscussionData($(elem).attr("_id"))
|
||||
discussion = new Discussion()
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
$ ->
|
||||
$.fn.extend
|
||||
loading: ->
|
||||
$(this).after("<span class='discussion-loading'></span>")
|
||||
@$_loading = $("<span class='discussion-loading'></span>")
|
||||
$(this).after(@$_loading)
|
||||
loaded: ->
|
||||
$(this).parent().children(".discussion-loading").remove()
|
||||
@$_loading.remove()
|
||||
|
||||
class @DiscussionUtil
|
||||
|
||||
|
||||
9
lms/static/js/wiki/cheatsheet.js
Normal file
9
lms/static/js/wiki/cheatsheet.js
Normal file
@@ -0,0 +1,9 @@
|
||||
$(document).ready(function () {
|
||||
$('#cheatsheetLink').click(function() {
|
||||
$('#cheatsheetModal').modal('show');
|
||||
});
|
||||
|
||||
$('#cheatsheetModal .close-btn').click(function(e) {
|
||||
$('#cheatsheetModal').modal('hide');
|
||||
});
|
||||
});
|
||||
@@ -27,6 +27,12 @@ body.cs188 {
|
||||
margin-bottom: 1.416em;
|
||||
}
|
||||
|
||||
.choicegroup {
|
||||
input[type=checkbox], input[type=radio] {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -391,6 +391,18 @@ section.wiki {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
#div_id_content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#hint_id_content {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 0%;
|
||||
font-size: 12px;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.CodeMirror {
|
||||
background: #fafafa;
|
||||
border: 1px solid #c8c8c8;
|
||||
@@ -567,11 +579,73 @@ section.wiki {
|
||||
background: #f00 !important;
|
||||
}
|
||||
|
||||
|
||||
#cheatsheetLink {
|
||||
text-align: right;
|
||||
display: float;
|
||||
}
|
||||
|
||||
#cheatsheetModal {
|
||||
width: 950px;
|
||||
margin-left: -450px;
|
||||
margin-top: -100px;
|
||||
|
||||
.left-column {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.left-column,
|
||||
.right-column {
|
||||
float: left;
|
||||
width: 450px;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #ccc;
|
||||
@include linear-gradient(top, #eee, #d2d2d2);
|
||||
font-size: 22px;
|
||||
line-height: 28px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
@include box-shadow(0 1px 0 #fff inset, 0 1px 2px rgba(0, 0, 0, .2));
|
||||
}
|
||||
}
|
||||
|
||||
#cheatsheet-body {
|
||||
background: #fff;
|
||||
text-align: left;
|
||||
padding: 20px;
|
||||
font-size: 14px;
|
||||
@include clearfix;
|
||||
|
||||
h3 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: circle;
|
||||
line-height: 1.4;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
#cheatsheet-body section + section {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
#cheatsheet-body pre{
|
||||
color: #000;
|
||||
text-align: left;
|
||||
background: #eee;
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/*-----------------
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
</div>
|
||||
<div class="discussion-right-wrapper">
|
||||
<ul class="admin-actions">
|
||||
<li><a href="javascript:void(0)" class="admin-endorse">Endorse</a></li>
|
||||
<li><a href="javascript:void(0)" class="admin-edit">Edit</a></li>
|
||||
<li><a href="javascript:void(0)" class="admin-delete">Delete</a></li>
|
||||
<li style="display: none;"><a href="javascript:void(0)" class="admin-endorse">Endorse</a></li>
|
||||
<li style="display: none;"><a href="javascript:void(0)" class="admin-edit">Edit</a></li>
|
||||
<li style="display: none;"><a href="javascript:void(0)" class="admin-delete">Delete</a></li>
|
||||
{{#thread}}
|
||||
<li><a href="javascript:void(0)" class="admin-openclose">{{close_thread_text}}</a></li>
|
||||
<li style="display: none;"><a href="javascript:void(0)" class="admin-openclose">{{close_thread_text}}</a></li>
|
||||
{{/thread}}
|
||||
</ul>
|
||||
{{#thread}}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
% if name is not UNDEFINED and name is not None:
|
||||
<h1> ${display_name} </h1>
|
||||
% if display_name is not UNDEFINED and display_name is not None:
|
||||
<h2> ${display_name} </h2>
|
||||
% endif
|
||||
|
||||
<div id="video_${id}" class="video" data-streams="${streams}" data-caption-data-dir="${data_dir}">
|
||||
<div id="video_${id}" class="video" data-streams="${streams}" data-caption-data-dir="${data_dir}" data-show-captions="${show_captions}">
|
||||
<div class="tc-wrapper">
|
||||
<article class="video-wrapper">
|
||||
<section class="video-player">
|
||||
|
||||
@@ -27,21 +27,20 @@
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
{% addtoblock 'js' %}
|
||||
{% comment %} These scripts load at the bottom of the body {% endcomment %}
|
||||
|
||||
|
||||
<script src="{% static 'js/bootstrap-alert.js' %}"></script>
|
||||
<script src="{% static 'js/bootstrap-collapse.js' %}"></script>
|
||||
<script src="{% static 'js/bootstrap-modal.js' %}"></script>
|
||||
|
||||
|
||||
{% with mathjax_mode='wiki' %}
|
||||
{% include "mathjax_include.html" %}
|
||||
{% endwith %}
|
||||
|
||||
{% endaddtoblock %}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -64,11 +63,12 @@
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% block wiki_contents %}{% endblock %}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
{% trans "Go back" %}
|
||||
</a>
|
||||
</div>
|
||||
{% include "wiki/includes/cheatsheet.html" %}
|
||||
</form>
|
||||
|
||||
</article>
|
||||
|
||||
@@ -40,7 +40,10 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% include "wiki/includes/cheatsheet.html" %}
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
56
lms/templates/wiki/includes/cheatsheet.html
Normal file
56
lms/templates/wiki/includes/cheatsheet.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<div class="modal hide fade" id="cheatsheetModal">
|
||||
<a href="#" class="close-btn">×</a>
|
||||
<div id="cheatsheet-body" class="modal-body">
|
||||
<div class="left-column">
|
||||
<section>
|
||||
<h2>Wiki Syntax Help</h2>
|
||||
<p>This wiki uses <strong>Markdown</strong> for styling. There are several useful guides online. See any of the links below for in-depth details:</p>
|
||||
<ul>
|
||||
<li><a href="http://daringfireball.net/projects/markdown/basics" target="_blank">Markdown: Basics</a></li>
|
||||
<li><a href="http://greg.vario.us/doc/markdown.txt" target="_blank">Quick Markdown Syntax Guide</a></li>
|
||||
<li><a href="http://www.lowendtalk.com/discussion/6/miniature-markdown-guide" target="_blank">Miniature Markdown Guide</a></li>
|
||||
</ul>
|
||||
<p>To create a new wiki article, create a link to it. Clicking the link gives you the creation page.</p>
|
||||
<pre>[Article Name](wiki:ArticleName)</pre>
|
||||
</section>
|
||||
<section>
|
||||
<h3>edX Additions:</h3>
|
||||
<pre>
|
||||
circuit-schematic:</pre>
|
||||
<pre>
|
||||
$LaTeX Math Expression$</pre>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div class="right-column">
|
||||
<section>
|
||||
<h3>Useful examples:</h3>
|
||||
<pre>
|
||||
http://wikipedia.org
|
||||
[Wikipedia](http://wikipedia.org)
|
||||
[edX Wiki](wiki:/edx/)</pre>
|
||||
<pre>
|
||||
Huge Header
|
||||
===========</pre>
|
||||
<pre>
|
||||
Smaller Header
|
||||
--------------</pre>
|
||||
<pre>
|
||||
*emphasis* or _emphasis_</pre>
|
||||
<pre>
|
||||
**strong** or __strong__</pre>
|
||||
<pre>
|
||||
- Unordered List
|
||||
- Sub Item 1
|
||||
- Sub Item 2</pre>
|
||||
<pre>
|
||||
1. Ordered
|
||||
2. List</pre>
|
||||
<pre>
|
||||
> Quotes</pre>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
4
lms/templates/wiki/includes/editor_widget.html
Normal file
4
lms/templates/wiki/includes/editor_widget.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<textarea {{ attrs }}>{{ content }}</textarea>
|
||||
<p id="hint_id_content" class="help-block">
|
||||
Markdown syntax is allowed. See the <a id="cheatsheetLink" href="#">cheatsheet</a> for help.
|
||||
</p>
|
||||
14
lms/wsgi.py
Normal file
14
lms/wsgi.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import os
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lms.envs.aws")
|
||||
|
||||
# This application object is used by the development server
|
||||
# as well as any WSGI server configured to use this file.
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
application = get_wsgi_application()
|
||||
|
||||
from django.conf import settings
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
for store_name in settings.MODULESTORE:
|
||||
modulestore(store_name)
|
||||
Reference in New Issue
Block a user