Last active
December 7, 2018 15:55
-
-
Save gsidebo/469d9d2089cf8258b6b1f8235d52c600 to your computer and use it in GitHub Desktop.
Helper functions for Open edX (to be run in an LMS Django shell)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from urlparse import urlparse, parse_qs | |
from collections import namedtuple | |
from django.core.urlresolvers import resolve | |
from django.contrib.auth.models import User | |
from courseware.model_data import FieldDataCache, DjangoKeyValueStore | |
from courseware.module_render import get_module_for_descriptor_internal | |
from courseware.courses import get_course_with_access, get_course_by_id | |
from opaque_keys.edx.keys import CourseKey, UsageKey | |
from opaque_keys.edx.locations import SlashSeparatedCourseKey | |
from xblock.runtime import KvsFieldData | |
from xmodule.modulestore.django import modulestore | |
VERTICAL_ID_QS_KEY = 'activate_block_id' | |
ProblemUrl = namedtuple('ProblemUrl', ['course', 'chapter', 'section', 'vertical']) | |
def get_block_descriptors(user, block_ids): | |
for block_id in block_ids: | |
usage_key = UsageKey.from_string(block_id) | |
simple_block_descriptor = modulestore().get_item(usage_key) | |
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course_key, user, simple_block_descriptor) | |
student_kvs = DjangoKeyValueStore(field_data_cache) | |
student_data = KvsFieldData(student_kvs) | |
yield get_module_for_descriptor_internal( | |
user, | |
descriptor=simple_block_descriptor, | |
student_data=student_data, | |
course_id=usage_key.course_key, | |
track_function=lambda: None, | |
xqueue_callback_url_prefix='', | |
request_token=None | |
) | |
def parse_problem_url(problem_url): | |
parsed_url = urlparse(problem_url) | |
qs_dict = parse_qs(parsed_url.query) | |
parsed_url = urlparse(problem_url) | |
relative_problem_url = parsed_url.path | |
if not relative_problem_url.startswith("/"): | |
relative_problem_url = "/{}".format(relative_problem_url) | |
resolved_url = resolve(relative_problem_url) | |
course_key = SlashSeparatedCourseKey.from_deprecated_string(resolved_url.kwargs['course_id']) | |
course = get_course_by_id(course_key) | |
chapter = next(c for c in course.get_children() if c.scope_ids.usage_id.block_id == resolved_url.kwargs['chapter']) | |
section = next(s for s in chapter.get_children() if s.scope_ids.usage_id.block_id == resolved_url.kwargs['section']) | |
vertical_usage_id_str = qs_dict['activate_block_id'][0] | |
vertical = next(v for v in section.get_children() if str(v.scope_ids.usage_id) == vertical_usage_id_str) | |
return ProblemUrl( | |
course=course, | |
chapter=chapter, | |
section=section, | |
vertical=vertical, | |
) | |
def get_problem_display_names(user, block_ids): | |
""" | |
Example usage: | |
get_problem_display_names( | |
User.objects.get(username='edx'), | |
[ | |
'block-v1:ODL+CS101+F2018+type@problem+block@d1c9cec328c8480aa0bcb03493b46262', | |
'block-v1:ODL+CS102+F2018+type@problem+block@d1c9cec328c8480aa0bcb03493b46263', | |
] | |
) | |
""" | |
return [ | |
block_descriptor.display_name | |
for block_descriptor in get_block_descriptors(user, block_ids) | |
] | |
def get_problem_answer_ids(user, block_id): | |
""" | |
Example usage: | |
get_problem_answer_ids( | |
User.objects.get(username='edx'), | |
'block-v1:ODL+CS101+F2018+type@problem+block@d1c9cec328c8480aa0bcb03493b46262' | |
) | |
""" | |
block_descriptor = next(get_block_descriptors(user, [block_id])) | |
tree = block_descriptor.lcp.tree | |
choicegroup_id = tree.xpath('//choicegroup')[0].get("id") | |
answer_ids = [choice.get("name") for choice in tree.xpath('//choicegroup/choice')] | |
return { | |
'choicegroup_id': choicegroup_id, | |
'answer_ids': answer_ids | |
} | |
def get_problem_block_id_from_url(problem_url, problem_display_name): | |
""" | |
Example usage: | |
get_problem_block_id_from_url( | |
'http://localhost:18000/courses/<course_id>/courseware/<chapter_id>/<section_id>/1?activate_block_id=<vertical_id>', | |
'Problem #3' | |
) | |
""" | |
parsed_problem_url = parse_problem_url(problem_url) | |
try: | |
problem = next(p for p in parsed_problem_url.vertical.get_children() if p.display_name == problem_display_name) | |
except StopIteration: | |
raise ValueError("No problem found with the given name ({})".format(problem_display_name)) | |
return str(problem.location) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment