def setupLocalRDFRepositories(context):

    if context.readDataFile('eeaploneadmin_localsites.txt') is None:
        return

    plone = context.getSite()
    logger = context.getLogger('eea-localsite')
    wf = getToolByName(plone, 'portal_workflow')

    enRDFRepo = plone.SITE.themes['rdf-repository']
    #siteLangView = plone.unrestrictedTraverse('@@translatedSitesLanguages')
    languages = getLanguages(context)

    for rid, ob in enRDFRepo.objectItems():
        if 'reports_' in rid:
            theme = IThemeTagging(ob).tags[0]
            rssTemplate = ('http://reports.eea.europa.eu/reports_local.rdf?'
                           'select=public&image=yes&replang=%s&theme=%s')
            rssTitle = _(u'Reports')
            newRss = oldRss = 0
            for lang, _unused in languages:
                translation = ob.getTranslation(lang)
                if translation is None:
                    ob.addTranslation(lang)
                    translation = ob.getTranslation(lang)
                    transaction.savepoint()
                    newRss += 1
                else:
                    oldRss += 1

                IThemeTagging(translation).tags = IThemeTagging(ob).tags
                translation.unmarkCreationFlag()
                translation.setTitle(translate(rssTitle, target_language=lang))
                translation.setUrl('/%s/themes/%s/reports' % (lang, theme))
                rssUrl = rssTemplate % (lang, theme)
                translation.setFeedURL(rssUrl)
                translation.setLanguage(lang)
                translation.setEntriesSize(10000)
                translation.setEntriesWithDescription(0)
                translation.updateFeed()
                if wf.getInfoFor(translation, 'review_state') != 'published':
                    wf.doActionFor(translation,
                                   'publish',
                                   comment=('Initial publish by method '
                                            'setupLocalRDFRepositories'))
            logger.info("setupLocalRDFRepositories(): "
                        "configured %s new and %s old RSS FeedRecipe for "
                        "theme:%s" % (newRss, oldRss, theme))
def setupLocalRDFRepositories(context):

    if context.readDataFile('eeaploneadmin_localsites.txt') is None:
        return

    plone = context.getSite()
    logger = context.getLogger('eea-localsite')
    wf = getToolByName(plone, 'portal_workflow')

    enRDFRepo = plone.SITE.themes['rdf-repository']
    #siteLangView = plone.unrestrictedTraverse('@@translatedSitesLanguages')
    languages = getLanguages(context)

    for rid, ob in enRDFRepo.objectItems():
        if 'reports_' in rid:
            theme = IThemeTagging(ob).tags[0]
            rssTemplate = ('http://reports.eea.europa.eu/reports_local.rdf?'
                           'select=public&image=yes&replang=%s&theme=%s')
            rssTitle = _(u'Reports')
            newRss = oldRss = 0
            for lang, _unused in languages:
                translation = ob.getTranslation(lang)
                if translation is None:
                    ob.addTranslation(lang)
                    translation = ob.getTranslation(lang)
                    transaction.savepoint()
                    newRss += 1
                else:
                    oldRss += 1

                IThemeTagging(translation).tags = IThemeTagging(ob).tags
                translation.unmarkCreationFlag()
                translation.setTitle(translate(rssTitle, target_language=lang))
                translation.setUrl('/%s/themes/%s/reports' % (lang, theme))
                rssUrl = rssTemplate % (lang, theme)
                translation.setFeedURL(rssUrl)
                translation.setLanguage(lang)
                translation.setEntriesSize(10000)
                translation.setEntriesWithDescription(0)
                translation.updateFeed()
                if wf.getInfoFor(translation, 'review_state') != 'published':
                    wf.doActionFor(translation, 'publish',
                                   comment=('Initial publish by method '
                                            'setupLocalRDFRepositories'))
            logger.info("setupLocalRDFRepositories(): "
                        "configured %s new and %s old RSS FeedRecipe for "
                        "theme:%s" % (newRss, oldRss, theme))
Exemple #3
0
    def sameTypeByTheme(self, constraints=None):
        """NOTE: returns full info. The results are limited in number so
        we can afford this
        :param constraints: a dict which constraints the result of the query
        """
        # doesn't return latest item found at
        # www/SITE/themes/natural/publications
        # which was www/SITE/publications/consumption-and-the-environment-2012
        defaultConstraints = {
            'review_state': 'published',
            'sort_limit': 3,
            'queryThemesSeparately': True
        }
        if constraints:
            defaultConstraints.update(constraints)
        limitResults = defaultConstraints['sort_limit']
        result = self.sameTheme(portal_type=self.context.portal_type,
                                constraints=defaultConstraints)
        byTheme = {}

        brainsWithMultipleThemes = []
        for annotatedBrain in result:
            themes = annotatedBrain['commonThemesIds']
            if themes:
                theme = themes[0]
                themeObjs = byTheme.get(theme, [])
                # save items with multiple themes in case we will need them
                # later if we have less results per theme
                if len(themes) > 1:
                    brainsWithMultipleThemes.append(annotatedBrain)

                if len(themeObjs) < limitResults:
                    themeObjs.append(annotatedBrain)
                    byTheme[theme] = themeObjs

        # check if we have the right amount of items based on limitResults
        # for every theme
        for theme in byTheme:
            if len(byTheme[theme]) < limitResults:
                for annotatedBrain in brainsWithMultipleThemes:
                    if theme in annotatedBrain['commonThemesIds']:
                        byTheme[theme].append(annotatedBrain)
                    # break if we already have enough results for the given
                    # theme
                    if not len(byTheme[theme]) < limitResults:
                        break

        # now we have the themes in a dictionary, put them in a list instead
        themes = []
        vocabFactory = getUtility(IVocabularyFactory, name="Allowed themes")
        themesVocab = vocabFactory(self)
        contextThemes = self._contextThemes()
        for themename in contextThemes:
            theme = byTheme.get(themename, None)
            if theme:
                # disabled as auto relation macro from document_relateditems
                # is no longer used on account of pour performance see ticket
                # https://taskman.eionet.europa.eu/issues/7452
                # disabled as part of ticket #13771
                # and added back as part of ticket #13994
                url = IThemeMoreLink(self.context).url(themename)
                try:
                    themeTitle = themesVocab.getTerm(themename).title
                except LookupError:
                    logger.error('unable to retrieve theme name %s from %s',
                                 themename, self.context.absolute_url())
                    continue
                themes.append({
                    'name': _(str(themeTitle)),
                    'items': theme,
                    'more_link': url
                })

        for dicts in themes:
            # 9272 reverse sort of latest addition
            dicts['items'].reverse()
        return themes
