Commit f0acda19 by Xavier Antoviaque

Merge pull request #46 from dragonfi/opaque-keys

Move to use opaque keys
parents eb76233b 7e54dd78
......@@ -31,7 +31,7 @@ from xblock.fragment import Fragment
from .light_children import LightChild, Boolean, Scope, String, Integer
from .models import Answer
from .utils import render_template
from .utils import render_template, serialize_opaque_key
# Globals ###########################################################
......@@ -137,11 +137,11 @@ class AnswerBlock(LightChild):
name = self.name
# Consistency check - we should have a name by now
if not name:
raise ValueError, 'AnswerBlock.name field need to be set to a non-null/empty value'
raise ValueError('AnswerBlock.name field need to be set to a non-null/empty value')
# TODO: Why do we need to use `xmodule_runtime` and not `runtime`?
student_id = self.xmodule_runtime.anonymous_student_id
course_id = self.xmodule_runtime.course_id
course_id = serialize_opaque_key(self.xmodule_runtime.course_id)
answer_data, created = Answer.objects.get_or_create(
student_id=student_id,
......
......@@ -31,7 +31,7 @@ from xblock.core import XBlock
from xblock.fragment import Fragment
from .models import Answer
from .utils import list2csv, render_template
from .utils import list2csv, render_template, serialize_opaque_key
# Globals ###########################################################
......@@ -70,7 +70,7 @@ class MentoringDataExportBlock(XBlock):
return response
def get_csv(self):
course_id = self.xmodule_runtime.course_id
course_id = serialize_opaque_key(self.xmodule_runtime.course_id)
answers = Answer.objects.filter(course_id=course_id).order_by('student_id', 'name')
answers_names = answers.values_list('name', flat=True).distinct().order_by('name')
......@@ -96,4 +96,3 @@ class MentoringDataExportBlock(XBlock):
if row:
yield list2csv(row)
......@@ -44,9 +44,9 @@ try:
from xmodule_modifiers import replace_jump_to_id_urls
except:
# TODO-WORKBENCH-WORKAROUND: To allow to load from the workbench
replace_jump_to_id_urls = lambda a,b,c,d,frag,f: frag
replace_jump_to_id_urls = lambda a, b, c, d, frag, f: frag
from .utils import XBlockWithChildrenFragmentsMixin
from .utils import serialize_opaque_key, XBlockWithChildrenFragmentsMixin
# Globals ###########################################################
......@@ -142,7 +142,7 @@ class LightChildrenMixin(XBlockWithChildrenFragmentsMixin):
frag = getattr(child, view_name)(context)
frag.content = u'<div class="xblock-light-child" name="{}" data-type="{}">{}</div>'.format(
child.name, child.__class__.__name__, frag.content)
child.name, child.__class__.__name__, frag.content)
return frag
def get_children_fragment(self, context, view_name='student_view', instance_of=None,
......@@ -188,7 +188,7 @@ class XBlockWithLightChildren(LightChildrenMixin, XBlock):
"""
# TODO: Why do we need to use `xmodule_runtime` and not `runtime`?
try:
course_id = self.xmodule_runtime.course_id
course_id = serialize_opaque_key(self.xmodule_runtime.course_id)
except AttributeError:
# TODO-WORKBENCH-WORKAROUND: To allow to load from the workbench
course_id = 'sample-course'
......@@ -298,10 +298,10 @@ class LightChild(Plugin, LightChildrenMixin):
name = self.name
if not name:
raise ValueError, 'LightChild.name field need to be set to a non-null/empty value'
raise ValueError('LightChild.name field need to be set to a non-null/empty value')
student_id = self.xmodule_runtime.anonymous_student_id
course_id = self.xmodule_runtime.course_id
course_id = serialize_opaque_key(self.xmodule_runtime.course_id)
url_name = "%s-%s" % (self.xblock_container.url_name, name)
lightchild_data, created = LightChildModel.objects.get_or_create(
......@@ -349,7 +349,7 @@ class Integer(LightChildField):
def __set__(self, instance, value):
try:
self.data[instance] = int(value)
except (TypeError, ValueError): # not an integer
except (TypeError, ValueError): # not an integer
self.data[instance] = 0
......
......@@ -47,6 +47,7 @@ def load_resource(resource_path):
resource_content = pkg_resources.resource_string(__name__, resource_path)
return unicode(resource_content)
def render_template(template_path, context={}):
"""
Evaluate a template by resource path, applying the provided context
......@@ -55,6 +56,7 @@ def render_template(template_path, context={}):
template = Template(template_str)
return template.render(Context(context))
def list2csv(row):
"""
Convert a list to a CSV string (single row)
......@@ -65,6 +67,7 @@ def list2csv(row):
f.seek(0)
return f.read()
def get_scenarios_from_path(scenarios_path, include_identifier=False):
"""
Returns an array of (title, xmlcontent) from files contained in a specified directory,
......@@ -88,6 +91,7 @@ def get_scenarios_from_path(scenarios_path, include_identifier=False):
return scenarios
def load_scenarios_from_path(scenarios_path):
"""
Load all xml files contained in a specified directory, as workbench scenarios
......@@ -95,6 +99,29 @@ def load_scenarios_from_path(scenarios_path):
return get_scenarios_from_path(scenarios_path, include_identifier=True)
def serialize_opaque_key(key):
"""
Gracefully handle opaque keys, both before and after the transition.
https://github.com/edx/edx-platform/wiki/Opaque-Keys
From https://github.com/edx/edx-ora2/pull/330
Currently uses `to_deprecated_string()` to ensure that new keys
are backwards-compatible with keys we store in ORA2 database models.
Args:
key (unicode or OpaqueKey subclass): The key to serialize.
Returns:
unicode
"""
if hasattr(key, 'to_deprecated_string'):
return key.to_deprecated_string()
else:
return unicode(key)
# Classes ###########################################################
class XBlockWithChildrenFragmentsMixin(object):
......
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