Skip to content

Instantly share code, notes, and snippets.

@gsidebo
Last active December 7, 2018 15:55
Show Gist options
  • Save gsidebo/469d9d2089cf8258b6b1f8235d52c600 to your computer and use it in GitHub Desktop.
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)
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