Example #1
0
def _handle_removing_translation(event):
    obj = event.source
    removed_language = event.language
    translation = event.translation

    if obj.indexed:
        for member in obj.__class__.iter_members():
            if (member.translated and member.indexed
                    and obj._should_index_member(member)):
                value = obj.get(member, removed_language)

                # Remove index entries for the removed language and all its
                # derived translations
                for lang in obj.iter_derived_translations(removed_language,
                                                          include_self=True):
                    remove_index_entry(obj, member, value, lang)

                    # Add index entries for derived translations that now
                    # inherit their values from a different fallback language.
                    if lang != removed_language:
                        for fallback in iter_language_chain(lang):
                            if (fallback != removed_language
                                    and fallback in obj.translations):
                                add_index_entry(obj, member,
                                                obj.get(member, fallback),
                                                lang)
                                break
Example #2
0
 def iter_derived_translations(self, language=None, include_self=False):
     language = require_language(language)
     for derived_lang in descend_language_tree(language,
                                               include_self=include_self):
         for chain_lang in iter_language_chain(derived_lang):
             if chain_lang == language:
                 yield derived_lang
                 break
             elif chain_lang in self.translations:
                 break
Example #3
0
def _handle_translation_removed(event):

    if not indexing_enabled:
        return

    obj = event.source
    id = obj.id
    removed_language = event.language

    translated_members = []

    if obj._should_index_member_full_text(obj.__class__):
        translated_members.append(obj.__class__)

    translated_members.extend(
        member
        for member in obj.__class__.iter_members()
        if member.translated
        and obj._should_index_member_full_text(member)
    )

    for lang in obj.iter_derived_translations(
        removed_language,
        include_self = True
    ):
        for member in translated_members:
            index = member.get_full_text_index(lang)
            index.unindex_doc(id)

        if lang != removed_language:
            for chain_lang in iter_language_chain(lang):
                if (
                    chain_lang != removed_language
                    and chain_lang in obj.translations
                ):
                    for member in translated_members:

                        if isinstance(member, type):
                            text = obj.get_searchable_text(
                                languages = (chain_lang,)
                            )
                        else:
                            text = obj.get(member, chain_lang)
                            if text:
                                text = normalize(text)

                        if text:
                            index = member.get_full_text_index(lang)
                            index.index_doc(id, text)

                    break
Example #4
0
def _init_translation(cls,
                      instance,
                      values=None,
                      accessor=None,
                      excluded_members=None,
                      copy_from_fallback=True):

    # Set 'translated_object' and 'language' first, so events for changes in
    # all other members are relayed to the translation owner
    if values is not None:

        language = values.pop("language")
        if language is not None:
            instance.language = language

        translated_object = values.pop("translated_object")
        if translated_object is not None:
            instance.translated_object = translated_object

        if language is not None and translated_object is not None:
            translated_object.translations[language] = instance

        if excluded_members is None:
            excluded_members = (cls.translated_object, cls.language)
        else:
            excluded_members = \
                set([cls.translated_object, cls.language]) + set(excluded_members)

        # Copy values from the first available fallback translation
        if (copy_from_fallback and language is not None
                and translated_object is not None):
            languages = iter_language_chain(language)
            next(languages)
            get_translation = translated_object.translations.get
            for lang in languages:
                base_translation = get_translation(lang)
                if base_translation is not None:
                    for key, member in cls.members().items():
                        if member not in excluded_members:
                            values.setdefault(key, base_translation.get(key))
                    break

    Schema.init_instance(cls, instance, values, accessor, excluded_members)
Example #5
0
        def __get__(self, instance, type=None, language=None):
            if instance is None:
                return self.member
            else:
                # Calculated field
                expression = self.member.expression
                if expression is not None:
                    return self.member.resolve_expression(instance, language)

                if self.member.translated:
                    for language in iter_language_chain(language):
                        target = instance.translations.get(language)
                        if target is not None:
                            break
                    else:
                        return None
                else:
                    target = instance

                value = getattr(target, self.__priv_key, undefined)

                if value is undefined:
                    if getattr(instance, "_v_is_producing_default", False):
                        return None

                    instance._v_is_producing_default = True
                    try:
                        value = self.member.produce_default(instance)
                        self.__set__(instance,
                                     value,
                                     language=language,
                                     previous_value=None)
                        return self.__get__(instance, type, language)
                    finally:
                        instance._v_is_producing_default = False

                return value
    def _handle_form_data(self):

        stack_node = self.stack_node
        form_data = stack_node.form_data
        translations = stack_node.translations

        section = self.params.read(schema.String("section", default="fields"))

        added_translation = self.params.read(
            schema.String("add_translation",
                          enumeration=self.available_languages))

        deleted_translation = self.params.read(
            schema.String("delete_translation", enumeration=translations))

        # Remove translations
        if deleted_translation:
            translations.remove(deleted_translation)
            for key, member in self.fields_schema.members().iteritems():
                if member.translated:
                    values = form_data.get(key)
                    if values:
                        values.pop(deleted_translation, None)

        get_method = cherrypy.request.method.upper() == "GET"

        # Load form data from the request
        get_parameter(self.fields_schema,
                      target=form_data,
                      languages=translations,
                      prefix=self.form_prefix,
                      errors="ignore",
                      implicit_booleans=not get_method,
                      undefined="skip" if get_method else "set_none")

        # Add translations
        if added_translation and added_translation not in translations:
            translations.append(added_translation)

            # Try to copy an existing fallback translation
            for fallback_language in iter_language_chain(added_translation,
                                                         include_self=False):
                if fallback_language in translations:
                    for key, member in self.fields_schema.members().iteritems(
                    ):
                        if member.translated:
                            value = schema.get(form_data,
                                               key,
                                               language=fallback_language)
                            schema.set(form_data,
                                       key,
                                       value,
                                       language=added_translation)
                    break
            # If there's no fallback translation to use, create a new
            # translation from scratch
            else:
                translation_data = {}
                stack_node.content_type.translation.init_instance(
                    translation_data)
                for key, value in translation_data.iteritems():
                    schema.set(form_data,
                               key,
                               value,
                               language=added_translation)

        # Drop references
        unlink = cherrypy.request.params.get("relation-unlink")

        if unlink:
            form_data[unlink] = None

        return form_data
Example #7
0
 def get_source_locale(self, locale):
     translations = self.translations
     for locale in iter_language_chain(locale):
         if locale in translations:
             return locale