def themecentreFix(context):
    if context.readDataFile('eeaploneadmin_localsites.txt') is None:
        return

    plone = context.getSite()
    logger = context.getLogger('eea-localsite')
    wf = getToolByName(plone, 'portal_workflow')
    catalog = getToolByName(plone, 'portal_catalog')
    #siteLangView = plone.unrestrictedTraverse('@@translatedSitesLanguages')
    languages = getLanguages(context)

    navman = plone.portal_navigationmanager.default

    for lang, _unused in languages:
        local = getattr(plone, lang, None)
        if local is None:
            continue
        highlights = local['highlights']
        pressReleases = local['pressroom']['newsreleases']

        for f in local.themes.objectValues():
            default = f.getCanonical().getDefaultPage()
            if default is not None and hasattr(f, default):
                intro = f[default]
                f.setDefaultPage(intro.getId())
                intro.setLayout('themecentre_view')
            else:
                logger.info('No intro page for %s' % f.absolute_url())
            if f.getId() in themecentres2MovePressIn:
                # find all highlights and pressreleases in
                # this theme centre and move theme
                # out since the themecentre is unpublished
                press = catalog(path='/'.join(f.getPhysicalPath()),
                                portal_type=['Highlight', 'PressRelease'],
                                Language='all')

                for b in press:
                    obj = b.getObject()
                    parent = aq_parent(obj)
                    cut = parent.manage_cutObjects(ids=[
                        b.getId,
                    ])
                    if b.portal_type == 'Highlight':
                        highlights.manage_pasteObjects(cut)
                    elif b.portal_type == 'PressRelease':
                        pressReleases.manage_pasteObjects(cut)

            if not hasattr(aq_base(f), 'reports') and hasattr(
                    aq_base(f.getCanonical()), 'reports'):
                reportRSS = getattr(local.themes['rdf-repository'],
                                    'reports_%s' % f.getId(), None)
                if reportRSS is not None:
                    reportsEN = f.getCanonical()['reports']
                    reportsEN.addTranslation(lang)
                    doc = reportsEN.getTranslation(lang)
                    transaction.savepoint()
                    doc.setTitle(translate(_('Reports'), target_language=lang))
                    doc.setRelatedItems(reportRSS.UID())
                    if wf.getInfoFor(reportsEN, 'review_state') == 'published':
                        wf.doActionFor(
                            doc,
                            'publish',
                            comment='Unpublish on local site migration')

        if navman.hasTranslation(lang):
            try:
                themes = navman.getTranslation(lang)['themes']
                logger.info('Removing themes in %s' % themes.absolute_url())
                themes.manage_delObjects(
                    ids=navigationItems2RemoveFromTranslatedMenues)
            except Exception:
                logger.info('FAILED Removing menu themes %s' % lang)
