def adapt_object(self, source_object, target_object, source_accessor=None, target_accessor=None, source_schema=None, target_schema=None, languages=None, parent_context=None): context = AdaptationContext( adapter=self.adapter, source_object=source_object, target_object=target_object, source_accessor=source_accessor or self.source_accessor or get_accessor(source_object), target_accessor=target_accessor or self.target_accessor or get_accessor(target_object), source_schema=source_schema, target_schema=target_schema, copy_mode=self.copy_mode, collection_copy_mode=self.collection_copy_mode, languages=languages, parent_context=parent_context) for rule in self.__rules: rule.adapt_object(context) if self.implicit_copy: copy_rule = Copy( set(source_schema.members()) - context._consumed_keys) copy_rule.adapt_object(context)
def from_json_value(self, value, **options): if value is None: return None record = (self.type or dict)() accessor = get_accessor(record) for key, member_value in value.items(): member = self.get_member(key) if member is None: continue if member.translated and isinstance(member_value, Mapping): if member_value: for lang, lang_value in member_value.items(): accessor.set(record, member.name, member.from_json_value( lang_value, **options), language=lang) else: accessor.set(record, member.name, member.from_json_value(member_value, **options)) return record
def to_json_value(self, value, **options): languages = options.get("languages", None) if languages is None: languages = get_language() if value is None: return None record = {} accessor = get_accessor(value) for member in self.iter_members(): if member.translated and not isinstance(languages, str): member_value = dict( (lang, member.to_json_value(accessor.get(value, language=lang), **options)) for lang in accessor.languages(value, member.name)) else: member_value = member.to_json_value( accessor.get(value, member.name), **options) record[member.name] = member_value return record
def _default_validation(self, context): """Validation rule for schemas. Applies the validation rules defined by all members in the schema, propagating their errors.""" for error in Member._default_validation(self, context): yield error accessor = (self.accessor or context.get("accessor", None) or get_accessor(context.value)) languages = context.get("languages") for member in self.ordered_members(): key = member.name if member.translated: for language in (languages or accessor.languages(context.value, key)): value = accessor.get(context.value, key, language=language) for error in member.get_errors(value, parent_context=context, language=language): yield error else: value = accessor.get(context.value, key, default=None) for error in member.get_errors(value, parent_context=context): yield error
def init_instance(self, instance, values=None, accessor=None, excluded_members=None): if accessor is None: accessor = get_accessor(instance) # Set the value of all object members, either from a parameter or from # a default value definition for name, member in self.members().items(): if excluded_members is not None and member in excluded_members: continue value = default if values is None else values.get(name, default) if value is undefined: continue if value is default: if member.translated: continue value = member.produce_default(instance) accessor.set(instance, name, value)
def eval(self, context, accessor = None): value = (accessor or get_accessor(context)).get(context, self.relation) if value: return all(filter.eval(value, accessor) for filter in self.filters) return False
def captcha_validation_rule(self, validable, context): """Validation rule for reCaptcha. Applies the validation rules defined by all members in the schema, propagating their errors. Checks that the L{response} member is valid for the L{challenge} and the L{public_key} constraint. """ accessor = self.accessor \ or context.get("accessor", None) \ or get_accessor(validable) challenge = accessor.get(validable, "challenge", default=None) response = accessor.get(validable, "response", default=None) if challenge and response: def encode_if_necessary(s): if isinstance(s, unicode): return s.encode('utf-8') return s private_key = ReCaptchaExtension.instance.private_key remote_ip = cherrypy.request.remote.ip params = urllib.urlencode({ 'privatekey': encode_if_necessary(private_key), 'remoteip': encode_if_necessary(remote_ip), 'challenge': encode_if_necessary(challenge), 'response': encode_if_necessary(response), }) request = urllib2.Request( url="http://%s/verify" % self.VERIFY_SERVER, data=params, headers={ "Content-type": "application/x-www-form-urlencoded", "User-agent": "Woost reCAPTCHA extension" }) httpresp = urllib2.urlopen(request) return_values = httpresp.read().splitlines() httpresp.close() return_code = return_values[0] if (return_code != "true"): yield ReCaptchaValidationError(self, response, context) else: yield ReCaptchaValidationError(self, response, context)
def eval(self, context, accessor = None): value = (accessor or get_accessor(context)).get(context, self.relation) if value: for item in value: for filter in self.filters: if not filter.eval(item, accessor): return False return True
def _add_relation(self, obj, related_obj): key = self.name accessor = get_accessor(obj) collection = accessor.get(obj, key) if collection is None: # Try to create a new, empty collection automatically collection_type = self.type or self.default_type if collection_type: accessor.set(obj, key, collection_type()) collection = accessor.get(obj, key) else: raise ValueError("Error relating %s to %s on %s; " "the target collection is undefined" % (obj, related_obj, self)) collection.add(related_obj)
def _remove_relation(self, obj, related_obj): get_accessor(obj).get(obj, self.name).remove(related_obj)
def eval(self, context, accessor = None): return (accessor or get_accessor(context)) \ .get(context, self.name, None)
def _remove_relation(self, obj, related_obj): get_accessor(obj).set(obj, self.name, None)
def _add_relation(self, obj, related_obj): get_accessor(obj).set(obj, self.name, related_obj)
def coerce(self, value: Any, coercion: Coercion, **validation_parameters) -> Any: """Coerces the given value to conform to the member definition. The method applies the behavior indicated by the `coercion` parameter to each member of the scheam, either accepting or rejecting its value. Depending on the selected coercion strategy, rejected values may be transformed into a new value or raise an exception. New values are modified in place. """ if coercion is Coercion.NONE: return value if coercion is Coercion.FAIL: errors = list(self.get_errors(value, **validation_parameters)) if errors: raise InputError(self, value, errors) else: # Coercion of members affected by schema wide validation rules accessor = get_accessor(value) schema_level_errors = self.get_errors(value, recursive=False, **validation_parameters) for error in schema_level_errors: if coercion is Coercion.FAIL_IMMEDIATELY: raise InputError(self, value, [error]) elif coercion is Coercion.SET_NONE: for member in error.invalid_members: if member.schema is self: accessor.set(value, member.name, None, error.language) elif coercion is Coercion.SET_DEFAULT: for member in error.invalid_members: if member.schema is self: accessor.set(value, member.name, member.produce_default(value), error.language) # Per member coercion if value is not None: for member in self.iter_members(): if member.translated: for language in accessor.languages(value, member.name): lang_value = accessor.get(value, member.name, language) coerced_lang_value = member.coerce( lang_value, coercion, **validation_parameters) if lang_value != coerced_lang_value: accessor.set(value, member.name, coerced_lang_value, language) else: member_value = accessor.get(value, member.name) coerced_member_value = member.coerce( member_value, coercion, **validation_parameters) if member_value != coerced_member_value: accessor.set(value, member.name, coerced_member_value) return value
def diff( source, target, schema = None, source_accessor = None, target_accessor = None, exclude = None, language_subset = None): """Obtains the set of members that differ between two items. @param source: The first item to compare. @param target: The other item to compare. @param schema: The schema used to compare both objects. Can be omitted if both objects are instances of the same L{SchemaObject<cocktail.schema.SchemaObject}. @type schema: L{Schema<cocktail.schema.Schema>} @param source_accessor: A data accessor used to extract data from the source item. @type source_accessor: L{Accessor<cocktail.accessors.Accessor>} subclass @param target_accessor: A data accessor used to extract data from the target item. @type target_accessor: L{Accessor<cocktail.accessors.Accessor>} subclass @param exclude: An optional filtering function that will be called to determine if a given member should be inspected or not. @type exclude: callable (L{member<cocktail.schema.member.Member>}) -> bool @param language_subset: Indicates the language that should be inspected in search of differences. Leave empty to consider all languages defined by either the source or the target objects. @type language_subset: str collection or None @return: An iterable sequence of member and language tuples. @rtype: (L{member<cocktail.schema.member.Member>}, str) iterable """ if source_accessor is None: source_accessor = get_accessor(source) if target_accessor is None: target_accessor = get_accessor(target) if language_subset is not None and not isinstance(language_subset, set): language_subset = set(language_subset) # Try to infer the schema for SchemaObject instances if schema is None: if type(source) is type(target) \ and isinstance(source, SchemaObject) \ and isinstance(target, SchemaObject): schema = type(source) else: raise ValueError("The schema parameter for the diff() function " "can't be ommitted if the two compared objects aren't " "instances of the same SchemaObject derived class") for member in schema.members().values(): if exclude and exclude(member): continue key = member.name # Translated members if member.translated: source_languages = set(source_accessor.languages(source, key)) target_languages = set(target_accessor.languages(target, key)) languages = source_languages | target_languages if language_subset: languages &= language_subset for language in languages: source_value = source_accessor.get( source, key, default = None, language = language) target_value = target_accessor.get( target, key, default = None, language = language) if source_value != target_value: yield (member, language) # Regular members else: source_value = source_accessor.get(source, key, default = None) target_value = target_accessor.get(target, key, default = None) if source_value != target_value: yield (member, None)