diff --git a/lms/envs/common.py b/lms/envs/common.py index f3bf223451..eb8c9989f0 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -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 diff --git a/lms/envs/dev_edx4edx.py b/lms/envs/dev_edx4edx.py index c138ed81ae..2ebd24e68b 100644 --- a/lms/envs/dev_edx4edx.py +++ b/lms/envs/dev_edx4edx.py @@ -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] diff --git a/lms/envs/edx4edx_aws.py b/lms/envs/edx4edx_aws.py index de377c0b57..b82048824f 100644 --- a/lms/envs/edx4edx_aws.py +++ b/lms/envs/edx4edx_aws.py @@ -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 diff --git a/lms/lib/dogfood/README.md b/lms/lib/dogfood/README.md deleted file mode 100644 index c6a7113049..0000000000 --- a/lms/lib/dogfood/README.md +++ /dev/null @@ -1 +0,0 @@ -This is a library for edx4edx, allowing users to practice writing problems. diff --git a/lms/lib/dogfood/__init__.py b/lms/lib/dogfood/__init__.py deleted file mode 100644 index d00d8ea793..0000000000 --- a/lms/lib/dogfood/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from check import * diff --git a/lms/lib/dogfood/check.py b/lms/lib/dogfood/check.py deleted file mode 100644 index 070d3f9262..0000000000 --- a/lms/lib/dogfood/check.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/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 = '
' - msg += '' % (settings.MITX_ROOT_URL, pfn) - msg += '
' - - endmsg = """

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. -

