Commit f4b37b28 by Calen Pennington

Merge pull request #1060 from cpennington/lazy-textbooks

Make Textbooks properly lazy
parents 7bd54546 ad2da44c
...@@ -6,10 +6,10 @@ from path import path # NOTE (THK): Only used for detecting presence of syllabu ...@@ -6,10 +6,10 @@ from path import path # NOTE (THK): Only used for detecting presence of syllabu
import requests import requests
from datetime import datetime from datetime import datetime
import dateutil.parser import dateutil.parser
from lazy import lazy
from xmodule.modulestore import Location from xmodule.modulestore import Location
from xmodule.seq_module import SequenceDescriptor, SequenceModule from xmodule.seq_module import SequenceDescriptor, SequenceModule
from xmodule.util.decorators import lazyproperty
from xmodule.graders import grader_from_conf from xmodule.graders import grader_from_conf
import json import json
...@@ -62,17 +62,22 @@ class Textbook(object): ...@@ -62,17 +62,22 @@ class Textbook(object):
def __init__(self, title, book_url): def __init__(self, title, book_url):
self.title = title self.title = title
self.book_url = book_url self.book_url = book_url
self.start_page = int(self.table_of_contents[0].attrib['page'])
@lazy
def start_page(self):
return int(self.table_of_contents[0].attrib['page'])
@lazy
def end_page(self):
# The last page should be the last element in the table of contents, # The last page should be the last element in the table of contents,
# but it may be nested. So recurse all the way down the last element # but it may be nested. So recurse all the way down the last element
last_el = self.table_of_contents[-1] last_el = self.table_of_contents[-1]
while last_el.getchildren(): while last_el.getchildren():
last_el = last_el[-1] last_el = last_el[-1]
self.end_page = int(last_el.attrib['page']) return int(last_el.attrib['page'])
@lazyproperty @lazy
def table_of_contents(self): def table_of_contents(self):
""" """
Accesses the textbook's table of contents (default name "toc.xml") at the URL self.book_url Accesses the textbook's table of contents (default name "toc.xml") at the URL self.book_url
...@@ -738,7 +743,7 @@ class CourseDescriptor(CourseFields, SequenceDescriptor): ...@@ -738,7 +743,7 @@ class CourseDescriptor(CourseFields, SequenceDescriptor):
return announcement, start, now return announcement, start, now
@lazyproperty @lazy
def grading_context(self): def grading_context(self):
""" """
This returns a dictionary with keys necessary for quickly grading This returns a dictionary with keys necessary for quickly grading
......
def lazyproperty(fn):
"""
Use this decorator for lazy generation of properties that
are expensive to compute. From http://stackoverflow.com/a/3013910/86828
Example:
class Test(object):
@lazyproperty
def a(self):
print 'generating "a"'
return range(5)
Interactive Session:
>>> t = Test()
>>> t.__dict__
{}
>>> t.a
generating "a"
[0, 1, 2, 3, 4]
>>> t.__dict__
{'_lazy_a': [0, 1, 2, 3, 4]}
>>> t.a
[0, 1, 2, 3, 4]
"""
attr_name = '_lazy_' + fn.__name__
@property
def _lazyprop(self):
if not hasattr(self, attr_name):
setattr(self, attr_name, fn(self))
return getattr(self, attr_name)
return _lazyprop
...@@ -34,6 +34,7 @@ feedparser==5.1.3 ...@@ -34,6 +34,7 @@ feedparser==5.1.3
fs==0.4.0 fs==0.4.0
GitPython==0.3.2.RC1 GitPython==0.3.2.RC1
glob2==0.3 glob2==0.3
lazy==1.1
lxml==3.0.1 lxml==3.0.1
mako==0.7.3 mako==0.7.3
Markdown==2.2.1 Markdown==2.2.1
......
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