Ejemplo n.º 1
0
    def findLocationForTranslation(self, language):
        parent = aq_parent(aq_inner(self.context))
        trans_parent = ITranslatable(parent, None)
        if trans_parent is None:
            return parent

        return trans_parent.getTranslation(language) or parent
Ejemplo n.º 2
0
    def _translations(self, missing):
        # Figure out the "closest" translation in the parent chain of the
        # context. We stop at both an INavigationRoot or an ISiteRoot to look
        # for translations. We do want to find something that is definitely
        # in the language the user asked for.
        context = aq_inner(self.context)
        translations = {}
        chain = aq_chain(context)
        first_pass = True
        _checkPermission = getSecurityManager().checkPermission
        for item in chain:
            if ISiteRoot.providedBy(item):
                # We have a site root, which works as a fallback
                has_view_permission = bool(_checkPermission('View', item))
                for c in missing:
                    translations[c] = (item, first_pass, has_view_permission)
                break

            translatable = ITranslatable(item, None)
            if translatable is None:
                continue

            item_trans = item.getTranslations(review_state=False)
            for code, trans in item_trans.items():
                code = str(code)
                if code not in translations:
                    # make a link to a translation only if the user
                    # has view permission
                    has_view_permission = bool(_checkPermission('View', trans))
                    if (not INavigationRoot.providedBy(item)
                            and not has_view_permission):
                        continue
                    # If we don't yet have a translation for this language
                    # add it and mark it as found
                    translations[code] = (trans, first_pass,
                                          has_view_permission)
                    missing = missing - set((code, ))

            if len(missing) <= 0:
                # We have translations for all
                break
            if INavigationRoot.providedBy(item):
                # Don't break out of the navigation root jail
                has_view_permission = bool(_checkPermission('View', item))
                for c in missing:
                    translations[c] = (item, False, has_view_permission)
                break
            first_pass = False
        # return a dict of language code to tuple. the first tuple element is
        # the translated object, the second argument indicates wether the
        # translation is a direct translation of the context or something from
        # higher up the translation chain
        return translations
Ejemplo n.º 3
0
    def createTranslation(self, container, language, *args, **kwargs):
        context = aq_inner(self.context)
        canonical = context.getCanonical()
        portal_type = self.getTranslationPortalType(container, language)
        new_id = kwargs.pop(
            'id', self.generateId(container, canonical.getId(), language))
        kwargs["language"] = language
        translation = _createObjectByType(portal_type, container, new_id,
                                          *args, **kwargs)

        # If there is a custom factory method that doesn't add the
        # translation relationship, make sure it is done now.
        if translation.getCanonical() != canonical:
            translation.addTranslationReference(canonical)

        # THIS IS THE LINE WE NEED TO CUSTOMIZE
        OSHALanguageIndependentFields(canonical).copyFields(translation)

        if isDefaultPage(aq_parent(aq_inner(canonical)), canonical):
            translation._lp_default_page = True

        # If this is a folder, move translated subobjects aswell.
        if context.isPrincipiaFolderish:
            moveids = []
            for obj in context.values():
                translator = ITranslatable(obj, None)
                if translator is not None \
                   and translator.getLanguage() == language:
                    lockable = ILockable(obj, None)
                    if lockable is not None and lockable.can_safely_unlock():
                        lockable.unlock()
                    moveids.append(obj.getId())
            if moveids:
                info = context.manage_cutObjects(moveids)
                translation.manage_pasteObjects(info)

        return translation
Ejemplo n.º 4
0
        def can_translate(context, language):
            """ Check if required parent translations are in place so that we can translate this item

            :return: True if the item can be translated

            """

            assert context is not None

            parent = aq_parent(context)

            if ISiteRoot.providedBy(parent):
                return True

            # Parent is a language base folder at plone site root
            if INavigationRoot.providedBy(parent):
                return True

            if ITranslatable.providedBy(parent):
                translatable = ITranslatable(parent)
            else:
                from logging import getLogger
                log = getLogger('silvuple.views.can_translate')
                if parent:
                    log.info('Parent is not translatable: %s' %
                             parent.absolute_url())
                else:
                    log.error(
                        'Cannot translate language: %s, no parent for %s' %
                        (language, context.absolute_url()))

                return False

            translation = translatable.getTranslation(language)

            return translation is not None