def setupLocalSites(context):

    if context.readDataFile('eeaploneadmin_localsites.txt') is None:
        return

    plone = context.getSite()
    logger = context.getLogger('eea-localsite')

    qi = getToolByName(plone, 'portal_quickinstaller')
    if not qi.isProductInstalled('RedirectionTool'):
        logger.info("EEAPloneAdmin:local-sites: RedirectionTool "
                    "needs to be installed")
        return

    sendWorkflowEmails = plone.getProperty('send_workflow_emails')
    if sendWorkflowEmails is None:
        plone.manage_addProperty('send_workflow_emails', False, 'boolean')
        sendWorkflowEmails = True
    else:
        plone.manage_changeProperties(send_workflow_emails=False)

    languages = getLanguages(context)
    logger.info("EEAPloneAdmin:local-sites: setup local sites")
    wf = getToolByName(plone, 'portal_workflow')
    utils = getToolByName(plone, 'plone_utils')

    local = getattr(plone, 'SITE')

    en = local
    title = _(u'European Environment Agency')

    if not hasattr(en, 'introduction'):
        en.invokeFactory('Document', id='introduction', title='Introduction')
    enIntro = en['introduction']

    if not hasattr(en, 'reports'):
        en.invokeFactory('Folder', id='reports', title='Reports')
        enReportsFolder = en['reports']
        enReportsFolder.invokeFactory('Document',
                                      id='reports',
                                      title='Reports')
        enReportsFolder.setDefaultPage('reports')
    enReportsFolder = en['reports']
    enReports = enReportsFolder['reports']

    for lang, _unused in languages:
        alreadyDone = []

        if not DevelopmentMode and hasattr(plone, lang):
            # if we are in production we don't want to change
            # already migrated local sites
            logger.info("Skipping language %s" % lang)
            continue

        translation = en.getTranslation(lang)
        if translation is None:
            en.addTranslation(lang)
            transaction.savepoint()
            translation = en.getTranslation(lang)
            translation.setId(lang)
            translation.unmarkCreationFlag()
            wf.doActionFor(translation,
                           'publish',
                           comment='Initial publish by method setupLocalSite')
            alsoProvides(translation, INavigationRoot)
            logger.info("added localsite %s" % lang)

        if translation.getProperty('navigationmanager_site') is None:
            translation.manage_addProperty('navigationmanager_site',
                                           'default-%s' % lang, 'string')

        translation.setLayout('frontpage_view')
        translation.setTitle(translate(title, target_language=lang))

        for path, portalType, msgId in translateFromSite:
            paths = path.split('/')
            obj = en
            for p in paths:
                obj = getattr(obj, p, None)
                if obj is None:
                    logger.info("EEAPloneAdmin:local-sites: "
                                "WARNING No existing object %s" % path)
                    continue
                if obj in alreadyDone:
                    continue

                doc = obj.getTranslation(lang)
                if doc is None:
                    obj.addTranslation(lang)
                    doc = obj.getTranslation(lang)
                    doc.unmarkCreationFlag()
                    originalState = wf.getInfoFor(obj, 'review_state')
                    if originalState == 'published':
                        wf.doActionFor(
                            doc,
                            'publish',
                            comment='Initial publish by method setupLocalSite')
                    elif originalState == 'visible' and portalType != 'Folder':
                        wf.doActionFor(
                            doc,
                            'submit',
                            comment='Initial submit by method setupLocalSite')
                        wf.doActionFor(
                            doc,
                            'show',
                            comment='Initial show by method setupLocalSite')

                    doc.setTitle(
                        translate(_(msgId or obj.Title()),
                                  target_language=lang))

                if obj.getId() in excludeFromNav:
                    doc.setExcludeFromNav(True)

                if utils.isDefaultPage(obj):
                    parent = aq_parent(aq_inner(doc))
                    parent.setDefaultPage(doc.getId())

                if obj.getProperty('layout') is not None:
                    doc.setLayout(obj.getLayout())

                doc.reindexObject()
                alreadyDone.append(obj)
                transaction.savepoint()

        if not hasattr(translation, 'introduction'):
            xliffMarshaller = getComponent('atxliff')
            TITLE = re.compile(
                """&lt;tr&gt; \r\n          &lt;td width="100%" colspan="3" valign="top" class="TeaserBoxHeaderEEA30sec" align="center"&gt; \r\n            &lt;p class="head0w"&gt;(.*)&lt;/p&gt;\r\n          &lt;/td&gt;\r\n        &lt;/tr&gt;\r\n        """
            )
            TITLE_TO_REMOVE = re.compile(
                """&lt;tr&gt; \r\n          &lt;td width="100%" colspan="3" valign="top" class="TeaserBoxHeaderEEA30sec" align="center"&gt; \r\n            &lt;p class="head0w"&gt;.*&lt;/p&gt;\r\n          &lt;/td&gt;\r\n        &lt;/tr&gt;\r\n        """
            )
            try:
                filename = os.path.join(package_home(GLOBALS), 'exportimport',
                                        'local-sites',
                                        'introduction-%s.xlf' % lang)
                xliff = open(filename, 'r').read()
                newTitle = TITLE.findall(xliff)
                xliff = TITLE_TO_REMOVE.sub('', xliff)
                # set path to the english introduction
                xliff = xliff.replace(
                    'original="/index_html"',
                    'original="%s"' % '/'.join(enIntro.getPhysicalPath()))
                # in plone the body field is called text
                xliff = xliff.replace('id="body"', 'id="text"')
                # fix xhtml
                xliff = xliff.replace('&lt;br/&gt;', '&lt;br /&gt;')
                # fix broke resolveuid
                # about-us/governance/intro - List of Management Board Members
                xliff = xliff.replace(
                    'resolveuid/3374ee862f322175658ae0109cfa4d8d',
                    'resolveuid/883275041407e0cfea1bdfe9961f2252')
                # about-us/governance/intro -
                # List of Scientific Committee members
                xliff = xliff.replace(
                    'resolveuid/c48511d8d406547c9a6ce84ee94dc781',
                    'resolveuid/7957a7529ed5df88caa7ad40ee9859f2')
                xliffMarshaller.demarshall(enIntro,
                                           xliff,
                                           useTidy=True,
                                           keepHTML=False)
                intro = enIntro.getTranslation(lang)
                intro.unmarkCreationFlag()
                if len(newTitle) == 2:
                    intro.setTitle(newTitle[1])
                else:
                    logger.info("EEAPloneAdmin:local-sites title not "
                                "changed for %s" % filename)

            except Exception:
                logger.info("EEAPloneAdmin:local-sites ERROR failed "
                            "to load %s" % filename)

        if not hasattr(translation, 'reports'):
            rssTitle = _(u'Reports')

            # reports folder
            enReportsFolder.addTranslation(lang)
            rfolder = enReportsFolder.getTranslation(lang)
            rfolder.unmarkCreationFlag()
            rfolder.setTitle(translate(rssTitle, target_language=lang))
            rfolder.manage_addProperty('navigationmanager_menuid', 'products',
                                       'string')

            enReports.addTranslation(lang)
            doc = enReports.getTranslation(lang)
            doc.unmarkCreationFlag()
            doc.setTitle(translate(rssTitle, target_language=lang))
            rfolder.setDefaultPage('reports')

            transaction.savepoint()
            wf.doActionFor(doc,
                           'publish',
                           comment='Initial publish by method setupLocalSite')

    setupTranslateSiteStructure(context)
    setupNavigationManager(context)
    setupLocalRDFRepositories(context)
    themecentreFix(context)
    importTranslations(context)
    setupRetagAllTranslations(context)
    fixPromotion(context)
    fixLangIndependentFields(context)

    catalog = getToolByName(plone, 'portal_catalog')
    # catalog.manage_catalogReindex redirects so we do it here
    pgthreshold = catalog._getProgressThreshold()
    handler = ZLogHandler(pgthreshold) if pgthreshold > 0 else None
    catalog.refreshCatalog(clear=1, pghandler=handler)

    plone.manage_changeProperties(send_workflow_emails=sendWorkflowEmails)
    logger.info("LOCAL-SITES are up online")