""" - - 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 += "

Error: %s

" % str(err).replace('<', '<') - msg += "

%s

" % traceback.format_exc().replace('<', '<') - - ret = {'ok': is_ok, - 'msg': msg + endmsg, - } - return ret diff --git a/lms/lib/dogfood/views.py b/lms/lib/dogfood/views.py deleted file mode 100644 index 6df881df98..0000000000 --- a/lms/lib/dogfood/views.py +++ /dev/null @@ -1,325 +0,0 @@ -''' -dogfood.py - -For using mitx / edX / i4x in checking itself. - -df_capa_problem: accepts an XML file for a problem, and renders it. -''' -import logging -import datetime -import re -import os # FIXME - use OSFS instead - -from fs.osfs import OSFS - -from django.conf import settings -from django.contrib.auth.models import User -from django.core.context_processors import csrf -from django.core.mail import send_mail -from django.http import Http404 -from django.http import HttpResponse -from django.shortcuts import redirect -from mitxmako.shortcuts import render_to_response, render_to_string - -import track.views -from lxml import etree - -from courseware.module_render import make_track_function, ModuleSystem, get_module -from courseware.models import StudentModule -from multicourse import multicourse_settings -from student.models import UserProfile -from util.cache import cache -from util.views import accepts - -import courseware.content_parser as content_parser -#import courseware.modules -import xmodule - -log = logging.getLogger("mitx.courseware") - -etree.set_default_parser(etree.XMLParser(dtd_validation=False, load_dtd=False, - remove_comments=True)) - -DOGFOOD_COURSENAME = 'edx_dogfood' # FIXME - should not be here; maybe in settings - - -def update_problem(pfn, pxml, coursename=None, overwrite=True, filestore=None): - ''' - update problem with filename pfn, and content (xml) pxml. - ''' - if not filestore: - if not coursename: coursename = DOGFOOD_COURSENAME - xp = multicourse_settings.get_course_xmlpath(coursename) # path to XML for the course - pfn2 = settings.DATA_DIR + xp + 'problems/%s.xml' % pfn - fp = open(pfn2, 'w') - else: - pfn2 = 'problems/%s.xml' % pfn - fp = filestore.open(pfn2, 'w') - log.debug('[dogfood.update_problem] pfn2=%s' % pfn2) - - if os.path.exists(pfn2) and not overwrite: return # don't overwrite if already exists and overwrite=False - pxmls = pxml if type(pxml) in [str, unicode] else etree.tostring(pxml, pretty_print=True) - fp.write(pxmls) - fp.close() - - -def df_capa_problem(request, id=None): - ''' - dogfood capa problem. - - Accepts XML for a problem, inserts it into the dogfood course.xml. - Returns rendered problem. - ''' - # "WARNING: UNDEPLOYABLE CODE. FOR DEV USE ONLY." - - if settings.DEBUG: - log.debug('[lib.dogfood.df_capa_problem] id=%s' % id) - - if not 'coursename' in request.session: - coursename = DOGFOOD_COURSENAME - else: - coursename = request.session['coursename'] - - xp = multicourse_settings.get_course_xmlpath(coursename) # path to XML for the course - - # Grab the XML corresponding to the request from course.xml - module = 'problem' - - try: - xml = content_parser.module_xml(request.user, module, 'id', id, coursename) - except Exception, err: - log.error("[lib.dogfood.df_capa_problem] error in calling content_parser: %s" % err) - xml = None - - # if problem of given ID does not exist, then create it - # do this only if course.xml has a section named "DogfoodProblems" - if not xml: - m = re.match('filename([A-Za-z0-9_]+)$', id) # extract problem filename from ID given - if not m: - raise Exception, '[lib.dogfood.df_capa_problem] Illegal problem id %s' % id - pfn = m.group(1) - log.debug('[lib.dogfood.df_capa_problem] creating new problem pfn=%s' % pfn) - - # add problem to course.xml - fn = settings.DATA_DIR + xp + 'course.xml' - xml = etree.parse(fn) - seq = xml.find('chapter/section[@name="DogfoodProblems"]/sequential') # assumes simplistic course.xml structure! - if seq == None: - raise Exception, "[lib.dogfood.views.df_capa_problem] missing DogfoodProblems section in course.xml!" - newprob = etree.Element('problem') - newprob.set('type', 'lecture') - newprob.set('showanswer', 'attempted') - newprob.set('rerandomize', 'never') - newprob.set('title', pfn) - newprob.set('filename', pfn) - newprob.set('name', pfn) - seq.append(newprob) - fp = open(fn, 'w') - fp.write(etree.tostring(xml, pretty_print=True)) # write new XML - fp.close() - - # now create new problem file - # update_problem(pfn,'\n\nThis is a new problem\n\n\n',coursename,overwrite=False) - - # reset cache entry - user = request.user - groups = content_parser.user_groups(user) - options = {'dev_content': settings.DEV_CONTENT, - 'groups': groups} - filename = xp + 'course.xml' - cache_key = filename + "_processed?dev_content:" + str(options['dev_content']) + "&groups:" + str(sorted(groups)) - log.debug('[lib.dogfood.df_capa_problem] cache_key = %s' % cache_key) - #cache.delete(cache_key) - tree = content_parser.course_xml_process(xml) # add ID tags - cache.set(cache_key, etree.tostring(tree), 60) - # settings.DEFAULT_GROUPS.append('dev') # force content_parser.course_file to not use cache - - xml = content_parser.module_xml(request.user, module, 'id', id, coursename) - if not xml: - log.debug("[lib.dogfood.df_capa_problem] problem xml not found!") - - # add problem ID to list so that is_staff check can be bypassed - request.session['dogfood_id'] = id - - # hand over to quickedit to do the rest - return quickedit(request, id=id, qetemplate='dogfood.html', coursename=coursename) - - -def quickedit(request, id=None, qetemplate='quickedit.html', coursename=None): - ''' - quick-edit capa problem. - - Maybe this should be moved into capa/views.py - Or this should take a "module" argument, and the quickedit moved into capa_module. - - id is passed in from url resolution - qetemplate is used by dogfood.views.dj_capa_problem, to override normal template - ''' - print "WARNING: UNDEPLOYABLE CODE. FOR DEV USE ONLY." - print "In deployed use, this will only edit on one server" - print "We need a setting to disable for production where there is" - print "a load balanacer" - - if not request.user.is_staff: - if not ('dogfood_id' in request.session and request.session['dogfood_id'] == id): - return redirect('/') - - if id == 'course.xml': - return quickedit_git_reload(request) - - # get coursename if stored - if not coursename: - coursename = multicourse_settings.get_coursename_from_request(request) - xp = multicourse_settings.get_course_xmlpath(coursename) # path to XML for the course - - def get_lcp(coursename, id): - # Grab the XML corresponding to the request from course.xml - # create empty student state for this problem, if not previously existing - s = StudentModule.objects.filter(student=request.user, - module_id=id) - student_module_cache = list(s) if s is not None else [] - #if len(s) == 0 or s is None: - # smod=StudentModule(student=request.user, - # module_type = 'problem', - # module_id=id, - # state=instance.get_state()) - # smod.save() - # student_module_cache = [smod] - module = 'problem' - module_xml = etree.XML(content_parser.module_xml(request.user, module, 'id', id, coursename)) - module_id = module_xml.get('id') - log.debug("module_id = %s" % module_id) - (instance, smod, module_type) = get_module(request.user, request, module_xml, student_module_cache, position=None) - log.debug('[dogfood.views] instance=%s' % instance) - lcp = instance.lcp - log.debug('[dogfood.views] lcp=%s' % lcp) - pxml = lcp.tree - pxmls = etree.tostring(pxml, pretty_print=True) - return instance, pxmls - - def old_get_lcp(coursename, id): - # Grab the XML corresponding to the request from course.xml - module = 'problem' - xml = content_parser.module_xml(request.user, module, 'id', id, coursename) - - ajax_url = settings.MITX_ROOT_URL + '/modx/' + id + '/' - - # Create the module (instance of capa_module.Module) - system = ModuleSystem(track_function=make_track_function(request), - render_function=None, - render_template=render_to_string, - ajax_url=ajax_url, - filestore=OSFS(settings.DATA_DIR + xp), - ) - instance = xmodule.get_module_class(module)(system, - xml, - id, - state=None) - log.info('ajax_url = ' + instance.ajax_url) - - # create empty student state for this problem, if not previously existing - s = StudentModule.objects.filter(student=request.user, - module_state_key=id) - if len(s) == 0 or s is None: - smod = StudentModule(student=request.user, - module_type='problem', - module_state_key=id, - state=instance.get_instance_state()) - smod.save() - - lcp = instance.lcp - pxml = lcp.tree - pxmls = etree.tostring(pxml, pretty_print=True) - - return instance, pxmls - - instance, pxmls = get_lcp(coursename, id) - - # if there was a POST, then process it - msg = '' - if 'qesubmit' in request.POST: - action = request.POST['qesubmit'] - if "Revert" in action: - msg = "Reverted to original" - elif action == 'Change Problem': - key = 'quickedit_%s' % id - if not key in request.POST: - msg = "oops, missing code key=%s" % key - else: - newcode = request.POST[key] - - # see if code changed - if str(newcode) == str(pxmls) or '\n' + str(newcode) == str(pxmls): - msg = "No changes" - else: - # check new code - isok = False - try: - newxml = etree.fromstring(newcode) - isok = True - except Exception, err: - msg = "Failed to change problem: XML error \"%s\"" % err - - if isok: - filename = instance.lcp.fileobject.name - fp = open(filename, 'w') # TODO - replace with filestore call? - fp.write(newcode) - fp.close() - msg = "Problem changed! (%s)" % filename - instance, pxmls = get_lcp(coursename, id) - - lcp = instance.lcp - - # get the rendered problem HTML - phtml = instance.get_html() - # phtml = instance.get_problem_html() - - context = {'id': id, - 'msg': msg, - 'lcp': lcp, - 'filename': lcp.fileobject.name, - 'pxmls': pxmls, - 'phtml': phtml, - "destroy_js": '', - 'init_js': '', - 'csrf': csrf(request)['csrf_token'], - } - - result = render_to_response(qetemplate, context) - return result - - -def quickedit_git_reload(request): - ''' - reload course.xml and all courseware files for this course, from the git repo. - assumes the git repo has already been setup. - staff only. - ''' - if not request.user.is_staff: - return redirect('/') - - # get coursename if stored - coursename = multicourse_settings.get_coursename_from_request(request) - xp = multicourse_settings.get_course_xmlpath(coursename) # path to XML for the course - - msg = "" - if 'cancel' in request.POST: - return redirect("/courseware") - - if 'gitupdate' in request.POST: - import os # FIXME - put at top? - #cmd = "cd ../data%s; git reset --hard HEAD; git pull origin %s" % (xp,xp.replace('/','')) - cmd = "cd ../data%s; ./GITRELOAD '%s'" % (xp, xp.replace('/', '')) - msg += '

cmd: %s

' % cmd - ret = os.popen(cmd).read() - msg += '

%s

' % ret.replace('<', '<') - msg += "

git update done!

" - - context = {'id': id, - 'msg': msg, - 'coursename': coursename, - 'csrf': csrf(request)['csrf_token'], - } - - result = render_to_response("gitupdate.html", context) - return result diff --git a/lms/templates/dogfood.html b/lms/templates/dogfood.html deleted file mode 100644 index 8460454f81..0000000000 --- a/lms/templates/dogfood.html +++ /dev/null @@ -1,144 +0,0 @@ -<%namespace name='static' file='static_content.html'/> - - -## ----------------------------------------------------------------------------- -## Template for lib.dogfood.views.dj_capa_problem -## -## Used for viewing assesment problems in "dogfood" self-evaluation mode -## ----------------------------------------------------------------------------- - - -## -## - -% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']: -## <%static:css group='application'/> -% endif - -% if not settings.MITX_FEATURES['USE_DJANGO_PIPELINE']: -## -% endif - - - - - -% 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'] ]: - - % endfor -% endif - -## codemirror - - - -## alternate codemirror -## -## -## - -## image input: for clicking on images (see imageinput.html) - - - -<%include file="mathjax_include.html" /> - - - - - - -
- -## ----------------------------------------------------------------------------- -## information - -##
-##

Rendition of your problem code

-##
- -## ----------------------------------------------------------------------------- -## rendered problem display - - - - - - - -
-
- ${phtml} -
-
- - - - - -## - - - -## image input: for clicking on images (see imageinput.html) - - - - - <%block name="js_extra"/> - - - diff --git a/lms/templates/gitupdate.html b/lms/templates/gitupdate.html deleted file mode 100644 index a0cedabeae..0000000000 --- a/lms/templates/gitupdate.html +++ /dev/null @@ -1,32 +0,0 @@ - - -edX gitupdate - - - -
-

edX gitupdate

-
- -

Coursename: ${coursename}

- -% if msg: - - ${msg} - -% else: -

-Do you REALLY want to overwrite all the course.xml + problems + html -files with version from the main git repository? -

- -
- -## - -
-% endif - -

Return to site

- - diff --git a/lms/templates/quickedit.html b/lms/templates/quickedit.html deleted file mode 100644 index bc8e74eb65..0000000000 --- a/lms/templates/quickedit.html +++ /dev/null @@ -1,180 +0,0 @@ -<%namespace name='static' file='static_content.html'/> - - -## ----------------------------------------------------------------------------- -## Template for courseware.views.quickedit -## -## Used for quick-edit link present when viewing capa-format assesment problems. -## ----------------------------------------------------------------------------- - - -## -## - -% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']: - <%static:css group='application'/> -% endif - -% if not settings.MITX_FEATURES['USE_DJANGO_PIPELINE']: -## -% endif - - - - - -% 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'] ]: - - % endfor -% endif - -## codemirror - - - -## alternate codemirror -## -## -## - -## image input: for clicking on images (see imageinput.html) - - -## - - - -<%block name="headextra"/> - - - <%include file="mathjax_include.html" /> - - - - - - - -## ----------------------------------------------------------------------------- -## information and i4x PSL code - -
-

QuickEdit

-
- - -
- -
- - - -
- -${msg|n} - -## ----------------------------------------------------------------------------- -## rendered problem display - - - -
- - - - - - - -
-
-
- ${phtml} -
-
-
- - - - - -## - - - - - - - - <%block name="js_extra"/> - - - diff --git a/lms/urls.py b/lms/urls.py index b25c4d259e..a203d468e7 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -320,10 +320,6 @@ if settings.COURSEWARE_ENABLED: 'courseware.views.static_tab', name="static_tab"), ) -if settings.QUICKEDIT: - urlpatterns += (url(r'^quickedit/(?P[^/]*)$', 'dogfood.views.quickedit'),) - urlpatterns += (url(r'^dogfood/(?P[^/]*)$', 'dogfood.views.df_capa_problem'),) - if settings.ENABLE_JASMINE: urlpatterns += (url(r'^_jasmine/', include('django_jasmine.urls')),)