From 1dad5caef9c956453e93cbc075a7b5fde7408065 Mon Sep 17 00:00:00 2001 From: Piotr Mitros Date: Tue, 20 Dec 2011 19:43:53 -0500 Subject: [PATCH] Basic support for per-user courseware in place --- auth/models.py | 2 +- courseware/capa_module.py | 1 - courseware/content_parser.py | 15 +++++++---- courseware/module_render.py | 2 +- courseware/profile.py | 48 ------------------------------------ courseware/views.py | 7 +++--- 6 files changed, 16 insertions(+), 59 deletions(-) delete mode 100644 courseware/profile.py diff --git a/auth/models.py b/auth/models.py index b79c3519b4..1a7bf6c221 100644 --- a/auth/models.py +++ b/auth/models.py @@ -11,7 +11,7 @@ class UserProfile(models.Model): language = models.TextField(blank=True) location = models.TextField(blank=True) meta = models.TextField(blank=True) # JSON dictionary for future expansion - courseware = models.TextField(blank=True, default='courseware.xml') + courseware = models.TextField(blank=True, default='course.xml') class Registration(models.Model): ''' Allows us to wait for e-mail before user is registered. A diff --git a/courseware/capa_module.py b/courseware/capa_module.py index 14119bdd22..72efae286a 100644 --- a/courseware/capa_module.py +++ b/courseware/capa_module.py @@ -9,7 +9,6 @@ from capa_problem import LoncapaProblem import dateutil import datetime - from xml.dom.minidom import parse, parseString ## TODO: Abstract out from Django diff --git a/courseware/content_parser.py b/courseware/content_parser.py index c5ecf63909..284869bbaa 100644 --- a/courseware/content_parser.py +++ b/courseware/content_parser.py @@ -1,6 +1,7 @@ from django.conf import settings from xml.dom.minidom import parse, parseString import libxml2 +from auth.models import UserProfile ''' This file will eventually form an abstraction layer between the course XML file and the rest of the system. @@ -8,10 +9,14 @@ course XML file and the rest of the system. TODO: Shift everything from xml.dom.minidom to XPath (or XQuery) ''' -def module_xml(module, id_tag, module_id): +def course_file(user): + # TODO: Cache. Also, return the libxml2 object. + return settings.DATA_DIR+UserProfile.objects.get(user=user).courseware + +def module_xml(coursefile, module, id_tag, module_id): ''' Get XML for a module based on module and module_id. Assumes - module occurs once in course.xml. ''' - doc = libxml2.parseFile(settings.DATA_DIR+'course.xml') + module occurs once in courseware XML file.. ''' + doc = libxml2.parseFile(coursefile) # Sanitize input if not module.isalnum(): @@ -28,8 +33,8 @@ def module_xml(module, id_tag, module_id): return None return result_set[0].serialize() -def toc_from_xml(active_chapter,active_section): - dom=parse(settings.DATA_DIR+'course.xml') +def toc_from_xml(coursefile, active_chapter, active_section): + dom=parse(coursefile) course = dom.getElementsByTagName('course')[0] name=course.getAttribute("name") diff --git a/courseware/module_render.py b/courseware/module_render.py index 7f6ca5239f..42870bbe09 100644 --- a/courseware/module_render.py +++ b/courseware/module_render.py @@ -142,7 +142,7 @@ def modx_dispatch(request, module=None, dispatch=None, id=None): #print "X",s.xml, "Y",content_parser.module_xml(module, id_tag, id) print - xml = content_parser.module_xml(module, id_tag, id) + xml = content_parser.module_xml(content_parser.course_file(request.user), module, id_tag, id) instance=modx_modules[module](xml, s.module_id, diff --git a/courseware/profile.py b/courseware/profile.py deleted file mode 100644 index 6f7cb1ede7..0000000000 --- a/courseware/profile.py +++ /dev/null @@ -1,48 +0,0 @@ -def profile(request): - ''' User profile. Show username, location, etc, as well as grades . - We need to allow the user to change some of these settings .''' - if not request.user.is_authenticated(): - return redirect('/') - - dom=parse(settings.DATA_DIR+'course.xml') - hw=[] - course = dom.getElementsByTagName('course')[0] - chapters = course.getElementsByTagName('chapter') - - responses=StudentModule.objects.filter(student=request.user) - - for c in chapters: - for s in c.getElementsByTagName('section'): - problems=s.getElementsByTagName('problem') - scores=[] - if len(problems)>0: - for p in problems: - id = p.getAttribute('filename') - correct = 0 - for response in responses: - if response.module_id == id: - if response.grade!=None: - correct=response.grade - else: - correct=0 - total=capa_module.LoncapaModule(p.toxml(), "id").max_score() # TODO: Add state. Not useful now, but maybe someday problems will have randomized max scores? - scores.append((int(correct),total)) - score={'course':course.getAttribute('name'), - 'section':s.getAttribute("name"), - 'chapter':c.getAttribute("name"), - 'scores':scores, - } - hw.append(score) - - user_info=UserProfile.objects.get(user=request.user) - - context={'name':user_info.name, - 'username':request.user.username, - 'location':user_info.location, - 'language':user_info.language, - 'email':request.user.email, - 'homeworks':hw, - 'csrf':csrf(request)['csrf_token'] - } - return render_to_response('profile.html', context) - diff --git a/courseware/views.py b/courseware/views.py index 09ad29e39b..5a8f88a5dc 100644 --- a/courseware/views.py +++ b/courseware/views.py @@ -39,7 +39,7 @@ def profile(request): if not request.user.is_authenticated(): return redirect('/') - dom=parse(settings.DATA_DIR+'course.xml') + dom=parse(content_parser.course_file(request.user)) hw=[] course = dom.getElementsByTagName('course')[0] chapters = course.getElementsByTagName('chapter') @@ -87,7 +87,7 @@ def render_accordion(request,course,chapter,section): def format_string(string): return urllib.quote(string.replace(' ','_')) - toc=content_parser.toc_from_xml(chapter, section) + toc=content_parser.toc_from_xml(content_parser.course_file(request.user), chapter, section) active_chapter=1 for i in range(len(toc)): if toc[i]['active']: @@ -117,7 +117,8 @@ def index(request, course="6.002 Spring 2012", chapter="Using the System", secti if course!="6.002 Spring 2012": return redirect('/') - dom=parse(settings.DATA_DIR+'course.xml') + cf = content_parser.course_file(request.user) + dom=parse(cf) dom_course=content_parser.dom_select(dom, 'course', course) dom_chapter=content_parser.dom_select(dom_course, 'chapter', chapter) dom_section=content_parser.dom_select(dom_chapter, 'section', section)