def setupNavigationManager(context):
    if context.readDataFile('eeaploneadmin_localsites.txt') is None:
        return
    plone = context.getSite()
    logger = context.getLogger('eea-localsite')

    languages = getLanguages(context)

    navman = plone.portal_navigationmanager
    wf = getToolByName(plone, 'portal_workflow')

    if navman.getProperty('navigationmanager_fallback') is None:
        navman.manage_addProperty('navigationmanager_fallback', True,
                                  'boolean')

    site = getattr(plone, 'SITE')
    en = getattr(navman, 'default')
    navigationRoots = en.contentValues()
    en.setLanguage('en')
    portal_url = _useCorrectUrlForWhereWeAreRunningThis(plone)

    for lang, _unused in languages:
        if not site.hasTranslation(lang):
            # a language that doesn't have local site
            continue
        translation = en.getTranslation(lang)
        if translation is None:
            en.addTranslation(lang)
            translation = en.getTranslation(lang)
            transaction.savepoint()
            wf.doActionFor(translation,
                           'publish',
                           comment='Initial publish by method setupLocalSite')

        translation.unmarkCreationFlag()
        translation.setTitle(translate(_(en.Title()), target_language=lang))

        homeUrl = _useCorrectUrlForWhereWeAreRunningThis(
            site.getTranslation(lang))
        translation.setUrl(_fixNavigationUrls(portal_url, homeUrl, '', site))
        for root in navigationRoots:
            if root.Language() is None:
                root.setLanguage('en')
            translation = root.getTranslation(lang)
            if translation is None:
                root.addTranslation(lang)
                translation = root.getTranslation(lang)
                transaction.savepoint()
                if root.getId() not in navigationRoot2NotPublish:
                    wf.doActionFor(
                        translation,
                        'publish',
                        comment='Initial publish by method setupLocalSite')

            translation.unmarkCreationFlag()
            translation.setTitle(
                translate(_(root.Title()), target_language=lang))

            if root.getId() == 'eeahome':
                translation.setUrl(
                    _fixNavigationUrls(portal_url, homeUrl, '', site))
            else:
                translation.setUrl(
                    _fixNavigationUrls(portal_url, root.getUrl(), lang, site))
            translation.reindexObject()

            toTranslate = navigationMenues2Translate.get(root.getId(), None)
            for obj in root.contentValues():
                # if toTranslate is None then translate all
                # otherwise what is in the list
                if toTranslate is None or obj.getId() in toTranslate:
                    translation = obj.getTranslation(lang)
                    if translation is None:
                        obj.addTranslation(lang)
                        translation = obj.getTranslation(lang)
                        wf.doActionFor(
                            translation,
                            'publish',
                            comment='Initial publish by method setupLocalSite')
                    translation.unmarkCreationFlag()
                    title = _(obj.Title())
                    translation.setTitle(translate(title,
                                                   target_language=lang))
                    translation.setUrl(
                        _fixNavigationUrls(portal_url, obj.getUrl(), lang,
                                           site))
                    translation.reindexObject()

    # change main menu urls to the host we are using dev1 or webdev if we
    # are not on main site
    if 'www.eea.europa.eu' not in portal_url:
        for n in navigationRoots:
            n.setUrl(_fixNavigationUrls(portal_url, n.getUrl(), '', site))
            for o in n.contentValues():
                o.setUrl(_fixNavigationUrls(portal_url, o.getUrl(), '', site))

    logger.info("setupNavigationManager(): "
                "NavigationManager setup with local navigation")
    for lang, msgs in untranslatedMessages.items():
        pofile = codecs.open('/tmp/untranslated-navigation-%s.po' % lang,
                             'wb',
                             encoding='utf8')
        for msgid, msgstr in msgs.items():
            pofile.writelines('msgid "%s"\nmsgstr "%s"\n\n' % (msgid, msgstr))

        pofile.close()
