def __init__(self, org=None, offering=None, branch=None, version_guid=None): """ Construct a CourseLocator Args: version_guid (string or ObjectId): optional unique id for the version org, offering (string): the standard definition. Optional only if version_guid given branch (string): the branch such as 'draft', 'published', 'staged', 'beta' """ if version_guid: version_guid = self.as_object_id(version_guid) if not all(field is None or self.ALLOWED_ID_RE.match(field) for field in [org, offering, branch]): raise InvalidKeyError(self.__class__, [org, offering, branch]) super(CourseLocator, self).__init__(org=org, offering=offering, branch=branch, version_guid=version_guid) if self.version_guid is None and (self.org is None or self.offering is None): raise InvalidKeyError( self.__class__, "Either version_guid or org and offering should be set")
def _check_location_part(cls, val, regexp): # pylint: disable=missing-docstring if val is None: return if not isinstance(val, basestring): raise InvalidKeyError(cls, "{!r} is not a string".format(val)) if regexp.search(val) is not None: raise InvalidKeyError(cls, "Invalid characters in {!r}.".format(val))
def _from_string(cls, serialized): if not serialized.startswith('0x'): raise InvalidKeyError(cls, serialized) try: return cls(int(serialized, 16)) except (ValueError, TypeError): raise InvalidKeyError(cls, serialized)
def __init__(self, library_key, block_type, block_id, **kwargs): """ Construct a LibraryUsageLocator """ # LibraryUsageLocator is a new type of locator so should never be deprecated. if library_key.deprecated or kwargs.get('deprecated', False): raise InvalidKeyError( self.__class__, "LibraryUsageLocators are never deprecated.") block_id = self._parse_block_ref(block_id, False) if not all( self.ALLOWED_ID_RE.match(val) for val in (block_type, block_id)): raise InvalidKeyError( self.__class__, "Invalid block_type or block_id ('{}', '{}')".format( block_type, block_id)) # We skip the BlockUsageLocator init and go to its superclass: # pylint: disable=bad-super-call super(BlockUsageLocator, self).__init__(library_key=library_key, block_type=block_type, block_id=block_id, **kwargs)
def __init__(self, org=None, course=None, run=None, branch=None, version_guid=None, deprecated=False, **kwargs): """ Construct a CourseLocator Args: version_guid (string or ObjectId): optional unique id for the version org, course, run (string): the standard definition. Optional only if version_guid given branch (string): the branch such as 'draft', 'published', 'staged', 'beta' """ offering_arg = kwargs.pop('offering', None) if offering_arg: warnings.warn( "offering is deprecated! Use course and run instead.", DeprecationWarning, stacklevel=2 ) course, __, run = offering_arg.partition("/") if deprecated: for part in (org, course, run): self._check_location_part(part, self.INVALID_CHARS_DEPRECATED) fields = [org, course] # Deprecated style allowed to have None for run and branch, and allowed to have '' for run if run: fields.append(run) if branch is not None: fields.append(branch) if not all(self.DEPRECATED_ALLOWED_ID_RE.match(field) for field in fields): raise InvalidKeyError(self.__class__, fields) else: if version_guid: version_guid = self.as_object_id(version_guid) for name, value in [['org', org], ['course', course], ['run', run], ['branch', branch]]: if not (value is None or self.ALLOWED_ID_RE.match(value)): raise InvalidKeyError(self.__class__, u"Special characters not allowed in field {}: '{}'".format(name, value)) super(CourseLocator, self).__init__( org=org, course=course, run=run, branch=branch, version_guid=version_guid, deprecated=deprecated, **kwargs ) if self.deprecated and (self.org is None or self.course is None): raise InvalidKeyError(self.__class__, "Deprecated strings must set both org and course.") if not self.deprecated and self.version_guid is None and \ (self.org is None or self.course is None or self.run is None): raise InvalidKeyError(self.__class__, "Either version_guid or org, course, and run should be set")
def __init__(self, **kwargs): """constructor for a ccx locator""" # for a ccx locator we require a ccx id to be passed. if 'ccx' not in kwargs: raise InvalidKeyError(self.__class__, "ccx must be set") if kwargs.get('deprecated', False): raise InvalidKeyError(self.__class__, "cannot be deprecated") super(CCXLocator, self).__init__(**kwargs)
def __init__(self, org=None, library=None, branch=None, version_guid=None, **kwargs): """ Construct a LibraryLocator Args: version_guid (string or ObjectId): optional unique id for the version org, library: the standard definition. Optional only if version_guid given. branch (string): the optional branch such as 'draft', 'published', 'staged', 'beta' """ if 'offering' in kwargs: raise ValueError( "'offering' is not a valid field for a LibraryLocator.") if 'course' in kwargs: if library is not None: raise ValueError("Cannot specify both 'library' and 'course'") warnings.warn( "For LibraryLocators, use 'library' instead of 'course'.", DeprecationWarning, stacklevel=2) library = kwargs.pop('course') run = kwargs.pop('run', self.RUN) if run != self.RUN: raise ValueError("Invalid run. Should be '{}' or None.".format( self.RUN)) if version_guid: version_guid = self.as_object_id(version_guid) if not all(field is None or self.ALLOWED_ID_RE.match(field) for field in [org, library, branch]): raise InvalidKeyError(self.__class__, [org, library, branch]) if kwargs.get('deprecated', False): raise InvalidKeyError( self.__class__, 'LibraryLocator cannot have deprecated=True') super(LibraryLocator, self).__init__(org=org, library=library, branch=branch, version_guid=version_guid, **kwargs) if self.version_guid is None and (self.org is None or self.library is None): raise InvalidKeyError( self.__class__, "Either version_guid or org and library should be set")
def for_branch(self, branch): """ Return a new CourseLocator for another branch of the same library (also version agnostic) """ if self.org is None and branch is not None: raise InvalidKeyError(self.__class__, "Branches must have full library ids not just versions") return self.replace(branch=branch, version_guid=None)
def __init__(self, block_type, definition_id, deprecated=False): # pylint: disable=unused-argument if isinstance(definition_id, basestring): try: definition_id = self.as_object_id(definition_id) except ValueError: raise InvalidKeyError(DefinitionLocator, definition_id) super(DefinitionLocator, self).__init__(definition_id=definition_id, block_type=block_type, deprecated=False)
def _from_string(cls, serialized): serialized = serialized.replace("+", "/") if serialized.count('/') != 2: raise InvalidKeyError(cls, serialized) # Turns encoded slashes into actual slashes return cls(*serialized.split('/'))
def _parse_block_ref(cls, block_ref): if isinstance(block_ref, LocalId): return block_ref elif len(block_ref) > 0 and cls.ALLOWED_ID_RE.match(block_ref): return block_ref else: raise InvalidKeyError(cls, block_ref)
def _from_deprecated_string(cls, serialized): """ Return an instance of `cls` parsed from its deprecated `serialized` form. This will be called only if :meth:`OpaqueKey.from_string` is unable to parse a key out of `serialized`, and only if `set_deprecated_fallback` has been called to register a fallback class. Args: cls: The :class:`OpaqueKey` subclass. serialized (unicode): A serialized :class:`OpaqueKey`, with namespace already removed. Raises: InvalidKeyError: Should be raised if `serialized` is not a valid serialized key understood by `cls`. """ match = cls.DEPRECATED_URL_RE.match(serialized) if match is None: raise InvalidKeyError(BlockUsageLocator, serialized) groups = match.groupdict() course_key = CourseLocator( org=groups['org'], course=groups['course'], run=None, branch=groups.get('revision'), deprecated=True, ) return cls(course_key, groups['category'], groups['name'], deprecated=True)
def __init__(self, course_id): try: self.course_key = CourseKey.from_string(course_id) except InvalidKeyError: message = 'Invalid course_id: {} value for last login report'.format( course_id) LOG.error(message) raise InvalidKeyError(course_id, message)
def _from_string(cls, serialized): """ Requests LibraryLocator to deserialize its part and then adds the local deserialization of block """ # Allow access to _from_string protected method library_key = LibraryLocator._from_string(serialized) # pylint: disable=protected-access parsed_parts = LibraryLocator.parse_url(serialized) block_id = parsed_parts.get('block_id', None) if block_id is None: raise InvalidKeyError(cls, serialized) block_type = parsed_parts.get('block_type') if block_type is None: raise InvalidKeyError(cls, serialized) return cls(library_key, parsed_parts.get('block_type'), block_id)
def __init__(self, course_key, block_type, block_id): """ Construct a BlockUsageLocator """ block_id = self._parse_block_ref(block_id) if block_id is None: raise InvalidKeyError(self.__class__, "Missing block id") super(BlockUsageLocator, self).__init__(course_key=course_key, block_type=block_type, block_id=block_id)
def test_course_run_refund_status_invalid_course_key(self): """ Assert that view:course_run_refund_status returns correct Json for Invalid Course Key .""" with patch('opaque_keys.edx.keys.CourseKey.from_string') as mock_method: mock_method.side_effect = InvalidKeyError('CourseKey', 'The course key used to get refund status caused \ InvalidKeyError during look up.') response = self.client.get(reverse('course_run_refund_status', kwargs={'course_id': self.course.id})) self.assertEqual(json.loads(response.content.decode('utf-8')), {'course_refundable_status': ''}) self.assertEqual(response.status_code, 406)
def test_view_bad_course_key_fail(mocker, view, mock_request): """A request to the video API with an invalid course id/key should fail""" patched_course_key_parser = mocker.patch( "edx_video_api.views.CourseKey.from_string", side_effect=InvalidKeyError(mocker.Mock(), {})) response = view(mock_request, course_id=COURSE_ID).render() patched_course_key_parser.assert_called_once_with(COURSE_ID) assert response.status_code == status.HTTP_404_NOT_FOUND assert "Invalid course key" in json.loads(response.content)["error"]
def _from_string(cls, serialized): """ Return a BundleDefinitionLocator by parsing the given serialized string """ uuid_str = serialized try: return cls(uuid=uuid_str) except (ValueError, TypeError) as exc: raise InvalidKeyError(cls, serialized) from exc
def _from_string(cls, serialized): """ Instantiate this key from a serialized string """ try: (org, slug) = serialized.split(':') except ValueError: raise InvalidKeyError(cls, serialized) return cls(org=org, slug=slug)
def _from_string(cls, serialized): """ Requests CourseLocator to deserialize its part and then adds the local deserialization of block """ course_key = CourseLocator._from_string(serialized) parsed_parts = cls.parse_url(serialized) block_id = parsed_parts.get('block_id', None) if block_id is None: raise InvalidKeyError(cls, serialized) return cls(course_key, parsed_parts.get('block_type'), block_id)
def _check_location_part(cls, val, regexp): """ Check that `regexp` doesn't match inside `val`. If it does, raise an exception Args: val (string): The value to check regexp (re.RegexObject): The regular expression specifying invalid characters Raises: InvalidKeyError: Raised if any invalid character is found in `val` """ if val is None: return if not isinstance(val, basestring): raise InvalidKeyError(cls, "{!r} is not a string".format(val)) if regexp.search(val) is not None: raise InvalidKeyError(cls, "Invalid characters in {!r}.".format(val))
def __init__(self, block_family, block_type): # Call super using kwargs, so that we can set CHECKED_INIT to False if ':' in block_family: raise InvalidKeyError(self.__class__, "block_family may not contain ':'.") if block_family in (XBLOCK_V1, XMODULE_V1): block_family = XBLOCK_V1 super().__init__( block_family=block_family, block_type=block_type, deprecated=block_family == XBLOCK_V1, )
def __init__(self, block_type, definition_id): if isinstance(definition_id, LocalId): super(DefinitionLocator, self).__init__(definition_id=definition_id, block_type=block_type) elif isinstance(definition_id, basestring): try: definition_id = self.as_object_id(definition_id) except ValueError: raise InvalidKeyError(self, definition_id) super(DefinitionLocator, self).__init__(definition_id=definition_id, block_type=block_type) elif isinstance(definition_id, ObjectId): super(DefinitionLocator, self).__init__(definition_id=definition_id, block_type=block_type)
def as_object_id(cls, value): """ Attempts to cast value as a bson.objectid.ObjectId. Raises: ValueError: if casting fails """ try: return ObjectId(value) except InvalidId: raise InvalidKeyError(cls, '"%s" is not a valid version_guid' % value)
def __init__(self, course_key, block_type, block_id, **kwargs): """ Construct a BlockUsageLocator """ # Always use the deprecated status of the course key deprecated = kwargs['deprecated'] = course_key.deprecated block_id = self._parse_block_ref(block_id, deprecated) if block_id is None and not deprecated: raise InvalidKeyError(self.__class__, "Missing block id") super(BlockUsageLocator, self).__init__(course_key=course_key, block_type=block_type, block_id=block_id, **kwargs)
def for_branch(self, branch): """ Return a new CourseLocator for another branch of the same course (also version agnostic) """ if self.org is None: raise InvalidKeyError(self.__class__, "Branches must have full course ids not just versions") return CourseLocator( org=self.org, offering=self.offering, branch=branch, version_guid=None )
def __init__(self, uuid): """ Instantiate a new PathwayLocator """ if not isinstance(uuid, UUID): uuid_str = uuid uuid = UUID(uuid_str) # Raise an error if this UUID is not in standard form, to prevent inconsistent UUID serialization if uuid_str != str(uuid): raise InvalidKeyError(self.__class__, u"uuid field got UUID string that's not in standard form") super().__init__(uuid=uuid)
def make_usage_key_from_deprecated_string(self, location_url): """ Temporary mechanism for creating a UsageKey given a CourseKey and a serialized Location. NOTE: this prejudicially takes the tag, org, and course from the url not self. Raises: InvalidKeyError: if the url does not parse """ match = URL_RE.match(location_url) if match is None: raise InvalidKeyError(Location, location_url) groups = match.groupdict() return Location(run=self.run, **groups)
def _from_deprecated_string(cls, serialized): match = cls.ASSET_URL_RE.match(serialized) if match is None: raise InvalidKeyError(cls, serialized) groups = match.groupdict() course_key = CourseLocator( groups['org'], groups['course'], None, groups.get('revision', None), deprecated=True ) return cls(course_key, groups['category'], groups['name'], deprecated=True)
def _from_string(cls, serialized): """ Instantiate this key from a serialized string """ try: (library_org, library_slug, block_type, usage_id) = serialized.split(':') except ValueError: raise InvalidKeyError(cls, serialized) return cls(library_org=library_org, library_slug=library_slug, block_type=block_type, usage_id=usage_id)