def atualiza_secoes(context): """Remove referencias a secao General. Alteramos para Noticias""" ct = api.portal.get_tool('portal_catalog') resultados = ct.searchResults(section='General', portal_type='collective.nitf.content') logger.info(u'{0} conteúdos na seção General'.format(len(resultados))) for item in resultados: # Alteramos para Noticias o = item.getObject() o.section = u'Notícias' o.reindexObject(idxs=['section']) logger.info('Conteudos atualizados') available_sections = list( api.portal.get_registry_record( 'collective.nitf.controlpanel.INITFSettings.available_sections')) if 'General' in available_sections: available_sections.remove('General') logger.info('Remove secao General') if u'Notícias' not in available_sections: available_sections.append(u'Notícias') logger.info('Adiciona secao Noticias') # Adiciona a secao Noticias api.portal.set_registry_record( 'collective.nitf.controlpanel.INITFSettings.available_sections', set(available_sections)) default_section = api.portal.get_registry_record( 'collective.nitf.controlpanel.INITFSettings.default_section') if default_section == 'General': api.portal.set_registry_record( 'collective.nitf.controlpanel.INITFSettings.default_section', u'Notícias') logger.info('Define Noticias como secao padrao')
def deprecate_resource_registries(setup_tool): """Deprecate resource registries.""" js_tool = api.portal.get_tool('portal_javascripts') for js in SCRIPTS: js_tool.unregisterResource(id=js) assert js not in js_tool.getResourceIds() # nosec logger.info('Scripts removed')
def atualiza_secoes(context): """Remove referencias a secao General. Alteramos para Noticias""" ct = api.portal.get_tool("portal_catalog") resultados = ct.searchResults(section="General", portal_type="collective.nitf.content") logger.info(u"{0} conteúdos na seção General".format(len(resultados))) for item in resultados: # Alteramos para Noticias o = item.getObject() o.section = u"Notícias" o.reindexObject(idxs=["section"]) logger.info("Conteudos atualizados") available_sections = list( api.portal.get_registry_record("collective.nitf.controlpanel.INITFSettings.available_sections") ) if "General" in available_sections: available_sections.remove("General") logger.info("Remove secao General") if u"Notícias" not in available_sections: available_sections.append(u"Notícias") logger.info("Adiciona secao Noticias") # Adiciona a secao Noticias api.portal.set_registry_record( "collective.nitf.controlpanel.INITFSettings.available_sections", set(available_sections) ) default_section = api.portal.get_registry_record("collective.nitf.controlpanel.INITFSettings.default_section") if default_section == "General": api.portal.set_registry_record("collective.nitf.controlpanel.INITFSettings.default_section", u"Notícias") logger.info("Define Noticias como secao padrao")
def install_product(context): """Instala brasil.gov.portlets""" qi = api.portal.get_tool('portal_quickinstaller') if not qi.isProductInstalled('brasil.gov.portlets'): logger.info('Instalando produto brasil.gov.portlets') qi.installProduct('brasil.gov.portlets') logger.info('brasil.gov.portlets instalado')
def aplica_view_noticias(context): """Aplica visao sumaria para pasta Noticias""" noticias = api.content.get(path='/noticias') if noticias: noticias.setLayout('folder_summary_view') noticias.reindexObject() logger.info(u'Visão sumária aplicada na pasta Notícias')
def ordernacao_pastas(portal_setup): """ Ajusta a ordenacao das pastas da raiz do portal setando ordenação padrão Plone. Similar ao ordenacao_pastas feito no upgradeStep 5000, só que ao invés de ordenar pastas pontuais ele é executado em todas as pastas. """ plone_view = portal_setup.restrictedTraverse('@@plone_portal_state') site = plone_view.portal() for pasta_id in site.objectIds(): pasta = site[pasta_id] # Se não for diretório e já estiver com a ordenação default, não faça # nada. if (not IFolder.providedBy(pasta) or isinstance(pasta.getOrdering(), DefaultOrdering)): continue # Define ordenacao padrao pasta.setOrdering() ordering = pasta.getOrdering() # A ordenacao dos itens na pasta e mantida em uma # Annotation. Aqui vamos repopula-la com os dados # corretos real = [o for o in pasta.objectIds(ordered=False)] stored = [o for o in pasta.objectIds(ordered=True)] for o in stored: ordering.notifyRemoved(o) for o in real: ordering.notifyAdded(o) logger.info('Pasta %s atualizada', pasta.Title())
def aplica_view_noticias(context): """Aplica visao sumaria para pasta Noticias""" noticias = api.content.get(path='/noticias') if noticias: noticias.setLayout('summary_view') noticias.reindexObject() logger.info(u'Visão sumária aplicada na pasta Notícias')
def atualiza_produtos_terceiros(portal_setup): """ Atualiza os profiles de produtos de terceiros.""" profiles = [ 'brasil.gov.agenda:default', 'brasil.gov.barra:default', 'brasil.gov.portlets:default', 'brasil.gov.tiles:default', 'brasil.gov.vcge:default', 'collective.cover:default', 'collective.nitf:default', 'collective.polls:default', 'sc.embedder:default', 'sc.social.like:default', ] # Somente executo o upgrade step do brasil.gov.agenda se o seu profile foi # instalado. Em versões antigas do brasil.gov.portal o brasil.gov.agenda # não era instalado. agenda_profile = '{0}:default'.format(AGENDAPROJECTNAME) if portal_setup.getLastVersionForProfile(agenda_profile) == UNKNOWN: profiles.remove(agenda_profile) for profile_id in profiles: upgrade_profile(portal_setup, profile_id) logger.info('Produtos de terceiros foram atualizados')
def install_redirection_tool(setup_tool): """Install Products.RedirectionTool.""" addon = 'RedirectionTool' qi = api.portal.get_tool('portal_quickinstaller') if not qi.isProductInstalled(addon): qi.installProduct(addon) logger.info('Products.RedirectionTool was installed')
def reindex_object_after_workflow_migration(): """ Após a migração do tipo evento, o título não fica correto e todos os objetos do tipo evento ficam como privado, portanto precisamos desse patch que reindexa os novos objetos. FIXME: Se esse erro for corrigido upstream (ver https://github.com/plone/Products.contentmigration/issues/16) e a versão de plone.app.contenttypes for corrigida no release, esse patch pode ser removido. Lembrar de alterar no setup.py colocando a versão correspondente do plone.app.contenttypes que contenha essa correção. """ def migrate_workflow(self): """migrate the workflow state """ wfh = getattr(self.old, 'workflow_history', None) if wfh: wfh = copyPermMap(wfh) self.new.workflow_history = wfh # INICIO Customização self.new.reindexObject() # FIM Customização setattr(BaseCMFMigrator, 'migrate_workflow', migrate_workflow) logger.info('Patched migrate_workflow to help in events migration')
def update_infographic_workflow(setup_tool): """Remove workflow from Infographic content type.""" wftool = api.portal.get_tool('portal_workflow') if wftool.getChainForPortalType('Infographic') != (): logger.info('Removing workflow from Infographic content type') wftool.setChainForPortalTypes(['Infographic'], '') logger.info('Done')
def fix_nitf_default_view(setup_tool): """Fix wrong value on News Article factory.""" types_tool = api.portal.get_tool('portal_types') nitf = types_tool['collective.nitf.content'] if nitf.default_view != 'view': nitf.default_view = 'view' logger.info('collective.nitf default_view fixed')
def fix_cover_columns(setup_tool): """Fix column widths on cover objects. Resulting width depends on the number of columns in a row (width = 12 / columns). """ import json def fix_column_width(layout, columns=1): """Traverse the layout tree and fix columns width.""" new_layout = [] for e in layout: if 'column-size' in e: e['column-size'] = 12 // columns if e['type'] == 'row': columns = len(e['children']) e['children'] = fix_column_width(e['children'], columns) new_layout.append(e) return new_layout logger.info('Fixing column widths on collective.cover objects') for obj in get_valid_objects(portal_type='collective.cover.content'): try: layout = json.loads(obj.cover_layout) except TypeError: continue # empty layout? try: layout = fix_column_width(layout) except KeyError: msg = "Can't fix layout for object {0}" logger.error(msg.format(obj.absolute_url_path())) obj.cover_layout = json.dumps(layout) logger.info('Done')
def install_restapi(setup_tool): """Install plone.restapi.""" addon = 'plone.restapi' qi = api.portal.get_tool('portal_quickinstaller') if not qi.isProductInstalled(addon): qi.installProduct(addon) logger.info(addon + ' was installed')
def reindex_object_after_workflow_migration(): """ Após a migração do tipo evento, o título não fica correto e todos os objetos do tipo evento ficam como privado, portanto precisamos desse patch que reindexa os novos objetos. FIXME: Se esse erro for corrigido upstream (ver https://github.com/plone/Products.contentmigration/issues/16) e a versão de plone.app.contenttypes for corrigida no release, esse patch pode ser removido. Lembrar de alterar no setup.py colocando a versão correspondente do plone.app.contenttypes que contenha essa correção. """ def migrate_workflow(self): """migrate the workflow state """ wfh = getattr(self.old, 'workflow_history', None) if wfh: wfh = copyPermMap(wfh) self.new.workflow_history = wfh # INICIO Customização self.new.reindexObject() # FIM Customização setattr(BaseCMFMigrator, 'migrate_workflow', migrate_workflow) logger.info('Patched migrate_workflow to help in events migration')
def ordernacao_pastas(portal_setup): """ Ajusta a ordenacao das pastas da raiz do portal setando ordenação padrão Plone. Similar ao ordenacao_pastas feito no upgradeStep 5000, só que ao invés de ordenar pastas pontuais ele é executado em todas as pastas. """ plone_view = portal_setup.restrictedTraverse("@@plone_portal_state") site = plone_view.portal() for pasta_id in site.objectIds(): pasta = site[pasta_id] # Se não for diretório e já estiver com a ordenação default, não faça # nada. if not IFolder.providedBy(pasta) or isinstance(pasta.getOrdering(), DefaultOrdering): continue # Define ordenacao padrao pasta.setOrdering() ordering = pasta.getOrdering() # A ordenacao dos itens na pasta e mantida em uma # Annotation. Aqui vamos repopula-la com os dados # corretos real = [o for o in pasta.objectIds(ordered=False)] stored = [o for o in pasta.objectIds(ordered=True)] for o in stored: ordering.notifyRemoved(o) for o in real: ordering.notifyAdded(o) logger.info("Pasta %s atualizada", pasta.Title())
def install_dropdownmenu(setup_tool): """Install webcouturier.dropdownmenu.""" addon = 'webcouturier.dropdownmenu' qi = api.portal.get_tool('portal_quickinstaller') if not qi.isProductInstalled(addon): qi.installProduct(addon) logger.info(addon + ' was installed')
def corrige_conteudo_collectivecover(portal_setup): """ Verifica se o campo css_class não é uma string válida, e substitui por uma string vazia. """ # Initial content was not indexed correctly, reindex all covers _reindex_covers() logger.info("All covers were reindexed.") # Make sure collective.cover is upgraded before continuing upgrade_profile(portal_setup, "collective.cover:default") logger.info("CSS classes will be fixed from Cover layouts.") # Fix registry layouts registry = getUtility(IRegistry) settings = registry.forInterface(ICoverSettings) fixed_layouts = {} for name, layout in settings.layouts.iteritems(): fixed_layouts[name] = _corrige_conteudo_collectivecover(None, layout) settings.layouts = fixed_layouts logger.info("Registry layouts were updated.") # Fix cover layouts covers = portal_setup.portal_catalog(object_provides=ICover.__identifier__) logger.info("Layout of {0} objects will be updated".format(len(covers))) for cover in covers: obj = cover.getObject() obj.cover_layout = _corrige_conteudo_collectivecover(obj, obj.cover_layout) logger.info('"{0}" was updated'.format(obj.absolute_url_path())) # Necessário caso os upgradeSteps não sejam executados na ordem correta. # Ver https://github.com/plonegovbr/brasil.gov.portal/issues/289 # Esse método está presente no collective.cover a partir da versão 1.0a11, # e essa versão é pinada no IDG 1.1.3, momento em que esse upgradeStep foi # gerado. simplify_layout(api.portal.get())
def atualiza_produtos_terceiros(portal_setup): """ Atualiza os profiles de produtos de terceiros.""" profiles = [ "brasil.gov.agenda:default", "brasil.gov.barra:default", "brasil.gov.portlets:default", "brasil.gov.tiles:default", "brasil.gov.vcge:default", "collective.cover:default", "collective.nitf:default", "collective.polls:default", "sc.embedder:default", "sc.social.like:default", ] # Somente executo o upgrade step do brasil.gov.agenda se o seu profile foi # instalado. Em versões antigas do brasil.gov.portal o brasil.gov.agenda # não era instalado. agenda_profile = "{0}:default".format(AGENDAPROJECTNAME) if portal_setup.getLastVersionForProfile(agenda_profile) == UNKNOWN: profiles.remove(agenda_profile) for profile_id in profiles: upgrade_profile(portal_setup, profile_id) logger.info("Produtos de terceiros foram atualizados")
def corrige_conteudo_collectivecover(portal_setup): """ Verifica se o campo css_class não é uma string válida, e substitui por uma string vazia. """ # Initial content was not indexed correctly, reindex all covers _reindex_covers() logger.info('All covers were reindexed.') # Make sure collective.cover is upgraded before continuing upgrade_profile(portal_setup, 'collective.cover:default') logger.info('CSS classes will be fixed from Cover layouts.') # Fix registry layouts registry = getUtility(IRegistry) settings = registry.forInterface(ICoverSettings) fixed_layouts = {} for name, layout in settings.layouts.iteritems(): fixed_layouts[name] = _corrige_conteudo_collectivecover(None, layout) settings.layouts = fixed_layouts logger.info('Registry layouts were updated.') # Fix cover layouts covers = portal_setup.portal_catalog(object_provides=ICover.__identifier__) logger.info('Layout of {0} objects will be updated'.format(len(covers))) for cover in covers: obj = cover.getObject() obj.cover_layout = _corrige_conteudo_collectivecover(obj, obj.cover_layout) logger.info('"{0}" was updated'.format(obj.absolute_url_path()))
def remove_styles(setup_tool): """Remove CSS from registered resources.""" css_tool = api.portal.get_tool('portal_css') for css in STYLES: css_tool.unregisterResource(id=css) assert css not in css_tool.getResourceIds() # nosec logger.info('Styles removed')
def install_keyword_manager(setup_tool): """Install Products.PloneKeywordManager.""" addon = 'PloneKeywordManager' qi = api.portal.get_tool('portal_quickinstaller') if not qi.isProductInstalled(addon): qi.installProduct(addon) logger.info(addon + ' was installed')
def atualiza_pacotes_instalados(context): """Exibe pacotes de dependencias""" logger.info(u'Rotina para exibir pacotes de dependências') qi = api.portal.get_tool('portal_quickinstaller') for p in SHOW_DEPS: _instala_pacote(qi, p) logger.info(u'Exibe pacote {0}'.format(p))
def link(): def getRemoteUrl(self): return self.remoteUrl setattr(Link, 'getRemoteUrl', getRemoteUrl) logger.info('Patched Link content type')
def atualiza_pacotes_instalados(context): """Exibe pacotes de dependencias""" logger.info(u'Rotina para exibir pacotes de dependências') qi = api.portal.get_tool('portal_quickinstaller') for p in SHOW_DEPS: _instala_pacote(qi, p) logger.info(u'Exibe pacote {0}'.format(p))
def search_for_embedder(setup_tool): """Remove sc.embedder from types_not_searched.""" settings = api.portal.get_tool('portal_properties').site_properties if 'sc.embedder' in settings.types_not_searched: types_not_searched = list(settings.types_not_searched) types_not_searched.remove('sc.embedder') settings.types_not_searched = tuple(types_not_searched) logger.info('Search for sc.embedder objects is enabled')
def update_galeria_image_sizes(setup_tool): """Update galeria de fotos image sizes.""" settings = api.portal.get_tool('portal_properties').imaging_properties allowed_sizes = set(settings.allowed_sizes) allowed_sizes -= frozenset([ u'galeria_de_foto_thumb 87:49', u'galeria_de_foto_view 748:513']) allowed_sizes |= frozenset([u'galeria_de_foto_view 1150:650']) settings.allowed_sizes = tuple(allowed_sizes) logger.info('Galeria de fotos image sizes updated.')
def show_global_sections(setup_tool): """Show back global_sections viewlet.""" storage = queryUtility(IViewletSettingsStorage) manager = u'plone.portalheader' for skinname in storage._hidden: hidden = storage.getHidden(manager, skinname) hidden = (x for x in hidden if x != u'plone.global_sections') storage.setHidden(manager, skinname, hidden) logger.info('Global Sections Viewlet Showed')
def uninstall_doormat(setup_tool): """Uninstall Products.Doormat. The add-on removes itself all related content at uninstall so we don't need to do so here. """ addon = 'Doormat' qi = api.portal.get_tool('portal_quickinstaller') if qi.isProductInstalled(addon): qi.uninstallProducts([addon]) logger.info(addon + ' was uninstalled')
def remove_browserlayer(context): """ Remove as browserlayers OEmbedLayer e IPloneAppCollectionLayer caso elas ainda estejam registradas""" for Ilayer in registered_layers(): if Ilayer.getName() == 'OEmbedLayer': unregister_layer(name=u'collective.oembed') logger.info('Layer collective.oembed removida') elif Ilayer.getName() == 'IPloneAppCollectionLayer': unregister_layer(name=u'plone.app.collection') logger.info('Layer plone.app.collection removida')
def outputfilters(): def patched_call(self, data): """ Patch original __call__ """ data = data.replace('/>', ' />') return self.__orig_call__(data) setattr(base.ResolveUIDAndCaptionFilter, '__orig_call__', base.ResolveUIDAndCaptionFilter.__call__) setattr(base.ResolveUIDAndCaptionFilter, '__call__', patched_call) logger.info('Patched ResolveUIDAndCaptionFilter')
def instala_profile_agenda(portal_setup): """Instala o profile do brasil.gov.agenda se ele não estiver instalado. Em versões antigas do brasil.gov.portal o profile do brasil.gov.agenda não era instalado. Ver: https://github.com/plonegovbr/brasil.gov.portal/issues/154#issuecomment-78988918 """ agenda_profile = '{0}:default'.format(AGENDAPROJECTNAME) if portal_setup.getLastVersionForProfile(agenda_profile) == UNKNOWN: logger.info('Instalando profile do brasil.gov.agenda') profile = 'profile-{0}:default'.format(AGENDAPROJECTNAME) portal_setup.runAllImportStepsFromProfile(profile) logger.info('Profile do brasil.gov.agenda instalado')
def outputfilters(): def patched_call(self, data): """ Patch original __call__ """ data = data.replace('/>', ' />') return self.__orig_call__(data) setattr(base.ResolveUIDAndCaptionFilter, '__orig_call__', base.ResolveUIDAndCaptionFilter.__call__) setattr(base.ResolveUIDAndCaptionFilter, '__call__', patched_call) logger.info('Patched ResolveUIDAndCaptionFilter')
def remove_nitf_customizations(setup_tool): """Remove collective.nitf customizations.""" # remove customized view from types tool custom_view = 'nitf_custom_view' types_tool = api.portal.get_tool('portal_types') nitf = types_tool['collective.nitf.content'] if custom_view in nitf.view_methods: view_methods = list(nitf.view_methods) view_methods.remove(custom_view) nitf.view_methods = tuple(view_methods) nitf.default_view_fallback = True logger.info('collective.nitf types tool customizations removed') # set default view on objects using custom view # get_valid_objects asserts catalog objects are valid from collective.nitf.content import INITF from collective.nitf.upgrades.v2000 import get_valid_objects import transaction results = api.content.find(object_provides=INITF.__identifier__) logger.info('Found {0} news articles'.format(len(results))) for n, obj in enumerate(get_valid_objects(results), start=1): if obj.getLayout() != custom_view: continue obj.setLayout('view') if n % 1000 == 0: transaction.commit() logger.info('{0} items processed'.format(n)) transaction.commit() logger.info('Done')
def remove_portlet_assignments(obj): """Remove portlet assignments on object.""" from plone.portlets.interfaces import ILocalPortletAssignable from plone.portlets.interfaces import IPortletAssignmentMapping from plone.portlets.interfaces import IPortletManager from zope.component import getMultiAdapter from zope.component import getUtility if not ILocalPortletAssignable.providedBy(obj): return for name in ('plone.leftcolumn', 'plone.rightcolumn'): manager = getUtility(IPortletManager, name=name) mapping = getMultiAdapter((obj, manager), IPortletAssignmentMapping) for i in mapping.keys(): logger.info('Portlet "{0}" removed'.format(i)) del mapping[i]
def uninstall_widgets(setup_tool): """Uninstall collective.z3cform.widgets.""" from collective.z3cform.widgets.interfaces import ILayer from plone.browserlayer import utils addon = 'collective.z3cform.widgets' qi = api.portal.get_tool('portal_quickinstaller') if qi.isProductInstalled(addon): with api.env.adopt_roles(['Manager']): qi.uninstallProducts([addon]) logger.info(addon + ' was uninstalled') # product must not be installable assert not qi.isProductInstallable(addon) if ILayer in utils.registered_layers(): utils.unregister_layer(name=addon) logger.info(addon + ' browser layer was removed')
def get_valid_objects(**kw): """Generate a list of objects associated with valid brains.""" catalog = api.portal.get_tool('portal_catalog') results = catalog(**kw) logger.info('Found {0} objects in the catalog'.format(len(results))) for b in results: try: obj = b.getObject() except (AttributeError, KeyError): obj = None if obj is None: # warn on broken entries in the catalog msg = 'Invalid object reference in the catalog: {0}' logger.warn(msg.format(b.getPath())) continue yield obj
def upgrade_profile(setup, profile_id): """Runs all non-installed upgrades for a profile.""" step = None # get non-installed upgrades for upgrades in setup.listUpgrades(profile_id): for upgrade in upgrades: if upgrade['done']: continue step = upgrade['step'] step.doStep(setup) logger.info('Ran upgrade step %s for profile %s' % ( step.title, profile_id, )) if step and step.dest is not None and step.checker is None: setup.setLastVersionForProfile(profile_id, step.dest)
def upgrade_profile(setup, profile_id): """Runs all non-installed upgrades for a profile.""" step = None # get non-installed upgrades for upgrades in setup.listUpgrades(profile_id): for upgrade in upgrades: if upgrade['done']: continue step = upgrade['step'] step.doStep(setup) logger.info('Ran upgrade step %s for profile %s' % ( step.title, profile_id )) if step and step.dest is not None and step.checker is None: setup.setLastVersionForProfile(profile_id, step.dest)
def atualiza_estilos_cover(portal_setup): """Atualiza estilos da configuração do collective.cover caso os mesmos tenham sido perdidos. Ver: https://github.com/collective/collective.cover/issues/465 """ record = '{0}.styles'.format(ICoverSettings.__identifier__) old_styles = api.portal.get_registry_record(record) new_styles = set([ 'Amarelo|amarelo', 'Azul Claro - borda|azul-claro-borda', 'Azul Claro Saude|azul-claro', 'Azul Escuro Turismo|azul-escuro', 'Azul Governo|azul', 'Azul Petroleo Defesa Seguranca|azul-petroleo', 'Azul Piscina|azul-piscina', 'Azul Turquesa - borda|azul-turquesa-borda', 'Azul Turquesa|azul-turquesa', 'Bege - borda|bege-borda', 'Bege|bege', 'Dourado Cultura|dourado', 'Fio separador|fio-separador', 'Laranja - borda|laranja-borda', 'Laranja Cidadania Justica|laranja', 'Link Externo|link-externo', 'Lista Horizontal|lista-horizontal', 'Lista Vertical|lista-vertical', 'Marrom Claro Economia Emprego|marrom-claro', 'Marrom Infraestrutura|marrom', 'Padrao|padrao', 'Roxo - borda|roxo-borda', 'Roxo Ciencia Tecnologia|roxo', 'Verde Claro Meio Ambiente|verde-claro', 'Verde Escuro Educacao|verde-escuro', 'Verde Esporte|verde', ]) union_styles = sorted(old_styles.union(new_styles)) api.portal.set_registry_record(record, set(union_styles)) logger.info('Estilos do cover atualizados')
def atualiza_secoes(context): """Remove referencias a secao General. Alteramos para Noticias""" ct = api.portal.get_tool('portal_catalog') resultados = ct.searchResults( section='General', portal_type='collective.nitf.content' ) logger.info(u'{0} conteúdos na seção General'.format(len(resultados))) for item in resultados: # Alteramos para Noticias o = item.getObject() o.section = u'Notícias' o.reindexObject(idxs=['section']) logger.info('Conteudos atualizados') available_sections = list(api.portal.get_registry_record( 'collective.nitf.controlpanel.INITFSettings.available_sections' )) if 'General' in available_sections: available_sections.remove('General') logger.info('Remove secao General') if u'Notícias' not in available_sections: available_sections.append(u'Notícias') logger.info('Adiciona secao Noticias') # Adiciona a secao Noticias api.portal.set_registry_record( 'collective.nitf.controlpanel.INITFSettings.available_sections', set(available_sections) ) default_section = api.portal.get_registry_record( 'collective.nitf.controlpanel.INITFSettings.default_section' ) if default_section == 'General': api.portal.set_registry_record( 'collective.nitf.controlpanel.INITFSettings.default_section', u'Notícias' ) logger.info('Define Noticias como secao padrao')
def ordernacao_pastas(context): """ Ajusta a ordenacao das pastas assuntos, imagens e sobre """ plone_view = context.restrictedTraverse('@@plone_portal_state') site = plone_view.portal() pastas = ['assuntos', 'imagens', 'sobre'] for pasta_id in pastas: if pasta_id not in site.objectIds(): continue pasta = site[pasta_id] # Define ordenacao padrao pasta.setOrdering() ordering = pasta.getOrdering() # A ordenacao dos itens na pasta e mantida em uma # Annotation. Aqui vamos repopula-la com os dados # corretos real = [o for o in pasta.objectIds(ordered=False)] stored = [o for o in pasta.objectIds(ordered=True)] for o in stored: ordering.notifyRemoved(o) for o in real: ordering.notifyAdded(o) logger.info('Pasta %s atualizada' % pasta.Title())
def attendees_e_timezone(): """ attendees ========= Da forma como o método migrate_schema_fields está implementado https://github.com/plone/plone.app.contenttypes/blob/1.1.1/plone/app/contenttypes/migration/dxmigration.py#L63 Quando atualizamos o plone.app.contenttypes para 1.1.1 e rodamos os upgradeSteps, dá erro em objetos de eventos que não possuem o atributo "attendees" (https://github.com/plonegovbr/brasil.gov.portal/blob/master/src/brasil/gov/portal/profiles/initcontent/dados/portal/eventos/evento-1/data.json) adicionados automaticamente pelo brasil.gov.portal: plone.app.contenttypes-1.1.1-py2.7.egg/plone/app/contenttypes/migration/dxmigration.py", line 74, in migrate_schema_fields self.new.attendees = tuple(self.old.attendees.splitlines()) AttributeError: 'NoneType' object has no attribute 'splitlines' Apesar de ter sido sugerido fazer um upgradeStep aqui em brasil.gov.portal para setar uma tupla vazia (https://github.com/plonegovbr/brasil.gov.portal/issues/240#issuecomment-305652387) isso não funciona pois dá o mesmo erro: plone.app.contenttypes-1.1.1-py2.7.egg/plone/app/contenttypes/migration/dxmigration.py", line 74, in migrate_schema_fields self.new.attendees = tuple(self.old.attendees.splitlines()) AttributeError: 'tuple' object has no attribute 'splitlines' Esse erro também ocorre se, numa versão plone.app.contenttypes 1.0 você adicionar um evento mas não colocar nenhuma informação em attendees. Sobra assim a opção do patch logo abaixo. FIXME: Se esse erro for corrigido upstream (ver https://github.com/plone/plone.app.contenttypes/issues/414) e a versão de plone.app.contenttypes for corrigida no release, esse patch pode ser removido. Lembrar de alterar no setup.py colocando a versão correspondente do plone.app.contenttypes que contenha essa correção. timezone ======== Sem esse patch, após rodar os upgradeSteps de plone.app.contenttypes, ao tentar acessar a visão de um item do tipo evento, temos o erro: Module zope.traversing.adapters, line 136, in traversePathElement - __traceback_info__: (None, 'isoformat') Module zope.traversing.adapters, line 50, in traverse - __traceback_info__: (None, 'isoformat', ()) LocationError: getField - Expression: "data/start/isoformat" - Filename: ... nt-1.1.5-py2.7.egg/plone/app/event/browser/event_view.pt - Location: (line 19: col 60) - Source: ... "dtstart" tal:content="data/start/isoformat">end</li> ^^^^^^^^^^^^^^^^^^^^ Isso ocorre porque o método migrate_schema_fields chega a definir um timezone mas não atribui ele a self.new.timezone, fazendo uma migração incompleta. Ao adicionarmos self.new.timezone = timezone no método o erro pára de ocorrer. FIXME: Se esse erro for corrigido upstream (ver https://github.com/plone/plone.app.contenttypes/issues/424) e a versão de plone.app.contenttypes for corrigida no release, esse patch pode ser removido. Lembrar de alterar no setup.py colocando a versão correspondente do plone.app.contenttypes que contenha essa correção. """ def migrate_schema_fields(self): timezone = str(self.old.start_date.tzinfo) \ if self.old.start_date.tzinfo \ else default_timezone(fallback='UTC') # Customização timezone inicia aqui self.new.timezone = timezone # Customização timezone finaliza aqui self.new.start = datetime_fixer(self.old.start_date, timezone) self.new.end = datetime_fixer(self.old.end_date, timezone) if hasattr(self.old, 'location'): self.new.location = self.old.location if hasattr(self.old, 'attendees'): # Customização attendess inicia aqui # self.new.attendees = tuple(self.old.attendees.splitlines()) if self.old.attendees: self.new.attendees = tuple(self.old.attendees.splitlines()) else: self.new.attendees = tuple() # Customização attendess finalizada if hasattr(self.old, 'event_url'): self.new.event_url = self.old.event_url if hasattr(self.old, 'contact_name'): self.new.contact_name = self.old.contact_name if hasattr(self.old, 'contact_email'): self.new.contact_email = self.old.contact_email if hasattr(self.old, 'contact_phone'): self.new.contact_phone = self.old.contact_phone if hasattr(self.old, 'text'): # Copy the entire richtext object, not just it's representation self.new.text = self.old.text setattr(DXOldEventMigrator, 'migrate_schema_fields', migrate_schema_fields) logger.info('Patched migrate_schema_fields to help in attendees migration')
def apply_profile(portal_setup): """Atualiza profile para versao 10700.""" profile = "profile-brasil.gov.portal.upgrades.v10700:default" loadMigrationProfile(portal_setup, profile) logger.info("Atualizado para versao 10700")
def apply_profile(context): """Atualiza perfil para versao 10300""" profile = 'profile-brasil.gov.portal.upgrades.v10300:default' loadMigrationProfile(context, profile) logger.info('Atualizado para versao 10300')