def setupTranslateSiteStructure(context):
    if context.readDataFile('eeaploneadmin_localsites.txt') is None:
        return

    plone = context.getSite()
    logger = context.getLogger('eea-localsite')

    languages = getLanguages(context)

    catalog = getToolByName(plone, 'portal_catalog')
    utils = getToolByName(plone, 'plone_utils')
    wf = getToolByName(plone, 'portal_workflow')
    folders = catalog(path={
        'query': '/www/SITE',
    },
                      portal_type=['Folder', 'ATFolder', 'Topic'],
                      Language='en')
    foldersByPath = {}

    for f in folders:
        url = f.getPath()
        for path in structureNot2Translate:
            if path in url:
                break
        else:
            foldersByPath[url] = f

    folderPaths = foldersByPath.keys()
    folderPaths.sort()

    logger.info('PROGRESS: start: %s' % len(folderPaths))

    for lang, _unused in languages:
        logger.info('PROGRESS: language %s' % lang)
        for path in folderPaths:
            f = foldersByPath[path]
            if 'portal_factory' in f.getURL():
                # we can have portal factory
                # indexed objects which shouldn't be translated
                continue

            obj = f.getObject()

            translation = obj.getTranslation(lang)
            if translation is None:
                obj.addTranslation(lang)
                translation = obj.getTranslation(lang)
                transaction.savepoint()

                originalState = wf.getInfoFor(obj, 'review_state')
                if originalState != wf.getInfoFor(translation, 'review_state'):
                    if originalState == 'published':
                        wf.doActionFor(
                            translation,
                            'publish',
                            comment='Initial publish by method setupLocalSite')
                    elif (originalState == 'visible'
                          and obj.portal_type != 'Folder'):
                        wf.doActionFor(
                            translation,
                            'submit',
                            comment='Initial submit by method setupLocalSite')
                        wf.doActionFor(
                            translation,
                            'show',
                            comment='Initial show by method setupLocalSite')

                # we only translate title when creating translation
                # later we assume it's translated with imports and should
                # not be retranslated if the step is reimported
                title = _(obj.Title())
                translation.setTitle(
                    translate(title, target_language=lang, output=True))

                # disable rename after creation
                translation.unmarkCreationFlag()

            # copy layout
            if obj.getProperty('layout') is not None:
                translation.setLayout(obj.getLayout())
            # copy interfaces of original
            directlyProvides(translation, directlyProvidedBy(obj))
            # disable translation of parent on next edit
            if hasattr(translation, '_lp_default_page'):
                delattr(translation, '_lp_default_page')
            # copy exclude from nav setting
            if hasattr(aq_base(obj), 'getExcludeFromNav'):
                try:
                    translation.setExcludeFromNav(obj.getExcludeFromNav())
                except Exception:
                    logger.info("EEAPloneAdmin:local-sites: "
                                "EXCLUDE-FROM-NAV-ERROR for %s" %
                                obj.absolute_url())
            if obj.portal_type in ['Topic']:
                origCustFields = obj.getCustomViewFields()
                if list(origCustFields) != ['Title']:
                    #fields are already set use those
                    translation.setCustomViewFields(origCustFields)
                else:
                    # we only have default , we only need publish date
                    translation.setCustomViewFields(['EffectiveDate'])

            if (utils.isDefaultPage(obj)
                    and not utils.isDefaultPage(translation)):
                parent = aq_parent(aq_inner(translation))
                parent.setDefaultPage(translation.getId())

            if (obj.getProperty('navigationmanager_menuid')
                    and translation.getProperty('navigationmanager_menuid') is
                    None):
                translation.manage_addProperty(
                    'navigationmanager_menuid',
                    obj.getProperty('navigationmanager_menuid'), 'string')

            translation.reindexObject()
        logger.info('PROGRESS: %s done' % lang)
        transaction.savepoint()
    logger.info(" Structure translated")
def themecentreFix(context):
    if context.readDataFile('eeaploneadmin_localsites.txt') is None:
        return

    plone = context.getSite()
    logger = context.getLogger('eea-localsite')
    wf = getToolByName(plone, 'portal_workflow')
    catalog = getToolByName(plone, 'portal_catalog')
    #siteLangView = plone.unrestrictedTraverse('@@translatedSitesLanguages')
    languages = getLanguages(context)

    navman = plone.portal_navigationmanager.default

    for lang, _unused in languages:
        local = getattr(plone, lang, None)
        if local is None:
            continue
        highlights = local['highlights']
        pressReleases = local['pressroom']['newsreleases']

        for f in local.themes.objectValues():
            default = f.getCanonical().getDefaultPage()
            if default is not None and hasattr(f, default):
                intro = f[default]
                f.setDefaultPage(intro.getId())
                intro.setLayout('themecentre_view')
            else:
                logger.info('No intro page for %s' % f.absolute_url())
            if f.getId() in themecentres2MovePressIn:
                # find all highlights and pressreleases in
                # this theme centre and move theme
                # out since the themecentre is unpublished
                press = catalog(path='/'.join(f.getPhysicalPath()),
                                portal_type=['Highlight', 'PressRelease'],
                                Language='all')

                for b in press:
                    obj = b.getObject()
                    parent = aq_parent(obj)
                    cut = parent.manage_cutObjects(ids=[b.getId, ])
                    if b.portal_type == 'Highlight':
                        highlights.manage_pasteObjects(cut)
                    elif b.portal_type == 'PressRelease':
                        pressReleases.manage_pasteObjects(cut)

            if not hasattr(aq_base(f), 'reports') and hasattr(
                aq_base(f.getCanonical()), 'reports'):
                reportRSS = getattr(local.themes['rdf-repository'],
                                    'reports_%s' % f.getId(), None)
                if reportRSS is not None:
                    reportsEN = f.getCanonical()['reports']
                    reportsEN.addTranslation(lang)
                    doc = reportsEN.getTranslation(lang)
                    transaction.savepoint()
                    doc.setTitle(translate(_('Reports'), target_language=lang))
                    doc.setRelatedItems(reportRSS.UID())
                    if wf.getInfoFor(reportsEN, 'review_state') == 'published':
                        wf.doActionFor(doc, 'publish',
                                    comment='Unpublish on local site migration')

        if navman.hasTranslation(lang):
            try:
                themes = navman.getTranslation(lang)['themes']
                logger.info('Removing themes in %s' % themes.absolute_url())
                themes.manage_delObjects(
                    ids=navigationItems2RemoveFromTranslatedMenues)
            except Exception:
                logger.info('FAILED Removing menu themes %s' % lang)
