Beispiel #1
0
    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)
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    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)
Beispiel #6
0
    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
Beispiel #7
0
    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)
Beispiel #8
0
    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
Beispiel #9
0
    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)
Beispiel #10
0
 def _remove_relation(self, obj, related_obj):
     get_accessor(obj).get(obj, self.name).remove(related_obj)
Beispiel #11
0
 def eval(self, context, accessor = None):
     return (accessor or get_accessor(context)) \
            .get(context, self.name, None)
Beispiel #12
0
 def _remove_relation(self, obj, related_obj):
     get_accessor(obj).set(obj, self.name, None)
Beispiel #13
0
 def _add_relation(self, obj, related_obj):
     get_accessor(obj).set(obj, self.name, related_obj)
Beispiel #14
0
    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
Beispiel #15
0
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)