Ejemplo n.º 5
0
    def getContentByCanonical(self):
        """
        Gets a list of entries where content is arranged by its canonical language version.

        Each entry is a dictionary like:

            [
                ...
                [
                    { language : "en", available : true, title : "Foobar", canonical : True, url : "http://" },
                    { language : "fi", available : true, title : "Barbar", canonical : False, ... },
                    { language : "ru", available : false }
                ]
            ]

        Not available languages won't get any entries.
        """
        settings = self.getSettings()
        context = aq_inner(self.context)
        tools = getMultiAdapter((context, self.request), name="plone_tools")

        portal_catalog = tools.catalog()

        all_content = []

        if ITranslatable.providedBy(context):
            for lang, item in context.getTranslations(
                    review_state=False).items():
                all_content += portal_catalog(
                    Language="all",
                    path='/'.join(item.getPhysicalPath()),
                    portal_type=settings.contentTypes)
        else:
            all_content = portal_catalog(Language="all",
                                         path='/'.join(
                                             context.getPhysicalPath()),
                                         portal_type=settings.contentTypes)

        # List of UUID -> entry data mappings
        result = OrderedDict()

        # Create a dictionary entry populated with default languages,
        # so that languages come always in the same order
        # E.g. {en:{"available":False}}

        langs = self.getLanguages()

        def get_base_entry():
            """ Item row for all languages, everything set off by default """
            base_entry = OrderedDict()
            for lang in langs:
                base_entry[lang] = dict(available=False,
                                        language=lang,
                                        canTranslate=False)
            return base_entry

        def get_or_create_handle(translatable):
            """
            Get or create entry in the result listing.

            This is a dict of language -> data pairs
            """
            canonical = translatable.getCanonical()
            uuid = IUUID(canonical, None)

            if not uuid:
                raise RuntimeError("Object missing UUID: %s" % context)

            # Get the existing canonical entry
            # for the listing, or create a new empty
            # populated entry otherwise
            if uuid in result:
                return result[uuid]
            else:
                entry = get_base_entry()
                result[uuid] = entry
                return entry

        def can_translate(context, language):
            """ Check if required parent translations are in place so that we can translate this item

            :return: True if the item can be translated

            """

            assert context is not None

            parent = aq_parent(context)

            if ISiteRoot.providedBy(parent):
                return True

            # Parent is a language base folder at plone site root
            if INavigationRoot.providedBy(parent):
                return True

            if ITranslatable.providedBy(parent):
                translatable = ITranslatable(parent)
            else:
                from logging import getLogger
                log = getLogger('silvuple.views.can_translate')
                if parent:
                    log.info('Parent is not translatable: %s' %
                             parent.absolute_url())
                else:
                    log.error(
                        'Cannot translate language: %s, no parent for %s' %
                        (language, context.absolute_url()))

                return False

            translation = translatable.getTranslation(language)

            return translation is not None

        for brain in all_content:

            if not self.shouldTranslate(brain):
                continue

            try:
                context = brain.getObject()
            except Exception as e:
                logger.error("Could not load brain %s" % brain.getURL())
                logger.exception(e)
                continue

            if ITranslatable.providedBy(context):
                translatable = ITranslatable(context)
            else:
                from logging import getLogger
                log = getLogger('silvuple.views.can_translate')
                log.info('Content is not translatable: %s' %
                         context.absolute_url())
                continue

            try:
                entry = get_or_create_handle(translatable)
            except RuntimeError:
                from logging import getLogger
                log = getLogger('silvuple.views.getContentByCanonical')
                log.info('Item has no UUID: %s' & translatable.absolute_url())
                continue

            # Data exported to JSON + context object needed for post-processing
            data = dict(canonical=translatable.isCanonical(),
                        title=context.title_or_id(),
                        url=context.absolute_url(),
                        lang=map_language_id(context.Language()),
                        available=True,
                        path=context.absolute_url_path(),
                        context=context)

            entry[map_language_id(context.Language())] = data

        # Fill in items which can be translated
        for entry in result.values():

            canonical = None

            # First snatch canonical  item for this content
            for lang in entry.values():

                if lang.get("canonical", False):
                    canonical = lang["context"]

                # Do not leak out to JSON serialization
                lang["context"] = None

            if not canonical:
                logger.warn("No canonical content for %s" % entry)
                continue

            # Then populate untranslated languages
            for lang in entry.values():
                if not lang["available"]:

                    lang_code = lang["language"]

                    lang["canTranslate"] = can_translate(canonical, lang_code)

                    if canonical:
                        # Point to LinguaPlone Translate into... form
                        lang["url"] = "%s/@@translate?newlanguage=%s" % (
                            canonical.absolute_url(), lang_code)
                    else:
                        lang["url"] = "#"

        # Convert pre content entries to lists, so that we can guarantee
        # the order of langauges when passing thru JSON
        result = [entry.values() for entry in result.values()]

        self.sortContentListing(result)

        return result