def setupLocalSites(context):

    if context.readDataFile('eeaploneadmin_localsites.txt') is None:
        return

    plone = context.getSite()
    logger = context.getLogger('eea-localsite')

    qi = getToolByName(plone, 'portal_quickinstaller')
    if not qi.isProductInstalled('RedirectionTool'):
        logger.info("EEAPloneAdmin:local-sites: RedirectionTool "
                    "needs to be installed")
        return

    sendWorkflowEmails = plone.getProperty('send_workflow_emails')
    if sendWorkflowEmails is None:
        plone.manage_addProperty('send_workflow_emails', False, 'boolean')
        sendWorkflowEmails = True
    else:
        plone.manage_changeProperties(send_workflow_emails=False)

    languages = getLanguages(context)
    logger.info("EEAPloneAdmin:local-sites: setup local sites")
    wf = getToolByName(plone, 'portal_workflow')
    utils = getToolByName(plone, 'plone_utils')

    local = getattr(plone, 'SITE')

    en = local
    title = _(u'European Environment Agency')

    if not hasattr(en, 'introduction'):
        en.invokeFactory('Document', id='introduction', title='Introduction')
    enIntro = en['introduction']

    if not hasattr(en, 'reports'):
        en.invokeFactory('Folder', id='reports', title='Reports')
        enReportsFolder = en['reports']
        enReportsFolder.invokeFactory('Document', id='reports', title='Reports')
        enReportsFolder.setDefaultPage('reports')
    enReportsFolder = en['reports']
    enReports = enReportsFolder['reports']

    for lang, _unused  in languages:
        alreadyDone = []

        if not DevelopmentMode and hasattr(plone, lang):
            # if we are in production we don't want to change
            # already migrated local sites
            logger.info("Skipping language %s" % lang)
            continue

        translation = en.getTranslation(lang)
        if translation is None:
            en.addTranslation(lang)
            transaction.savepoint()
            translation = en.getTranslation(lang)
            translation.setId(lang)
            translation.unmarkCreationFlag()
            wf.doActionFor(translation, 'publish',
                           comment='Initial publish by method setupLocalSite')
            alsoProvides(translation, INavigationRoot)
            logger.info("added localsite %s" % lang)

        if translation.getProperty('navigationmanager_site') is None:
            translation.manage_addProperty('navigationmanager_site',
                                         'default-%s' % lang,
                                         'string')

        translation.setLayout('frontpage_view')
        translation.setTitle(translate(title, target_language=lang))

        for path, portalType, msgId in translateFromSite:
            paths = path.split('/')
            obj = en
            for p in paths:
                obj = getattr(obj, p, None)
                if obj is None:
                    logger.info("EEAPloneAdmin:local-sites: "
                                "WARNING No existing object %s" % path)
                    continue
                if obj in alreadyDone:
                    continue

                doc = obj.getTranslation(lang)
                if doc is None:
                    obj.addTranslation(lang)
                    doc = obj.getTranslation(lang)
                    doc.unmarkCreationFlag()
                    originalState = wf.getInfoFor(obj, 'review_state')
                    if originalState == 'published':
                        wf.doActionFor(doc, 'publish',
                            comment='Initial publish by method setupLocalSite')
                    elif originalState == 'visible' and portalType != 'Folder':
                        wf.doActionFor(doc, 'submit',
                              comment='Initial submit by method setupLocalSite')
                        wf.doActionFor(doc, 'show',
                                comment='Initial show by method setupLocalSite')

                    doc.setTitle(translate(_(msgId or obj.Title()),
                                           target_language=lang))

                if obj.getId() in excludeFromNav:
                    doc.setExcludeFromNav(True)

                if utils.isDefaultPage(obj):
                    parent = aq_parent(aq_inner(doc))
                    parent.setDefaultPage(doc.getId())

                if obj.getProperty('layout') is not None:
                    doc.setLayout(obj.getLayout())

                doc.reindexObject()
                alreadyDone.append(obj)
                transaction.savepoint()


        if not hasattr(translation, 'introduction'):
            xliffMarshaller = getComponent('atxliff')
            TITLE = re.compile("""&lt;tr&gt; \r\n          &lt;td width="100%" colspan="3" valign="top" class="TeaserBoxHeaderEEA30sec" align="center"&gt; \r\n            &lt;p class="head0w"&gt;(.*)&lt;/p&gt;\r\n          &lt;/td&gt;\r\n        &lt;/tr&gt;\r\n        """)
            TITLE_TO_REMOVE = re.compile("""&lt;tr&gt; \r\n          &lt;td width="100%" colspan="3" valign="top" class="TeaserBoxHeaderEEA30sec" align="center"&gt; \r\n            &lt;p class="head0w"&gt;.*&lt;/p&gt;\r\n          &lt;/td&gt;\r\n        &lt;/tr&gt;\r\n        """)
            try:
                filename = os.path.join(package_home(GLOBALS),
                    'exportimport', 'local-sites', 'introduction-%s.xlf' % lang)
                xliff = open(filename, 'r').read()
                newTitle = TITLE.findall(xliff)
                xliff = TITLE_TO_REMOVE.sub('', xliff)
                # set path to the english introduction
                xliff = xliff.replace(
                    'original="/index_html"', 'original="%s"' % '/'.join(
                        enIntro.getPhysicalPath()))
                # in plone the body field is called text
                xliff = xliff.replace('id="body"', 'id="text"')
                # fix xhtml
                xliff = xliff.replace('&lt;br/&gt;', '&lt;br /&gt;')
                # fix broke resolveuid
                # about-us/governance/intro - List of Management Board Members
                xliff = xliff.replace(
                    'resolveuid/3374ee862f322175658ae0109cfa4d8d',
                    'resolveuid/883275041407e0cfea1bdfe9961f2252')
                # about-us/governance/intro -
                # List of Scientific Committee members
                xliff = xliff.replace(
                    'resolveuid/c48511d8d406547c9a6ce84ee94dc781',
                    'resolveuid/7957a7529ed5df88caa7ad40ee9859f2')
                xliffMarshaller.demarshall(enIntro, xliff, useTidy=True,
                                           keepHTML=False)
                intro = enIntro.getTranslation(lang)
                intro.unmarkCreationFlag()
                if len(newTitle) == 2:
                    intro.setTitle(newTitle[1])
                else:
                    logger.info("EEAPloneAdmin:local-sites title not "
                                "changed for %s" % filename)

            except Exception:
                logger.info("EEAPloneAdmin:local-sites ERROR failed "
                            "to load %s" % filename)


        if not hasattr(translation, 'reports'):
            rssTitle = _(u'Reports')

            # reports folder
            enReportsFolder.addTranslation(lang)
            rfolder = enReportsFolder.getTranslation(lang)
            rfolder.unmarkCreationFlag()
            rfolder.setTitle(translate(rssTitle, target_language=lang))
            rfolder.manage_addProperty('navigationmanager_menuid',
                                         'products',
                                         'string')

            enReports.addTranslation(lang)
            doc = enReports.getTranslation(lang)
            doc.unmarkCreationFlag()
            doc.setTitle(translate(rssTitle, target_language=lang))
            rfolder.setDefaultPage('reports')

            transaction.savepoint()
            wf.doActionFor(doc, 'publish',
                           comment='Initial publish by method setupLocalSite')

    setupTranslateSiteStructure(context)
    setupNavigationManager(context)
    setupLocalRDFRepositories(context)
    themecentreFix(context)
    importTranslations(context)
    setupRetagAllTranslations(context)
    fixPromotion(context)
    fixLangIndependentFields(context)

    catalog = getToolByName(plone, 'portal_catalog')
    # catalog.manage_catalogReindex redirects so we do it here
    pgthreshold = catalog._getProgressThreshold()
    handler = ZLogHandler(pgthreshold) if pgthreshold > 0 else None
    catalog.refreshCatalog(clear=1, pghandler=handler)

    plone.manage_changeProperties(send_workflow_emails=sendWorkflowEmails)
    logger.info("LOCAL-SITES are up online")
