MA-212 Mobile API support for backward compatibility of course updates.

This commit is contained in:
Nimisha Asthagiri
2015-01-07 22:19:14 -05:00
parent ed2afa8aaf
commit 3498eeb1f6
4 changed files with 95 additions and 76 deletions

View File

@@ -16,14 +16,14 @@ import re
import logging
from django.http import HttpResponseBadRequest
import django.utils
from django.utils.translation import ugettext as _
from lxml import html, etree
from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.modulestore.django import modulestore
from xmodule.html_module import CourseInfoModule
from xmodule_modifiers import get_course_update_items
# # This should be in a class which inherits from XmlDescriptor
log = logging.getLogger(__name__)
@@ -38,7 +38,7 @@ def get_course_updates(location, provided_id, user_id):
except ItemNotFoundError:
course_updates = modulestore().create_item(user_id, location.course_key, location.block_type, location.block_id)
course_update_items = get_course_update_items(course_updates, provided_id)
course_update_items = get_course_update_items(course_updates, _get_index(provided_id))
return _get_visible_update(course_update_items)
@@ -82,19 +82,6 @@ def update_course_updates(location, update, passed_id=None, user=None):
return course_update_dict
def _course_info_content(html_parsed):
"""
Constructs the HTML for the course info update, not including the header.
"""
if len(html_parsed) == 1:
# could enforce that update[0].tag == 'h2'
content = html_parsed[0].tail
else:
content = html_parsed[0].tail if html_parsed[0].tail is not None else ""
content += "\n".join([html.tostring(ele) for ele in html_parsed[1:]])
return content
def _make_update_dict(update):
"""
Return course update item as a dictionary with required keys ('id', "date" and "content").
@@ -167,55 +154,6 @@ def _get_index(passed_id=None):
return 0
def get_course_update_items(course_updates, provided_id=None):
"""
Returns list of course_updates data dictionaries either from new format if available or
from old. This function don't modify old data to new data (in db), instead returns data
in common old dictionary format.
New Format: {"items" : [{"id": computed_id, "date": date, "content": html-string}],
"data": "<ol>[<li><h2>date</h2>content</li>]</ol>"}
Old Format: {"data": "<ol>[<li><h2>date</h2>content</li>]</ol>"}
"""
if course_updates and getattr(course_updates, "items", None):
provided_id = _get_index(provided_id)
if provided_id and 0 < provided_id <= len(course_updates.items):
return course_updates.items[provided_id - 1]
# return list in reversed order (old format: [4,3,2,1]) for compatibility
return list(reversed(course_updates.items))
else:
# old method to get course updates
# purely to handle free formed updates not done via editor. Actually kills them, but at least doesn't break.
try:
course_html_parsed = html.fromstring(course_updates.data)
except (etree.XMLSyntaxError, etree.ParserError):
log.error("Cannot parse: " + course_updates.data)
escaped = django.utils.html.escape(course_updates.data)
course_html_parsed = html.fromstring("<ol><li>" + escaped + "</li></ol>")
# confirm that root is <ol>, iterate over <li>, pull out <h2> subs and then rest of val
course_update_items = []
provided_id = _get_index(provided_id)
if course_html_parsed.tag == 'ol':
# 0 is the newest
for index, update in enumerate(course_html_parsed):
if len(update) > 0:
content = _course_info_content(update)
# make the id on the client be 1..len w/ 1 being the oldest and len being the newest
computed_id = len(course_html_parsed) - index
payload = {
"id": computed_id,
"date": update.findtext("h2"),
"content": content
}
if provided_id == 0:
course_update_items.append(payload)
elif provided_id == computed_id:
return payload
return course_update_items
def _get_html(course_updates_items):
"""
Method to create course_updates_html from course_updates items