Merge pull request #426 from MITx/feature/halogenandtoast/multiple_textbooks
Feature/halogenandtoast/multiple textbooks
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from fs.errors import ResourceNotFoundError
|
||||
import time
|
||||
import logging
|
||||
from lxml import etree
|
||||
|
||||
from xmodule.util.decorators import lazyproperty
|
||||
from xmodule.graders import load_grading_policy
|
||||
@@ -10,12 +11,28 @@ from xmodule.timeparse import parse_time, stringify_time
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CourseDescriptor(SequenceDescriptor):
|
||||
module_class = SequenceModule
|
||||
|
||||
class Textbook:
|
||||
def __init__(self, title, table_of_contents_url):
|
||||
self.title = title
|
||||
self.table_of_contents_url = table_of_contents_url
|
||||
|
||||
@classmethod
|
||||
def from_xml_object(cls, xml_object):
|
||||
return cls(xml_object.get('title'), xml_object.get('table_of_contents_url'))
|
||||
|
||||
@property
|
||||
def table_of_contents(self):
|
||||
raw_table_of_contents = open(self.table_of_contents_url, 'r') # TODO: This will need to come from S3
|
||||
table_of_contents = etree.parse(raw_table_of_contents).getroot()
|
||||
return table_of_contents
|
||||
|
||||
|
||||
def __init__(self, system, definition=None, **kwargs):
|
||||
super(CourseDescriptor, self).__init__(system, definition, **kwargs)
|
||||
self.textbooks = self.definition['data']['textbooks']
|
||||
|
||||
msg = None
|
||||
if self.start is None:
|
||||
@@ -28,6 +45,16 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
self.enrollment_start = self._try_parse_time("enrollment_start")
|
||||
self.enrollment_end = self._try_parse_time("enrollment_end")
|
||||
|
||||
@classmethod
|
||||
def definition_from_xml(cls, xml_object, system):
|
||||
textbooks = []
|
||||
for textbook in xml_object.findall("textbook"):
|
||||
textbooks.append(cls.Textbook.from_xml_object(textbook))
|
||||
xml_object.remove(textbook)
|
||||
definition = super(CourseDescriptor, cls).definition_from_xml(xml_object, system)
|
||||
definition.setdefault('data', {})['textbooks'] = textbooks
|
||||
return definition
|
||||
|
||||
def has_started(self):
|
||||
return time.gmtime() > self.start
|
||||
|
||||
@@ -53,7 +80,6 @@ class CourseDescriptor(SequenceDescriptor):
|
||||
|
||||
return grading_policy
|
||||
|
||||
|
||||
@lazyproperty
|
||||
def grading_context(self):
|
||||
"""
|
||||
|
||||
@@ -6,19 +6,17 @@ from courseware.courses import get_course_with_access
|
||||
from lxml import etree
|
||||
|
||||
@login_required
|
||||
def index(request, course_id, page=0):
|
||||
def index(request, course_id, book_index, page=0):
|
||||
course = get_course_with_access(request.user, course_id, 'load')
|
||||
staff_access = has_access(request.user, course, 'staff')
|
||||
|
||||
# TODO: This will need to come from S3
|
||||
raw_table_of_contents = open('lms/templates/book_toc.xml', 'r')
|
||||
table_of_contents = etree.parse(raw_table_of_contents).getroot()
|
||||
textbook = course.textbooks[int(book_index)]
|
||||
table_of_contents = textbook.table_of_contents
|
||||
|
||||
return render_to_response('staticbook.html',
|
||||
{'page': int(page), 'course': course,
|
||||
'table_of_contents': table_of_contents,
|
||||
'staff_access': staff_access})
|
||||
|
||||
|
||||
def index_shifted(request, course_id, page):
|
||||
return index(request, course_id=course_id, page=int(page) + 24)
|
||||
|
||||
@@ -21,8 +21,10 @@ def url_class(url):
|
||||
<li class="info"><a href="${reverse('info', args=[course.id])}" class="${url_class('info')}">Course Info</a></li>
|
||||
% if user.is_authenticated():
|
||||
% if settings.MITX_FEATURES.get('ENABLE_TEXTBOOK'):
|
||||
<li class="book"><a href="${reverse('book', args=[course.id])}" class="${url_class('book')}">Textbook</a></li>
|
||||
% endif
|
||||
% for index, textbook in enumerate(course.textbooks):
|
||||
<li class="book"><a href="${reverse('book', args=[course.id, index])}" class="${url_class('book')}">${textbook.title}</a></li>
|
||||
% endfor
|
||||
% endif
|
||||
% if settings.MITX_FEATURES.get('ENABLE_DISCUSSION'):
|
||||
<li class="discussion"><a href="${reverse('questions')}">Discussion</a></li>
|
||||
% endif
|
||||
|
||||
@@ -126,9 +126,9 @@ if settings.COURSEWARE_ENABLED:
|
||||
#Inside the course
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/info$',
|
||||
'courseware.views.course_info', name="info"),
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book$',
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book/(?P<book_index>[^/]*)/$',
|
||||
'staticbook.views.index', name="book"),
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book/(?P<page>[^/]*)$',
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book/(?P<book_index>[^/]*)/(?P<page>[^/]*)$',
|
||||
'staticbook.views.index'),
|
||||
url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/book-shifted/(?P<page>[^/]*)$',
|
||||
'staticbook.views.index_shifted'),
|
||||
|
||||
Reference in New Issue
Block a user