def setupNavigationManager(context):
    if context.readDataFile('eeaploneadmin_localsites.txt') is None:
        return
    plone = context.getSite()
    logger = context.getLogger('eea-localsite')

    languages = getLanguages(context)

    navman = plone.portal_navigationmanager
    wf = getToolByName(plone, 'portal_workflow')

    if navman.getProperty('navigationmanager_fallback') is None:
        navman.manage_addProperty('navigationmanager_fallback',
                                  True,
                                  'boolean')


    site = getattr(plone, 'SITE')
    en = getattr(navman, 'default')
    navigationRoots = en.contentValues()
    en.setLanguage('en')
    portal_url = _useCorrectUrlForWhereWeAreRunningThis(plone)

    for lang, _unused in languages:
        if not site.hasTranslation(lang):
            # a language that doesn't have local site
            continue
        translation = en.getTranslation(lang)
        if translation is None:
            en.addTranslation(lang)
            translation = en.getTranslation(lang)
            transaction.savepoint()
            wf.doActionFor(translation, 'publish',
                           comment='Initial publish by method setupLocalSite')

        translation.unmarkCreationFlag()
        translation.setTitle(translate(_(en.Title()), target_language=lang))

        homeUrl = _useCorrectUrlForWhereWeAreRunningThis(
            site.getTranslation(lang))
        translation.setUrl(_fixNavigationUrls(portal_url, homeUrl, '', site))
        for root in navigationRoots:
            if root.Language() is None:
                root.setLanguage('en')
            translation = root.getTranslation(lang)
            if translation is None:
                root.addTranslation(lang)
                translation = root.getTranslation(lang)
                transaction.savepoint()
                if root.getId() not in navigationRoot2NotPublish:
                    wf.doActionFor(translation, 'publish',
                             comment='Initial publish by method setupLocalSite')

            translation.unmarkCreationFlag()
            translation.setTitle(translate(_(root.Title()),
                                           target_language=lang))

            if root.getId() == 'eeahome':
                translation.setUrl(_fixNavigationUrls(portal_url,
                                                      homeUrl, '', site))
            else:
                translation.setUrl(_fixNavigationUrls(portal_url,
                                                     root.getUrl(), lang, site))
            translation.reindexObject()

            toTranslate = navigationMenues2Translate.get(root.getId(), None)
            for obj in root.contentValues():
                # if toTranslate is None then translate all
                # otherwise what is in the list
                if toTranslate is None or obj.getId() in toTranslate:
                    translation = obj.getTranslation(lang)
                    if translation is None:
                        obj.addTranslation(lang)
                        translation = obj.getTranslation(lang)
                        wf.doActionFor(translation, 'publish',
                             comment='Initial publish by method setupLocalSite')
                    translation.unmarkCreationFlag()
                    title = _(obj.Title())
                    translation.setTitle(translate(title, target_language=lang))
                    translation.setUrl(_fixNavigationUrls(portal_url,
                                                      obj.getUrl(), lang, site))
                    translation.reindexObject()

    # change main menu urls to the host we are using dev1 or webdev if we
    # are not on main site
    if 'www.eea.europa.eu' not in portal_url:
        for n in navigationRoots:
            n.setUrl(_fixNavigationUrls(portal_url, n.getUrl(), '', site))
            for o in n.contentValues():
                o.setUrl(_fixNavigationUrls(portal_url, o.getUrl(), '', site))

    logger.info("setupNavigationManager(): "
                "NavigationManager setup with local navigation")
    for lang, msgs in untranslatedMessages.items():
        pofile = codecs.open('/tmp/untranslated-navigation-%s.po' % lang,
                             'wb', encoding='utf8')
        for msgid, msgstr in msgs.items():
            pofile.writelines('msgid "%s"\nmsgstr "%s"\n\n' % (msgid, msgstr))

        pofile.close()
