diff --git a/common/djangoapps/student/roles.py b/common/djangoapps/student/roles.py index 01252f742f..13b9b38a15 100644 --- a/common/djangoapps/student/roles.py +++ b/common/djangoapps/student/roles.py @@ -168,7 +168,7 @@ class CourseRole(GroupBasedRole): else: groupnames.append('{0}_{1}'.format(role, course_context)) try: - locator = loc_mapper().translate_location(course_context, self.location, True, True) + locator = loc_mapper().translate_location_to_course_locator(course_context, self.location) groupnames.append('{0}_{1}'.format(role, locator.package_id)) except (InvalidLocationError, ItemNotFoundError): # if it's never been mapped, the auth won't be via the Locator syntax diff --git a/common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py b/common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py index 5a37c260f7..d05810b473 100644 --- a/common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py +++ b/common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py @@ -7,7 +7,7 @@ import pymongo import bson.son from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError -from xmodule.modulestore.locator import BlockUsageLocator +from xmodule.modulestore.locator import BlockUsageLocator, CourseLocator from xmodule.modulestore import Location import urllib @@ -249,6 +249,37 @@ class LocMapperStore(object): return result return None + def translate_location_to_course_locator(self, old_style_course_id, location, published=True): + """ + Used when you only need the CourseLocator and not a full BlockUsageLocator. Probably only + useful for get_items which wildcards name or category. + + :param course_id: old style course id + """ + # doesn't use caching as cache requires full location w/o wildcards + location_id = self._interpret_location_course_id(old_style_course_id, location) + if old_style_course_id is None: + old_style_course_id = self._generate_location_course_id(location_id) + + maps = self.location_map.find(location_id) + maps = list(maps) + if len(maps) == 0: + raise ItemNotFoundError() + elif len(maps) == 1: + entry = maps[0] + else: + # find entry w/o name, if any; otherwise, pick arbitrary + entry = maps[0] + for item in maps: + if 'name' not in item['_id']: + entry = item + break + if published: + branch = entry['prod_branch'] + else: + branch = entry['draft_branch'] + return CourseLocator(package_id=entry['course_id'], branch=branch) + def _add_to_block_map(self, location, location_id, block_map): '''add the given location to the block_map and persist it''' if self._block_id_is_guid(location.name): diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py b/common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py index dee30ba491..73fa287b4c 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_location_mapper.py @@ -89,6 +89,14 @@ class TestLocationMapper(unittest.TestCase): self.assertEqual(prob_locator.block_id, block_id) self.assertEqual(prob_locator.branch, branch) + course_locator = loc_mapper().translate_location_to_course_locator( + old_style_course_id, + location, + published=(branch == 'published'), + ) + self.assertEqual(course_locator.package_id, new_style_package_id) + self.assertEqual(course_locator.branch, branch) + def test_translate_location_read_only(self): """ Test the variants of translate_location which don't create entries, just decode