Commit 237e6ff6 by Vasyl Nakvasiuk

merge

parents 93000af7 d55b818b
......@@ -27,10 +27,12 @@ from xmodule.contentstore.django import contentstore
from xmodule.templates import update_templates
from xmodule.modulestore.xml_exporter import export_to_xml
from xmodule.modulestore.xml_importer import import_from_xml
from xmodule.templates import update_templates
from xmodule.capa_module import CapaDescriptor
from xmodule.course_module import CourseDescriptor
from xmodule.seq_module import SequenceDescriptor
from xmodule.modulestore.exceptions import ItemNotFoundError
TEST_DATA_MODULESTORE = copy.deepcopy(settings.MODULESTORE)
TEST_DATA_MODULESTORE['default']['OPTIONS']['fs_root'] = path('common/test/data')
......@@ -409,3 +411,32 @@ class ContentStoreTest(ModuleStoreTestCase):
self.assertIn('markdown', context, "markdown is missing from context")
self.assertIn('markdown', problem.metadata, "markdown is missing from metadata")
self.assertNotIn('markdown', problem.editable_metadata_fields, "Markdown slipped into the editable metadata fields")
class TemplateTestCase(ModuleStoreTestCase):
def test_template_cleanup(self):
ms = modulestore('direct')
# insert a bogus template in the store
bogus_template_location = Location('i4x', 'edx', 'templates', 'html', 'bogus')
source_template_location = Location('i4x', 'edx', 'templates', 'html', 'Empty')
ms.clone_item(source_template_location, bogus_template_location)
verify_create = ms.get_item(bogus_template_location)
self.assertIsNotNone(verify_create)
# now run cleanup
update_templates()
# now try to find dangling template, it should not be in DB any longer
asserted = False
try:
verify_create = ms.get_item(bogus_template_location)
except ItemNotFoundError:
asserted = True
self.assertTrue(asserted)
......@@ -85,7 +85,6 @@ class ContentStoreTestCase(ModuleStoreTestCase):
# Now make sure that the user is now actually activated
self.assertTrue(user(email).is_active)
class AuthTestCase(ContentStoreTestCase):
"""Check that various permissions-related things work"""
......
......@@ -56,6 +56,10 @@ def update_templates():
available from the installed plugins
"""
# cdodge: build up a list of all existing templates. This will be used to determine which
# templates have been removed from disk - and thus we need to remove from the DB
templates_to_delete = modulestore('direct').get_items(['i4x', 'edx', 'templates', None, None, None])
for category, templates in all_templates().items():
for template in templates:
if 'display_name' not in template.metadata:
......@@ -85,3 +89,12 @@ def update_templates():
modulestore('direct').update_item(template_location, template.data)
modulestore('direct').update_children(template_location, template.children)
modulestore('direct').update_metadata(template_location, template.metadata)
# remove template from list of templates to delete
templates_to_delete = [t for t in templates_to_delete if t.location != template_location]
# now remove all templates which appear to have removed from disk
if len(templates_to_delete) > 0:
logging.debug('deleting dangling templates = {0}'.format(templates_to_delete))
for template in templates_to_delete:
modulestore('direct').delete_item(template.location)
......@@ -69,10 +69,10 @@ class VideoAlphaModule(XModule):
if 'position' in state:
self.position = int(float(state['position']))
def _get_source(self, xmltree, ext=None):
"""Find the first valid source, which ends with one of `ext`."""
ext = ['mp4', 'ogv', 'avi', 'webm'] if ext is None else ext
condition = lambda src: any([src.endswith(ext) for ext in ext])
def _get_source(self, xmltree, exts=None):
"""Find the first valid source, which ends with one of `exts`."""
exts = ['mp4', 'ogv', 'avi', 'webm'] if exts is None else exts
condition = lambda src: any([src.endswith(ext) for ext in exts])
return self._get_first_external(xmltree, 'source', condition)
def _get_track(self, xmltree):
......
......@@ -200,7 +200,6 @@ COURSE_TITLE = "Circuits and Electronics"
### Dark code. Should be enabled in local settings for devel.
ENABLE_MULTICOURSE = False # set to False to disable multicourse display (see lib.util.views.mitxhome)
QUICKEDIT = False
WIKI_ENABLED = False
......
......@@ -34,7 +34,6 @@ EDX4EDX_ROOT = ENV_ROOT / "data/edx4edx"
DEBUG = True
ENABLE_MULTICOURSE = True # set to False to disable multicourse display (see lib.util.views.mitxhome)
QUICKEDIT = True
MAKO_TEMPLATES['course'] = [DATA_DIR, EDX4EDX_ROOT]
......
......@@ -6,7 +6,6 @@ COURSE_TITLE = "edx4edx: edX Author Course"
EDX4EDX_ROOT = ENV_ROOT / "data/edx4edx"
### Dark code. Should be enabled in local settings for devel.
QUICKEDIT = True
ENABLE_MULTICOURSE = True # set to False to disable multicourse display (see lib.util.views.mitxhome)
###
PIPELINE_CSS_COMPRESSOR = None
......
This is a library for edx4edx, allowing users to practice writing problems.
#!/usr/bin/python
from random import choice
import string
import traceback
from django.conf import settings
import capa.capa_problem as lcp
from dogfood.views import update_problem
def GenID(length=8, chars=string.letters + string.digits):
return ''.join([choice(chars) for i in range(length)])
randomid = GenID()
def check_problem_code(ans, the_lcp, correct_answers, false_answers):
"""
ans = student's answer
the_lcp = LoncapaProblem instance
returns dict {'ok':is_ok,'msg': message with iframe}
"""
pfn = "dog%s" % randomid
pfn += the_lcp.problem_id.replace('filename', '') # add problem ID to dogfood problem name
update_problem(pfn, ans, filestore=the_lcp.system.filestore)
msg = '<hr width="100%"/>'
msg += '<iframe src="%s/dogfood/filename%s" width="95%%" height="400" frameborder="1">No iframe support!</iframe>' % (settings.MITX_ROOT_URL, pfn)
msg += '<hr width="100%"/>'
endmsg = """<p><font size="-1" color="purple">Note: if the code text box disappears after clicking on "Check",
please type something in the box to make it refresh properly. This is a
bug with Chrome; it does not happen with Firefox. It is being fixed.
</font></p>"""
is_ok = True
if (not correct_answers) or (not false_answers):
ret = {'ok': is_ok,
'msg': msg + endmsg,
}
return ret
try:
# check correctness
fp = the_lcp.system.filestore.open('problems/%s.xml' % pfn)
test_lcp = lcp.LoncapaProblem(fp, '1', system=the_lcp.system)
if not (test_lcp.grade_answers(correct_answers).get_correctness('1_2_1') == 'correct'):
is_ok = False
if (test_lcp.grade_answers(false_answers).get_correctness('1_2_1') == 'correct'):
is_ok = False
except Exception, err:
is_ok = False
msg += "<p>Error: %s</p>" % str(err).replace('<', '&#60;')
msg += "<p><pre>%s</pre></p>" % traceback.format_exc().replace('<', '&#60;')
ret = {'ok': is_ok,
'msg': msg + endmsg,
}
return ret
......@@ -32,7 +32,7 @@
<!-- TODO: http://docs.jquery.com/Plugins/Validation -->
<script type="text/javascript">
document.write('\x3Cscript type="text/javascript" src="' +
document.location.protocol + '//www.youtube.com/player_api">\x3C/script>');
document.location.protocol + '//www.youtube.com/iframe_api">\x3C/script>');
</script>
<script type="text/javascript">
......@@ -61,7 +61,7 @@
</script>
% if timer_expiration_duration:
<script type="text/javascript">
<script type="text/javascript">
var timer = {
timer_inst : null,
end_time : null,
......@@ -79,8 +79,8 @@
remaining_secs = remaining_secs % 3600;
var minutes = pretty_time_string(Math.floor(remaining_secs / 60));
remaining_secs = remaining_secs % 60;
var seconds = pretty_time_string(Math.floor(remaining_secs));
var seconds = pretty_time_string(Math.floor(remaining_secs));
var remainingTimeString = hours + ":" + minutes + ":" + seconds;
return remainingTimeString;
},
......@@ -100,11 +100,11 @@
end : function(self) {
clearInterval(self.timer_inst);
// redirect to specified URL:
window.location = "${time_expired_redirect_url}";
window.location = "${time_expired_redirect_url}";
}
}
// start timer right away:
timer.start();
}
// start timer right away:
timer.start();
</script>
% endif
......
<%namespace name='static' file='static_content.html'/>
<!DOCTYPE html>
<html>
## -----------------------------------------------------------------------------
## Template for lib.dogfood.views.dj_capa_problem
##
## Used for viewing assesment problems in "dogfood" self-evaluation mode
## -----------------------------------------------------------------------------
<head>
<link rel="stylesheet" href="${static.url('css/vendor/jquery.treeview.css')}" type="text/css" media="all" />
## <link rel="stylesheet" href="${ settings.LIB_URL }jquery.treeview.css" type="text/css" media="all" />
## <link rel="stylesheet" href="/static/sass/application.css" type="text/css" media="all" / >
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
## <%static:css group='application'/>
% endif
% if not settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
## <link rel="stylesheet" href="/static/sass/application.css" type="text/css" media="all" / >
% endif
<script type="text/javascript" src="${static.url('js/jquery.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery-ui.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/swfobject/swfobject.js')}"></script>
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
<%static:js group='application'/>
% endif
% if not settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
% for jsfn in [ '/static/%s' % x.replace('.coffee','.js') for x in settings.PIPELINE_JS['application']['source_filenames'] ]:
<script type="text/javascript" src="${jsfn}"></script>
% endfor
% endif
## codemirror
<link rel="stylesheet" href="/static/css/codemirror.css" type="text/css" media="all" />
<script type="text/javascript" src="${ settings.LIB_URL }codemirror-compressed.js"></script>
## alternate codemirror
## <script type="text/javascript" src="/static/js/CodeMirror-2.25/lib/codemirror.js"></script>
## <script type="text/javascript" src="/static/js/CodeMirror-2.25/mode/xml/xml.js"></script>
## <script type="text/javascript" src="/static/js/CodeMirror-2.25/mode/python/python.js"></script>
## image input: for clicking on images (see imageinput.html)
<script type="text/javascript" src="/static/js/imageinput.js"></script>
<%include file="mathjax_include.html" />
</head>
<body class="courseware">
<!--[if lt IE 9]>
<script src="/static/js/html5shiv.js"></script>
<![endif]-->
<div class="courseware"></div>
## -----------------------------------------------------------------------------
## information
## <hr width="100%">
## <h2>Rendition of your problem code</h2>
## <hr width="100%">
## -----------------------------------------------------------------------------
## rendered problem display
<script>
${init_js}
</script>
<style type="text/css">
.problem-header {display:none;}
.staff {display:none;}
.correct { display: -moz-inline-box;
-moz-box-orient: vertical;
display: inline-block;
vertical-align: baseline;
zoom: 1;
*display: inline;
*vertical-align: auto;
background: url("/static/images/correct-icon.png") center center no-repeat;
height: 20px;
position: relative;
top: 6px;
width: 25px; }
.incorrect{
display: -moz-inline-box;
-moz-box-orient: vertical;
display: inline-block;
vertical-align: baseline;
zoom: 1;
*display: inline;
*vertical-align: auto;
background: url("/static/images/incorrect-icon.png") center center no-repeat;
height: 20px;
width: 20px;
position: relative;
top: 6px; }
.unanswered {
display: -moz-inline-box;
-moz-box-orient: vertical;
display: inline-block;
vertical-align: baseline;
zoom: 1;
*display: inline;
*vertical-align: auto;
background: url("/static/images/unanswered-icon.png") center center no-repeat;
height: 14px;
position: relative;
top: 4px;
width: 14px; }
}
</style>
<meta name="path_prefix" content="${MITX_ROOT_URL}">
<section class="course-content">
<form>
${phtml}
</form>
</section>
<script type="text/javascript" src="${static.url('js/jquery.treeview.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.leanModal.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/jquery.qtip.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.cookie.js')}"></script>
## <script type="text/javascript" src="${static.url('js/video_player.js')}"></script>
<script type="text/javascript" src="${static.url('js/schematic.js')}"></script>
<script type="text/javascript" src="${static.url('js/cktsim.js')}"></script>
## image input: for clicking on images (see imageinput.html)
<script type="text/javascript" src="/static/js/imageinput.js"></script>
<script type="text/javascript" >
var codemirror_set= {}; // associative array of codemirror objects
</script>
<%block name="js_extra"/>
</body>
</html>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html> <head>
<title>edX gitupdate</title>
</head>
<body>
<hr>
<h1>edX gitupdate</h1>
<hr>
<h2>Coursename: ${coursename}</h2>
% if msg:
${msg}
% else:
<p>
Do you REALLY want to overwrite all the course.xml + problems + html
files with version from the main git repository?
</p>
<form method="post">
<input type="submit" value="Do git update" name="gitupdate" />
## <input type="submit" value="Cancel" name="cancel" />
<input type="hidden" name="csrfmiddlewaretoken" value="${csrf}"/>
</form>
% endif
<p><a href="${MITX_ROOT_URL}/courseware/">Return to site</a></p>
</body> </html>
<%namespace name='static' file='static_content.html'/>
<!DOCTYPE html>
<html>
## -----------------------------------------------------------------------------
## Template for courseware.views.quickedit
##
## Used for quick-edit link present when viewing capa-format assesment problems.
## -----------------------------------------------------------------------------
<head>
<link rel="stylesheet" href="${static.url('css/vendor/jquery.treeview.css')}" type="text/css" media="all" />
## <link rel="stylesheet" href="${ settings.LIB_URL }jquery.treeview.css" type="text/css" media="all" />
## <link rel="stylesheet" href="/static/sass/application.css" type="text/css" media="all" / >
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
<%static:css group='application'/>
% endif
% if not settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
## <link rel="stylesheet" href="/static/sass/application.css" type="text/css" media="all" / >
% endif
<script type="text/javascript" src="${static.url('js/jquery.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery-ui.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/swfobject/swfobject.js')}"></script>
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
<%static:js group='application'/>
% endif
% if not settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
% for jsfn in [ '/static/%s' % x.replace('.coffee','.js') for x in settings.PIPELINE_JS['application']['source_filenames'] ]:
<script type="text/javascript" src="${jsfn}"></script>
% endfor
% endif
## codemirror
<link rel="stylesheet" href="/static/css/codemirror.css" type="text/css" media="all" />
<script type="text/javascript" src="${ settings.LIB_URL }codemirror-compressed.js"></script>
## alternate codemirror
## <script type="text/javascript" src="/static/js/CodeMirror-2.25/lib/codemirror.js"></script>
## <script type="text/javascript" src="/static/js/CodeMirror-2.25/mode/xml/xml.js"></script>
## <script type="text/javascript" src="/static/js/CodeMirror-2.25/mode/python/python.js"></script>
## image input: for clicking on images (see imageinput.html)
<script type="text/javascript" src="/static/js/imageinput.js"></script>
## <script type="text/javascript">
## var codemirror_set = {}; // track all codemirror textareas, so they can be refreshed on page changes
## </script>
<!--[if lt IE 9]>
<script src="${static.url('js/html5shiv.js')}"></script>
<![endif]-->
<%block name="headextra"/>
<!-- This must appear after all mathjax-config blocks, so it is after the imports from the other templates.
It can't be run through static.url because MathJax uses crazy url introspection to do lazy loading of
MathJax extension libraries -->
<%include file="mathjax_include.html" />
</head>
<body class="courseware" style="text-align:left;" >
<style type="text/css">
.CodeMirror {border-style: solid;
border-width: 1px;}
.CodeMirror-scroll {
height: 500;
width: 100%
}
</style>
## -----------------------------------------------------------------------------
## information and i4x PSL code
<hr width="100%">
<h2>QuickEdit</h2>
<hr width="100%">
<ul>
<li>File = ${filename}</li>
<li>ID = ${id}</li>
</ul>
<form method="post">
<textarea rows="40" cols="160" name="quickedit_${id}" id="quickedit_${id}">${pxmls|h}</textarea>
<br/>
<input type="submit" value="Change Problem" name="qesubmit" />
<input type="submit" value="Revert to original" name="qesubmit" />
<input type="hidden" name="csrfmiddlewaretoken" value="${csrf}"/>
</form>
<span>${msg|n}</span>
## -----------------------------------------------------------------------------
## rendered problem display
<script>
// height: auto;
// overflow-y: hidden;
// overflow-x: auto;
$(function(){
var cm = CodeMirror.fromTextArea(document.getElementById("quickedit_${id}"),
{ 'mode': {name: "xml", alignCDATA: true},
lineNumbers: true
});
// $('.my-wymeditor').wymeditor();
});
</script>
<hr width="100%">
<script>
${init_js}
</script>
<style type="text/css">
.staff {display:none;}
.correct { display: -moz-inline-box;
-moz-box-orient: vertical;
display: inline-block;
vertical-align: baseline;
zoom: 1;
*display: inline;
*vertical-align: auto;
background: url("/static/images/correct-icon.png") center center no-repeat;
height: 20px;
position: relative;
top: 6px;
width: 25px; }
.incorrect{
display: -moz-inline-box;
-moz-box-orient: vertical;
display: inline-block;
vertical-align: baseline;
zoom: 1;
*display: inline;
*vertical-align: auto;
background: url("/static/images/incorrect-icon.png") center center no-repeat;
height: 20px;
width: 20px;
position: relative;
top: 6px; }
}
</style>
<meta name="path_prefix" content="${MITX_ROOT_URL}">
<section class="course-content">
<div id="seq_content">
<form>
${phtml}
</form>
</div>
</section>
<script type="text/javascript" src="${static.url('js/jquery.treeview.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.leanModal.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/jquery.qtip.min.js')}"></script>
<script type="text/javascript" src="${static.url('js/jquery.cookie.js')}"></script>
## <script type="text/javascript" src="${static.url('js/video_player.js')}"></script>
<script type="text/javascript" src="${static.url('js/schematic.js')}"></script>
<script type="text/javascript" src="${static.url('js/cktsim.js')}"></script>
<script type="text/javascript" >
var codemirror_set= {}; // associative array of codemirror objects
</script>
<script type="text/javascript" src="${static.url('js/jquery.scrollTo-1.4.2-min.js')}"></script>
<%block name="js_extra"/>
</body>
</html>
......@@ -320,10 +320,6 @@ if settings.COURSEWARE_ENABLED:
'courseware.views.static_tab', name="static_tab"),
)
if settings.QUICKEDIT:
urlpatterns += (url(r'^quickedit/(?P<id>[^/]*)$', 'dogfood.views.quickedit'),)
urlpatterns += (url(r'^dogfood/(?P<id>[^/]*)$', 'dogfood.views.df_capa_problem'),)
if settings.ENABLE_JASMINE:
urlpatterns += (url(r'^_jasmine/', include('django_jasmine.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