def setupTranslateSiteStructure(context):
    if context.readDataFile('eeaploneadmin_localsites.txt') is None:
        return

    plone = context.getSite()
    logger = context.getLogger('eea-localsite')

    languages = getLanguages(context)

    catalog = getToolByName(plone, 'portal_catalog')
    utils = getToolByName(plone, 'plone_utils')
    wf = getToolByName(plone, 'portal_workflow')
    folders = catalog(path={'query': '/www/SITE', },
                      portal_type=['Folder', 'ATFolder', 'Topic'],
                      Language='en'
                      )
    foldersByPath = {}

    for f in folders:
        url = f.getPath()
        for path in structureNot2Translate:
            if path in url:
                break
        else:
            foldersByPath[url] = f

    folderPaths = foldersByPath.keys()
    folderPaths.sort()

    logger.info('PROGRESS: start: %s' % len(folderPaths))

    for lang, _unused in languages:
        logger.info('PROGRESS: language %s' % lang)
        for path in folderPaths:
            f = foldersByPath[path]
            if 'portal_factory' in f.getURL():
                # we can have portal factory
                # indexed objects which shouldn't be translated
                continue

            obj = f.getObject()

            translation = obj.getTranslation(lang)
            if translation is None:
                obj.addTranslation(lang)
                translation = obj.getTranslation(lang)
                transaction.savepoint()

                originalState = wf.getInfoFor(obj, 'review_state')
                if originalState != wf.getInfoFor(translation, 'review_state'):
                    if originalState == 'published':
                        wf.doActionFor(translation, 'publish',
                            comment='Initial publish by method setupLocalSite')
                    elif (originalState == 'visible' and
                          obj.portal_type != 'Folder'):
                        wf.doActionFor(translation, 'submit',
                            comment='Initial submit by method setupLocalSite')
                        wf.doActionFor(translation, 'show',
                            comment='Initial show by method setupLocalSite')

                # we only translate title when creating translation
                # later we assume it's translated with imports and should
                # not be retranslated if the step is reimported
                title = _(obj.Title())
                translation.setTitle(translate(title,
                                            target_language=lang, output=True))

                # disable rename after creation
                translation.unmarkCreationFlag()

            # copy layout
            if obj.getProperty('layout') is not None:
                translation.setLayout(obj.getLayout())
            # copy interfaces of original
            directlyProvides(translation, directlyProvidedBy(obj))
            # disable translation of parent on next edit
            if hasattr(translation, '_lp_default_page'):
                delattr(translation, '_lp_default_page')
            # copy exclude from nav setting
            if hasattr(aq_base(obj), 'getExcludeFromNav'):
                try:
                    translation.setExcludeFromNav(obj.getExcludeFromNav())
                except Exception:
                    logger.info("EEAPloneAdmin:local-sites: "
                           "EXCLUDE-FROM-NAV-ERROR for %s" % obj.absolute_url())
            if obj.portal_type in ['Topic']:
                origCustFields = obj.getCustomViewFields()
                if list(origCustFields) != ['Title']:
                    #fields are already set use those
                    translation.setCustomViewFields(origCustFields)
                else:
                    # we only have default , we only need publish date
                    translation.setCustomViewFields(['EffectiveDate'])

            if (utils.isDefaultPage(obj)
                and not utils.isDefaultPage(translation)):
                parent = aq_parent(aq_inner(translation))
                parent.setDefaultPage(translation.getId())

            if (obj.getProperty('navigationmanager_menuid') and
                translation.getProperty('navigationmanager_menuid') is None):
                translation.manage_addProperty('navigationmanager_menuid',
                                    obj.getProperty('navigationmanager_menuid'),
                                    'string')

            translation.reindexObject()
        logger.info('PROGRESS: %s done' % lang)
        transaction.savepoint()
    logger.info(" Structure translated")
    def sameTypeByTheme(self, constraints=None):
        """NOTE: returns full info. The results are limited in number so
        we can afford this
        :param constraints: a dict which constraints the result of the query
        """
        # doesn't return latest item found at
        # www/SITE/themes/natural/publications
        # which was www/SITE/publications/consumption-and-the-environment-2012
        defaultConstraints = {'review_state': 'published', 'sort_limit': 3,
                              'queryThemesSeparately': True}
        if constraints:
            defaultConstraints.update(constraints)
        limitResults = defaultConstraints['sort_limit']
        result = self.sameTheme(portal_type=self.context.portal_type,
                                constraints=defaultConstraints)
        byTheme = {}

        brainsWithMultipleThemes = []
        for annotatedBrain in result:
            themes = annotatedBrain['commonThemesIds']
            if themes:
                theme = themes[0]
                themeObjs = byTheme.get(theme, [])
                # save items with multiple themes in case we will need them
                # later if we have less results per theme
                if len(themes) > 1:
                    brainsWithMultipleThemes.append(annotatedBrain)

                if len(themeObjs) < limitResults:
                    themeObjs.append(annotatedBrain)
                    byTheme[theme] = themeObjs

        # check if we have the right amount of items based on limitResults
        # for every theme
        for theme in byTheme:
            if len(byTheme[theme]) < limitResults:
                for annotatedBrain in brainsWithMultipleThemes:
                    if theme in annotatedBrain['commonThemesIds']:
                        byTheme[theme].append(annotatedBrain)
                    # break if we already have enough results for the given
                    # theme
                    if not len(byTheme[theme]) < limitResults:
                        break

        # now we have the themes in a dictionary, put them in a list instead
        themes = []
        vocabFactory = getUtility(IVocabularyFactory, name="Allowed themes")
        themesVocab = vocabFactory(self)
        contextThemes = self._contextThemes()
        for themename in contextThemes:
            theme = byTheme.get(themename, None)
            if theme:
                # disabled as auto relation macro from document_relateditems
                # is no longer used on account of pour performance see ticket
                # https://taskman.eionet.europa.eu/issues/7452
                # disabled as part of ticket #13771
                # and added back as part of ticket #13994
                url = IThemeMoreLink(self.context).url(themename)
                try:
                    themeTitle = themesVocab.getTerm(themename).title
                except LookupError:
                    logger.error('unable to retrieve theme name %s from %s',
                                 themename, self.context.absolute_url())
                    continue
                themes.append({'name': _(
                    str(themeTitle)),
                    'items': theme,
                    'more_link': url})

        for dicts in themes:
            # 9272 reverse sort of latest addition
            dicts['items'].reverse()
        return themes