def test_addOrUpdateSeveralIndexes(self): """ It is possible to pass several new indexes to addOrUpdateIndexes, in this case, only new indexes are added and updated. """ # for now reversedUID index does not exist... self.assertTrue('reversedUID' not in self.catalog.indexes()) # and add an existing index UID self.assertTrue(self.catalog.Indexes['UID'].getTagName() == 'UUIDIndex') # add a document prior to adding the index priorDocument = api.content.create(type='Document', id='prior-document', container=self.portal) addOrUpdateIndexes( self.portal, # use an ordered dict so UID, an existing index, is after the new one OrderedDict([ ('reversedUID', ('FieldIndex', {})), ('UID', ('UUIDIndex', {}))]) ) self.assertTrue('reversedUID' in self.portal.portal_catalog.indexes()) # moreover existing objects were updated brains = self.catalog(reversedUID=priorDocument.UID()[::-1]) self.assertTrue(len(brains) == 1) self.assertTrue(brains[0].getObject().UID() == priorDocument.UID())
def postInstall(context): """Called at the end of the setup process. """ if isNotImioZamqpPmProfile(context): return site = context.getSite() addOrUpdateIndexes(site, indexInfos) addOrUpdateColumns(site, columnInfos)
def run(self): logger.info('Migrating to collective.task 2.2') self.cleanRegistries() addOrUpdateIndexes(self.portal, indexInfos={'assigned_group': ('FieldIndex', {}), 'due_date': ('DateIndex', {})}) addOrUpdateColumns(self.portal, columns=('assigned_group', 'due_date')) self.runProfileSteps('collective.task', steps=['typeinfo', 'workflow', 'cssregistry']) self.finish()
def test_updateIndexType(self): """ If an index already exists with a given type, it can be updated to another given type. Add an index of type 'FieldIndex' then turn it into a 'KeywordIndex'. """ addOrUpdateIndexes(self.portal, {'reversedUID': ('FieldIndex', {})}) # the added index type is 'FieldIndex' self.assertTrue(self.catalog._catalog.indexes['reversedUID'].meta_type == 'FieldIndex') # now add it as a KeyWordIndex addOrUpdateIndexes(self.portal, {'reversedUID': ('KeywordIndex', {})}) self.assertTrue(self.catalog._catalog.indexes['reversedUID'].meta_type == 'KeywordIndex')
def postInstall(context): """Called as at the end of the setup process. """ # the right place for your custom code if isNotMeetingMonsProfile(context): return logStep("postInstall", context) site = context.getSite() # need to reinstall PloneMeeting after reinstalling MC workflows to re-apply wfAdaptations reinstallPloneMeeting(context, site) showHomeTab(context, site) reorderSkinsLayers(context, site) addOrUpdateIndexes(site, {'toCorrect': ('BooleanIndex', {})}) addOrUpdateIndexes(site, {'corrected': ('BooleanIndex', {})})
def postInstall(context): """Called as at the end of the setup process. """ # the right place for your custom code if isNotMeetingCharleroiProfile(context): return logStep("postInstall", context) site = context.getSite() # need to reinstall PloneMeeting after reinstalling MC workflows to re-apply wfAdaptations reinstallPloneMeeting(context, site) showHomeTab(context, site) reorderSkinsLayers(context, site) # add the groupsOfMatter index addOrUpdateIndexes(site, {'financesAdviceCategory': ('FieldIndex', {})})
def run(self): logger.info('Migrating to collective.task 2.2') self.cleanRegistries() addOrUpdateIndexes(self.portal, indexInfos={ 'assigned_group': ('FieldIndex', {}), 'due_date': ('DateIndex', {}) }) addOrUpdateColumns(self.portal, columns=('assigned_group', 'due_date')) self.runProfileSteps('collective.task', steps=['typeinfo', 'workflow', 'cssregistry']) self.finish()
def test_addOrUpdateZCTextIndex(self): """ While adding a ZCTextIndex, optional 'extra' record can be passed. If nothing available, default values are used. """ addOrUpdateIndexes(self.portal, {'sample_zctextindex': ('ZCTextIndex', {})}) index = self.catalog._catalog.indexes['sample_zctextindex'] # if no 'extra' record given, default values are used self.assertTrue(index.lexicon_id == ZCTextIndexInfo.lexicon_id) self.assertTrue(index._index_type == ZCTextIndexInfo.index_type) # we can also update an existing ZCTextIndex index indexInfos = ZCTextIndexInfo() indexInfos.lexicon_id = 'plaintext_lexicon' indexInfos.index_type = 'Cosine Measure' addOrUpdateIndexes(self.portal, {'sample_zctextindex': ('ZCTextIndex', indexInfos)}) index = self.catalog._catalog.indexes['sample_zctextindex'] self.assertTrue(index.lexicon_id == indexInfos.lexicon_id) self.assertTrue(index._index_type == indexInfos.index_type) # we can change the indexType addOrUpdateIndexes(self.portal, {'sample_zctextindex': ('FieldIndex', {})}) self.assertTrue(self.catalog._catalog.indexes['sample_zctextindex']. meta_type == 'FieldIndex') # and back to a ZCTextIndex addOrUpdateIndexes(self.portal, {'sample_zctextindex': ('ZCTextIndex', {})}) self.assertTrue(self.catalog._catalog.indexes['sample_zctextindex']. meta_type == 'ZCTextIndex')
def test_addOrUpdateIndexes(self): """ Normal usecase of addOrUpdateIndexes, this will add a new index of required type. Moreover existing objects will be updated. """ # for now reversedUID index does not exist... self.assertTrue(not 'reversedUID' in self.catalog.indexes()) # add a document prior to adding the index priorDocument = api.content.create(type='Document', id='prior-document', container=self.portal) addOrUpdateIndexes(self.portal, {'reversedUID': ('FieldIndex', {})}) self.assertTrue('reversedUID' in self.portal.portal_catalog.indexes()) # moreover existing objects were updated brains = self.catalog(reversedUID=priorDocument.UID()[::-1]) self.assertTrue(len(brains) == 1) self.assertTrue(brains[0].getObject().UID() == priorDocument.UID())
def test_addOrUpdateIndexes(self): """ Normal usecase of addOrUpdateIndexes, this will add a new index of required type. Moreover existing objects will be updated. """ # for now reversedUID index does not exist... self.assertTrue('reversedUID' not in self.catalog.indexes()) # add a document prior to adding the index priorDocument = api.content.create(type='Document', id='prior-document', container=self.portal) addOrUpdateIndexes(self.portal, {'reversedUID': ('FieldIndex', {})}) self.assertTrue('reversedUID' in self.portal.portal_catalog.indexes()) # moreover existing objects were updated brains = self.catalog(reversedUID=priorDocument.UID()[::-1]) self.assertTrue(len(brains) == 1) self.assertTrue(brains[0].getObject().UID() == priorDocument.UID())
def test_addOrUpdateColumnsWithExistingIndex(self): """ Normal usecase of addOrUpdateColumns, this will add a new column (metadata). Test here when a corresponding index exists. Moreover existing objects will be updated. """ # for now reversedUID metadata does not exist... self.assertTrue('reversedUID' not in self.catalog.schema()) # add a document prior to adding the index api.content.create(type='Document', id='prior-document', container=self.portal) addOrUpdateIndexes(self.portal, {'reversedUID': ('FieldIndex', {})}) addOrUpdateColumns(self.portal, ('reversedUID', )) # the metadata was actually added self.assertTrue('reversedUID' in self.catalog.schema()) # and existing objects were updated brains = self.catalog() for brain in brains: obj = brain.getObject() self.assertTrue(obj.UID()[::-1] == brain.reversedUID)
def test_addOrUpdateColumnsWithExistingIndex(self): """ Normal usecase of addOrUpdateColumns, this will add a new column (metadata). Test here when a corresponding index exists. Moreover existing objects will be updated. """ # for now reversedUID metadata does not exist... self.assertTrue(not 'reversedUID' in self.catalog.schema()) # add a document prior to adding the index api.content.create(type='Document', id='prior-document', container=self.portal) addOrUpdateIndexes(self.portal, {'reversedUID': ('FieldIndex', {})}) addOrUpdateColumns(self.portal, ('reversedUID', )) # the metadata was actually added self.assertTrue('reversedUID' in self.catalog.schema()) # and existing objects were updated brains = self.catalog() for brain in brains: obj = brain.getObject() self.assertTrue(obj.UID()[::-1] == brain.reversedUID)
def perform_reference_number(self): """ Add or update the reference_number index compute the reference_number per projectspace store the last_reference_number in projectspace update catalog """ logger.info('Perform reference number ...') addOrUpdateIndexes(self.context, {'reference_number': ('FieldIndex', {})}) catalog = api.portal.get_tool('portal_catalog') projectspaces = catalog(object_provides=IProjectSpace.__identifier__) for projectspace in projectspaces: path = '/'.join(self.portal.getPhysicalPath()) + '/' + projectspace.id brains = catalog(object_provides=IProject.__identifier__, path={'query': path, 'depth': 3}, sort_on='created') for num, brain in enumerate(brains): obj = brain.getObject() if obj.reference_number == 0: obj.reference_number = num + 1 obj.reindexObject() projectspace = getProjectSpace(obj) projectspace.last_reference_number = num + 1 logger.info('Done.')
def test_addOrUpdateSeveralIndexes(self): """ It is possible to pass several new indexes to addOrUpdateIndexes, in this case, only new indexes are added and updated. """ # for now reversedUID index does not exist... self.assertTrue('reversedUID' not in self.catalog.indexes()) # and add an existing index UID self.assertTrue( self.catalog.Indexes['UID'].getTagName() == 'UUIDIndex') # add a document prior to adding the index priorDocument = api.content.create(type='Document', id='prior-document', container=self.portal) addOrUpdateIndexes( self.portal, # use an ordered dict so UID, an existing index, is after the new one OrderedDict([('reversedUID', ('FieldIndex', {})), ('UID', ('UUIDIndex', {}))])) self.assertTrue('reversedUID' in self.portal.portal_catalog.indexes()) # moreover existing objects were updated brains = self.catalog(reversedUID=priorDocument.UID()[::-1]) self.assertTrue(len(brains) == 1) self.assertTrue(brains[0].getObject().UID() == priorDocument.UID())
def test_addOrUpdateZCTextIndex(self): """ While adding a ZCTextIndex, optional 'extra' record can be passed. If nothing available, default values are used. """ addOrUpdateIndexes(self.portal, {'sample_zctextindex': ('ZCTextIndex', {})}) index = self.catalog._catalog.indexes['sample_zctextindex'] # if no 'extra' record given, default values are used self.assertTrue(index.lexicon_id == ZCTextIndexInfo.lexicon_id) self.assertTrue(index._index_type == ZCTextIndexInfo.index_type) # we can also update an existing ZCTextIndex index indexInfos = ZCTextIndexInfo() indexInfos.lexicon_id = 'plaintext_lexicon' indexInfos.index_type = 'Cosine Measure' addOrUpdateIndexes(self.portal, {'sample_zctextindex': ('ZCTextIndex', indexInfos)}) index = self.catalog._catalog.indexes['sample_zctextindex'] self.assertTrue(index.lexicon_id == indexInfos.lexicon_id) self.assertTrue(index._index_type == indexInfos.index_type) # we can change the indexType addOrUpdateIndexes(self.portal, {'sample_zctextindex': ('FieldIndex', {})}) self.assertTrue(self.catalog._catalog.indexes['sample_zctextindex'].meta_type == 'FieldIndex') # and back to a ZCTextIndex addOrUpdateIndexes(self.portal, {'sample_zctextindex': ('ZCTextIndex', {})}) self.assertTrue(self.catalog._catalog.indexes['sample_zctextindex'].meta_type == 'ZCTextIndex')
def run(self): logger.info('Migrating to imio.dms.mail 1.0...') self.cleanRegistries() self.upgradeProfile('collective.dms.mailcontent:default') # We have to reapply type info before doing other subproducts migration self.runProfileSteps('imio.dms.mail', steps=['typeinfo']) # We have to update type schema because plone.dexterity doesn't detect schema_policy modification. BUG #44 for portal_type in ['dmsincomingmail', 'dmsoutgoingmail']: # i_e ok schemaName = dxutils.portalTypeToSchemaName(portal_type) schema = getattr(plone.dexterity.schema.generated, schemaName) fti = getUtility(IDexterityFTI, name=portal_type) model = fti.lookupModel() syncSchema(model.schema, schema, overwrite=True, sync_bases=True) notify(plone.dexterity.schema.SchemaInvalidatedEvent(portal_type)) self.upgradeProfile('collective.task:default') self.upgradeProfile('dexterity.localroles:default') self.upgradeProfile('dexterity.localrolesfield:default') self.upgradeProfile('collective.contact.plonegroup:default') self.runProfileSteps('imio.dms.mail', steps=[ 'actions', 'componentregistry', 'controlpanel', 'plone.app.registry', 'portlets', 'repositorytool', 'rolemap', 'sharing', 'workflow' ]) self.portal.portal_workflow.updateRoleMappings() self.runProfileSteps('collective.dms.mailcontent', steps=['controlpanel']) self.runProfileSteps('collective.contact.plonegroup', steps=['controlpanel']) self.reinstall([ 'collective.messagesviewlet:messages', 'collective.querynextprev:default', 'imio.dashboard:default', ]) # set jqueryui autocomplete to False. If not, contact autocomplete doesn't work self.registry[ 'collective.js.jqueryui.controlpanel.IJQueryUIPlugins.ui_autocomplete'] = False # delete old dmsmail portlet self.delete_portlet(self.portal, 'portlet_maindmsmail') # remove deprecated interfaces self.remove_contact_interfaces() # moved notes content to task_description catalog = api.portal.get_tool('portal_catalog') brains = catalog.searchResults(portal_type='dmsincomingmail') # i_e ok for brain in brains: obj = brain.getObject() if not base_hasattr(obj, 'notes') or not obj.notes: continue text = u'<p>%s</p>\r\n' % obj.notes.replace('\r\n', '<br />\r\n') obj.task_description = richtextval(text) delattr(obj, 'notes') # obj.reindexObject() # replace collections by Dashboard collections im_folder = self.portal['incoming-mail'] alsoProvides(im_folder, INextPrevNotNavigable) alsoProvides(im_folder, IIMDashboard) self.replaceCollections(im_folder) # apply contact faceted config reimport_faceted_config(self.portal['contacts'], 'contacts-faceted.xml') # add new indexes for dashboard addOrUpdateIndexes(self.portal, indexInfos={ 'mail_type': ('FieldIndex', {}), 'mail_date': ('DateIndex', {}), 'in_out_date': ('DateIndex', {}), }) # set dashboard on incoming mail configure_faceted_folder( im_folder, xml='default_dashboard_widgets.xml', default_UID=im_folder['mail-searches']['all_mails'].UID()) # set task local roles configuration configure_task_rolefields(self.portal) # update dexterity local roles configuration self.update_local_roles() # add task actionspanel config if not self.registry[ 'imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions']: self.registry['imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'] = [] self.registry['imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'] += \ ['task.back_in_created|', 'task.back_in_to_assign|', 'task.back_in_to_do|', 'task.back_in_progress|', 'task.back_in_realized|'] # activate ckeditor configure_ckeditor(self.portal, custom='ged') # Set markup allowed types adapter = MarkupControlPanelAdapter(self.portal) adapter.set_allowed_types(['text/html']) # update searchabletext self.update_dmsmainfile() self.upgradeAll() for prod in [ 'plone.formwidget.autocomplete', 'collective.documentviewer', 'plone.formwidget.masterselect', 'collective.contact.core', 'collective.contact.duplicated', 'collective.dms.basecontent', 'collective.dms.scanbehavior', 'collective.externaleditor', 'plone.app.collection', 'plone.app.intid', 'collective.contact.facetednav', 'plonetheme.imioapps', 'PasswordStrength', 'imio.dms.mail' ]: mark_last_version(self.portal, product=prod) self.portal.manage_permission( 'CMFEditions: Revert to previous versions', ('Manager', 'Site Administrator'), acquire=0) #self.refreshDatabase() self.finish()
def run(self): logger.info('Migrating to imio.dms.mail 1.1...') self.cleanRegistries() self.runProfileSteps('imio.dms.mail', steps=['actions', 'cssregistry', 'jsregistry', 'workflow']) self.runProfileSteps('collective.messagesviewlet', steps=['collective-messagesviewlet-messages'], profile='messages') self.upgradeProfile('collective.dms.mailcontent:default') self.upgradeProfile('collective.task:default') self.upgradeProfile('eea.facetednavigation:default') self.upgradeProfile('collective.querynextprev:default') im_folder = self.portal['incoming-mail'] # set mail-searches folder as not next/prev navigable if not INextPrevNotNavigable.providedBy(im_folder['task-searches']): alsoProvides(im_folder['task-searches'], INextPrevNotNavigable) # activate field on DashboardCollection self.add_view_field('mail_type', im_folder['mail-searches'], before='CreationDate') self.add_view_field('sender', im_folder['mail-searches'], before='CreationDate') self.add_view_field('task_parent', im_folder['task-searches'], before='review_state') # set showNumberOfItems on some collections self.update_count(im_folder['mail-searches'], ids=['to_validate', 'to_treat', 'im_treating', 'created']) self.update_count(im_folder['task-searches'], ids=['to_validate', 'to_treat', 'im_treating']) # update criterion on validation collections self.update_validation_collections() # Activate browser message msg = self.portal['messages-config']['browser-warning'] api.content.transition(obj=msg, to_state='activated') # update searchabletext self.update_dmsmainfile() self.update_dmsincomingmail() # add new indexes addOrUpdateIndexes(self.portal, indexInfos={'state_group': ('FieldIndex', {})}) # add metadata in portal_catalog addOrUpdateColumns(self.portal, columns=('mail_type',)) # block parent portlets on contacts blacklistPortletCategory(self.portal, self.portal['contacts']) # add local roles self.portal['contacts'].manage_addLocalRoles('dir_general', ['Contributor', 'Editor', 'Reader']) # configure autocomplete widget self.configure_autocomplete_widget(im_folder['mail-searches']) # configure task batch actions alsoProvides(im_folder['task-searches'], IIMTaskDashboard) # reimport contact faceted config reimport_faceted_config(self.portal['contacts'], xml='contacts-faceted.xml') # remove tinymce resources configure_ckeditor(self.portal, default=0, allusers=0, forceTextPaste=0, scayt=0) self.upgradeAll() self.runProfileSteps('imio.dms.mail', steps=['cssregistry', 'jsregistry']) # set jqueryui autocomplete to False. If not, contact autocomplete doesn't work self.registry['collective.js.jqueryui.controlpanel.IJQueryUIPlugins.ui_autocomplete'] = False for prod in ['plone.formwidget.autocomplete', 'collective.plonefinder', 'plone.formwidget.contenttree', 'plone.app.dexterity', 'plone.formwidget.masterselect', 'collective.behavior.talcondition', 'collective.contact.facetednav', 'collective.contact.plonegroup', 'collective.contact.widget', 'collective.dms.batchimport', 'collective.dms.scanbehavior', 'collective.documentgenerator', 'collective.eeafaceted.collectionwidget', 'collective.eeafaceted.z3ctable', 'collective.messagesviewlet', 'collective.querynextprev', 'dexterity.localroles', 'dexterity.localrolesfield', 'imio.actionspanel', 'imio.dashboard', 'imio.dms.mail', 'plone.formwidget.datetime', 'plonetheme.imioapps']: mark_last_version(self.portal, product=prod) #self.refreshDatabase() self.finish()
def setUp(self): """Custom shared utility setup for tests.""" super(TestCombinedIndex, self).setUp() # add the 'contained_types_and_states' to portal_catalog addOrUpdateIndexes(self.portal, {'contained_types_and_states': ('KeywordIndex', {})}) # make sure we have a default workflow self.portal.portal_workflow.setDefaultChain('simple_publication_workflow') self.dashboardcollection = api.content.create( id='dc1', type='DashboardCollection', title='Dashboard collection 1', container=self.portal, sort_on='', sort_reversed='' ) # this will by default query Folders self.dashboardcollection.query = [ {'i': 'portal_type', 'o': 'plone.app.querystring.operation.selection.is', 'v': ['Folder', ]}, ] # create 3 folders : # - first is empty; # - second contains one private Document and one published Document; # - third contains a private Folder. # folder1 self.folder1 = api.content.create( id='folder1', type='Folder', title='Folder 1', container=self.portal ) self.privatedoc = api.content.create( id='privatedoc', type='Document', title='Private document', container=self.portal.folder1 ) self.publicdoc = api.content.create( id='publicdoc', type='Document', title='Published document', container=self.portal.folder1 ) api.content.transition(self.publicdoc, 'publish') # folder2 self.folder2 = api.content.create( id='folder2', type='Folder', title='Folder 2', container=self.portal ) # folder3 self.folder3 = api.content.create( id='folder3', type='Folder', title='Folder 3', container=self.portal ) self.privatefolder = api.content.create( id='privatefolder', type='Folder', title='Private folder', container=self.portal.folder3 ) self.privatedoc2 = api.content.create( id='privatedoc2', type='Document', title='Private document 2', container=self.portal.folder3 ) # first check that contained_types_and_states index is correct self.folder1.reindexObject(idxs=['contained_types_and_states']) self.folder2.reindexObject(idxs=['contained_types_and_states']) self.folder3.reindexObject(idxs=['contained_types_and_states']) self.assertEquals(contained_types_and_states(self.folder1)(), ['Document', 'Document__private', 'Document__published', 'private', 'published']) self.assertEquals(contained_types_and_states(self.folder2)(), []) self.assertEquals(contained_types_and_states(self.folder3)(), ['Document', 'Document__private', 'Folder', 'Folder__private', 'private'])
def run(self): # Removed old import step setup = api.portal.get_tool('portal_setup') ir = setup.getImportStepRegistry() # /cputils_removeStep?step=imioprojectpst-adaptDefaultPortal if 'imioprojectpst-adaptDefaultPortal' in ir._registered: del ir._registered['imioprojectpst-adaptDefaultPortal'] self.upgradeProfile('collective.contact.core:default') self.upgradeProfile('collective.contact.plonegroup:default') self.upgradeProfile('plone.formwidget.masterselect:default') self.reinstall(['dexterity.localrolesfield:default']) self.runProfileSteps('imio.project.pst', steps=[ 'actions', 'catalog', 'componentregistry', 'jsregistry', 'portlets', 'propertiestool', 'plone.app.registry', 'typeinfo', 'workflow' ]) # update security settings self.portal.portal_workflow.updateRoleMappings() self.reinstall([ 'collective.documentgenerator:default', 'collective.externaleditor:default', 'collective.messagesviewlet:messages', 'collective.task:default', 'imio.dashboard:default', 'plonetheme.imioapps:pstskin', ]) self.various_update() indexes_to_add = { 'categories': ('KeywordIndex', {}), 'priority': ('FieldIndex', {}), 'representative_responsible': ('KeywordIndex', {}), 'administrative_responsible': ('KeywordIndex', {}), 'manager': ('KeywordIndex', {}), 'planned_begin_date': ('DateIndex', {}), 'planned_end_date': ('DateIndex', {}), 'effective_begin_date': ('DateIndex', {}), 'effective_end_date': ('DateIndex', {}), 'health_indicator': ('FieldIndex', {}), 'progress': ('FieldIndex', {}), 'extra_concerned_people': ('ZCTextIndex', {}), } addOrUpdateIndexes(self.context, indexes_to_add) # remove the old collections and configure the dashboard if 'collections' in self.portal.pst: api.content.delete(obj=self.portal.pst['collections']) for brain in self.pc(portal_type='Collection', path='/'.join(self.portal.pst.getPhysicalPath())): api.content.delete(obj=brain.getObject()) configureDashboard(self.portal.pst) self.portal.pst.setLayout('view') self.runProfileSteps('imio.project.pst', steps=['portlets'], profile='demo') # migrate oo fields brains = self.pc(portal_type="operationalobjective") for brain in brains: oo = brain.getObject() oo.administrative_responsible = [ r[:-13] for r in oo.administrative_responsible if r.endswith('_actioneditor') ] oo.manager = [ m[:-13] for m in oo.manager if m.endswith('_actioneditor') ] self.migrate_pst_action_fields() # update faceted navigation configs mapping = { 'strategicobjectives': 'strategicobjective', 'operationalobjectives': 'operationalobjective', 'pstactions': 'pstaction', } for col_folder_id, content_type in mapping.iteritems(): col_folder = self.portal.pst[col_folder_id] reimport_faceted_config(col_folder, xml='{}.xml'.format(content_type), default_UID=col_folder['all'].UID()) add_plonegroups_to_registry() configure_actions_panel(self.portal) configure_rolefields(self.portal) # migrate to documentgenerator self.migrate_templates() self.upgradeAll() # add documentation message add_message( 'doc1-0', 'Documentation 1.0', u'<p>Vous pouvez consulter la <a href="http://www.imio.be/support' '/documentation/manual/gestion-de-projet-1.0" target="_blank">documentation en ligne de la ' 'nouvelle version</a>.</p>', msg_type='significant', can_hide=True, req_roles=['Authenticated'], activate=True) # update portal_catalog self.refreshDatabase() for prod in [ 'collective.ckeditor', 'collective.contact.core', 'collective.contact.plonegroup', 'collective.plonefinder', 'collective.quickupload', 'collective.z3cform.datagridfield', 'imio.project.core', 'imio.project.pst', 'plonetheme.classic', 'plone.app.collection', 'plone.app.dexterity', 'plone.app.intid', 'plone.app.relationfield', 'plone.formwidget.masterselect', 'plone.formwidget.autocomplete', 'plone.formwidget.contenttree' ]: mark_last_version(self.portal, product=prod) # Reorder css and js self.runProfileSteps('imio.project.pst', steps=['cssregistry', 'jsregistry']) # Display duration self.finish()
def run(self): logger.info('Migrating to imio.dms.mail 0.3.1...') self.reinstall(['collective.task:uninstall_1.0']) self.cleanRegistries() self.reinstall([ 'imio.actionspanel:default', 'imio.history:default', 'collective.task:default', 'collective.compoundcriterion:default', 'collective.behavior.talcondition:default', 'collective.contact.facetednav:default', 'collective.contact.duplicated:default', 'plone.app.versioningbehavior:default', ]) self.runProfileSteps('imio.dms.mail', ['actions', 'catalog', 'componentregistry', 'jsregistry', 'plone.app.registry', 'rolemap', 'typeinfo', 'update-workflow-rolemap', 'viewlets', 'workflow']) self.runProfileSteps('collective.dms.basecontent', ['atcttool', 'catalog']) self.runProfileSteps('collective.dms.scanbehavior', ['catalog']) api.portal.get_tool('portal_diff').setDiffForPortalType( 'dmsincomingmail', {'any': "Compound Diff for Dexterity types"}) self.createNotEncodedPerson() self.changeTopicsFolder() self.replaceRoleByGroup() self.portal.portal_workflow.updateRoleMappings() catalog = api.portal.get_tool('portal_catalog') brains = catalog.searchResults(portal_type='dmsincomingmail') if brains: factory = getUtility(IVocabularyFactory, 'collective.dms.basecontent.treating_groups') voc = factory(brains[0].getObject()) good_values = voc.by_token for brain in brains: im = brain.getObject() new_incomingmail(im, None) if isinstance(im.treating_groups, list): if len(im.treating_groups) > 1: logger.error("More than one treating_groups %s for %s object" % (im.treating_groups, im)) keep = None for tg in im.treating_groups: if tg in good_values: keep = tg break logger.warn("Kept %s" % keep) im.treating_groups = keep elif not im.treating_groups: logger.warn("Replaced old value %s by first good value %s for %s object" % (im.treating_groups[0], good_values.keys()[0], im)) im.treating_groups = good_values.keys()[0] elif im.treating_groups[0] in good_values: #elif catalog(UID=im.treating_groups[0]): im.treating_groups = im.treating_groups[0] else: logger.warn("Replaced old value %s by first good value %s for %s object" % (im.treating_groups[0], good_values.keys()[0], im)) im.treating_groups = good_values.keys()[0] addOrUpdateIndexes(self.portal, indexInfos={'treating_groups': ('KeywordIndex', {}), 'recipient_groups': ('KeywordIndex', {}), 'organization_type': ('FieldIndex', {}), }) addOrUpdateColumns(self.portal, columns=('treating_groups', 'recipient_groups')) # a global recatalog is made after #brains = catalog.searchResults(portal_type='organization') #for brain in brains: # brain.getObject().reindexObject(idxs=['organization_type']) setupFacetedContacts(self.portal) changeSearchedTypes(self.portal) configure_actions_panel(self.portal) self.upgradeAll() self.refreshDatabase() self.finish()
def run(self): logger.info('Migrating to imio.dms.mail 1.1...') self.cleanRegistries() self.runProfileSteps( 'imio.dms.mail', steps=['actions', 'cssregistry', 'jsregistry', 'workflow']) self.runProfileSteps('collective.messagesviewlet', steps=['collective-messagesviewlet-messages'], profile='messages') self.upgradeProfile('collective.dms.mailcontent:default') self.upgradeProfile('collective.task:default') self.upgradeProfile('eea.facetednavigation:default') self.upgradeProfile('collective.querynextprev:default') im_folder = self.portal['incoming-mail'] # set mail-searches folder as not next/prev navigable if not INextPrevNotNavigable.providedBy(im_folder['task-searches']): alsoProvides(im_folder['task-searches'], INextPrevNotNavigable) # activate field on DashboardCollection self.add_view_field('mail_type', im_folder['mail-searches'], before='CreationDate') self.add_view_field('sender', im_folder['mail-searches'], before='CreationDate') self.add_view_field('task_parent', im_folder['task-searches'], before='review_state') # set showNumberOfItems on some collections self.update_count(im_folder['mail-searches'], ids=[ 'to_validate', 'to_treat', 'im_treating', 'searchfor_created' ]) self.update_count(im_folder['task-searches'], ids=['to_validate', 'to_treat', 'im_treating']) # update criterion on validation collections self.update_validation_collections() # Activate browser message msg = self.portal['messages-config']['browser-warning'] api.content.transition(obj=msg, to_state='activated') # update searchabletext self.update_dmsmainfile() self.update_dmsincomingmail() # add new indexes addOrUpdateIndexes(self.portal, indexInfos={'state_group': ('FieldIndex', {})}) # add metadata in portal_catalog addOrUpdateColumns(self.portal, columns=('mail_type', )) # block parent portlets on contacts blacklistPortletCategory(self.portal['contacts']) # add local roles self.portal['contacts'].manage_addLocalRoles( 'dir_general', ['Contributor', 'Editor', 'Reader']) # configure autocomplete widget self.configure_autocomplete_widget(im_folder['mail-searches']) # configure task batch actions alsoProvides(im_folder['task-searches'], ITaskDashboard) # reimport contact faceted config reimport_faceted_config(self.portal['contacts'], xml='contacts-faceted.xml') # remove tinymce resources configure_ckeditor(self.portal, default=0, allusers=0, forceTextPaste=0, scayt=0) self.upgradeAll() self.runProfileSteps('imio.dms.mail', steps=['cssregistry', 'jsregistry']) # set jqueryui autocomplete to False. If not, contact autocomplete doesn't work self.registry[ 'collective.js.jqueryui.controlpanel.IJQueryUIPlugins.ui_autocomplete'] = False for prod in [ 'plone.formwidget.autocomplete', 'collective.plonefinder', 'plone.formwidget.contenttree', 'plone.app.dexterity', 'plone.formwidget.masterselect', 'collective.behavior.talcondition', 'collective.contact.facetednav', 'collective.contact.plonegroup', 'collective.contact.widget', 'collective.dms.batchimport', 'collective.dms.scanbehavior', 'collective.documentgenerator', 'collective.eeafaceted.collectionwidget', 'collective.eeafaceted.z3ctable', 'collective.messagesviewlet', 'collective.querynextprev', 'dexterity.localroles', 'dexterity.localrolesfield', 'imio.actionspanel', 'imio.dashboard', 'imio.dms.mail', 'plone.formwidget.datetime', 'plonetheme.imioapps' ]: mark_last_version(self.portal, product=prod) #self.refreshDatabase() self.finish()
def setUp(self): """Custom shared utility setup for tests.""" super(TestCombinedIndex, self).setUp() # add the 'contained_types_and_states' to portal_catalog addOrUpdateIndexes( self.portal, {'contained_types_and_states': ('KeywordIndex', {})}) # make sure we have a default workflow self.portal.portal_workflow.setDefaultChain( 'simple_publication_workflow') self.dashboardcollection = api.content.create( id='dc1', type='DashboardCollection', title='Dashboard collection 1', container=self.portal, sort_on='', sort_reversed='') # this will by default query Folders self.dashboardcollection.query = [ { 'i': 'portal_type', 'o': 'plone.app.querystring.operation.selection.is', 'v': [ 'Folder', ] }, ] # create 3 folders : # - first is empty; # - second contains one private Document and one published Document; # - third contains a private Folder. # folder1 self.folder1 = api.content.create(id='folder1', type='Folder', title='Folder 1', container=self.portal) self.privatedoc = api.content.create(id='privatedoc', type='Document', title='Private document', container=self.portal.folder1) self.publicdoc = api.content.create(id='publicdoc', type='Document', title='Published document', container=self.portal.folder1) api.content.transition(self.publicdoc, 'publish') # folder2 self.folder2 = api.content.create(id='folder2', type='Folder', title='Folder 2', container=self.portal) # folder3 self.folder3 = api.content.create(id='folder3', type='Folder', title='Folder 3', container=self.portal) self.privatefolder = api.content.create(id='privatefolder', type='Folder', title='Private folder', container=self.portal.folder3) self.privatedoc2 = api.content.create(id='privatedoc2', type='Document', title='Private document 2', container=self.portal.folder3) # first check that contained_types_and_states index is correct self.folder1.reindexObject(idxs=['contained_types_and_states']) self.folder2.reindexObject(idxs=['contained_types_and_states']) self.folder3.reindexObject(idxs=['contained_types_and_states']) self.assertEquals( contained_types_and_states(self.folder1)(), [ 'Document', 'Document__private', 'Document__published', 'private', 'published' ]) self.assertEquals(contained_types_and_states(self.folder2)(), []) self.assertEquals( contained_types_and_states(self.folder3)(), [ 'Document', 'Document__private', 'Folder', 'Folder__private', 'private' ])
def run(self): logger.info('Migrating to imio.dms.mail 1.0...') self.cleanRegistries() self.upgradeProfile('collective.dms.mailcontent:default') # We have to reapply type info before doing other subproducts migration self.runProfileSteps('imio.dms.mail', steps=['typeinfo']) # We have to update type schema because plone.dexterity doesn't detect schema_policy modification. BUG #44 for portal_type in ['dmsincomingmail', 'dmsoutgoingmail']: schemaName = dxutils.portalTypeToSchemaName(portal_type) schema = getattr(plone.dexterity.schema.generated, schemaName) fti = getUtility(IDexterityFTI, name=portal_type) model = fti.lookupModel() syncSchema(model.schema, schema, overwrite=True, sync_bases=True) notify(plone.dexterity.schema.SchemaInvalidatedEvent(portal_type)) self.upgradeProfile('collective.task:default') self.upgradeProfile('dexterity.localroles:default') self.upgradeProfile('dexterity.localrolesfield:default') self.upgradeProfile('collective.contact.plonegroup:default') self.runProfileSteps('imio.dms.mail', steps=['actions', 'componentregistry', 'controlpanel', 'plone.app.registry', 'portlets', 'repositorytool', 'rolemap', 'sharing', 'workflow']) self.portal.portal_workflow.updateRoleMappings() self.runProfileSteps('collective.dms.mailcontent', steps=['controlpanel']) self.runProfileSteps('collective.contact.plonegroup', steps=['controlpanel']) self.reinstall([ 'collective.messagesviewlet:messages', 'collective.querynextprev:default', 'imio.dashboard:default', ]) # set jqueryui autocomplete to False. If not, contact autocomplete doesn't work self.registry['collective.js.jqueryui.controlpanel.IJQueryUIPlugins.ui_autocomplete'] = False # delete old dmsmail portlet self.delete_portlet(self.portal, 'portlet_maindmsmail') # remove deprecated interfaces self.remove_contact_interfaces() # moved notes content to task_description catalog = api.portal.get_tool('portal_catalog') brains = catalog.searchResults(portal_type='dmsincomingmail') for brain in brains: obj = brain.getObject() if not base_hasattr(obj, 'notes') or not obj.notes: continue text = u'<p>%s</p>\r\n' % obj.notes.replace('\r\n', '<br />\r\n') obj.task_description = create_richtextval(text) delattr(obj, 'notes') # obj.reindexObject() # replace collections by Dashboard collections im_folder = self.portal['incoming-mail'] alsoProvides(im_folder, INextPrevNotNavigable) alsoProvides(im_folder, IIMDashboard) self.replaceCollections(im_folder) # apply contact faceted config reimport_faceted_config(self.portal['contacts'], 'contacts-faceted.xml') # add new indexes for dashboard addOrUpdateIndexes(self.portal, indexInfos={'mail_type': ('FieldIndex', {}), 'mail_date': ('DateIndex', {}), 'in_out_date': ('DateIndex', {}), }) # set dashboard on incoming mail configure_faceted_folder(im_folder, xml='default_dashboard_widgets.xml', default_UID=im_folder['mail-searches']['all_mails'].UID()) # set task local roles configuration configure_task_rolefields(self.portal) # update dexterity local roles configuration self.update_local_roles() # add task actionspanel config if not self.registry['imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions']: self.registry['imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'] = [] self.registry['imio.actionspanel.browser.registry.IImioActionsPanelConfig.transitions'] += \ ['task.back_in_created|', 'task.back_in_to_assign|', 'task.back_in_to_do|', 'task.back_in_progress|', 'task.back_in_realized|'] # activate ckeditor configure_ckeditor(self.portal, custom='ged') # Set markup allowed types adapter = MarkupControlPanelAdapter(self.portal) adapter.set_allowed_types(['text/html']) # update searchabletext self.update_dmsmainfile() self.upgradeAll() for prod in ['plone.formwidget.autocomplete', 'collective.documentviewer', 'plone.formwidget.masterselect', 'collective.contact.core', 'collective.contact.duplicated', 'collective.dms.basecontent', 'collective.dms.scanbehavior', 'collective.externaleditor', 'plone.app.collection', 'plone.app.intid', 'collective.contact.facetednav', 'plonetheme.imioapps', 'PasswordStrength', 'imio.dms.mail']: mark_last_version(self.portal, product=prod) self.portal.manage_permission('CMFEditions: Revert to previous versions', ('Manager', 'Site Administrator'), acquire=0) #self.refreshDatabase() self.finish()
def run(self): logger.info('Migrating to imio.dms.mail 0.3.1...') self.reinstall(['collective.task:uninstall_1.0']) self.cleanRegistries() self.reinstall([ 'imio.actionspanel:default', 'imio.history:default', 'collective.task:default', 'collective.compoundcriterion:default', 'collective.behavior.talcondition:default', 'collective.contact.facetednav:default', 'collective.contact.duplicated:default', 'plone.app.versioningbehavior:default', ]) self.runProfileSteps('imio.dms.mail', [ 'actions', 'catalog', 'componentregistry', 'jsregistry', 'plone.app.registry', 'rolemap', 'typeinfo', 'update-workflow-rolemap', 'viewlets', 'workflow' ]) self.runProfileSteps('collective.dms.basecontent', ['atcttool', 'catalog']) self.runProfileSteps('collective.dms.scanbehavior', ['catalog']) api.portal.get_tool('portal_diff').setDiffForPortalType( 'dmsincomingmail', {'any': "Compound Diff for Dexterity types"}) # i_e ok self.createNotEncodedPerson() self.changeTopicsFolder() self.replaceRoleByGroup() self.portal.portal_workflow.updateRoleMappings() catalog = api.portal.get_tool('portal_catalog') brains = catalog.searchResults(portal_type='dmsincomingmail') # i_e ok if brains: factory = getUtility(IVocabularyFactory, 'collective.dms.basecontent.treating_groups') voc = factory(brains[0].getObject()) good_values = voc.by_token for brain in brains: im = brain.getObject() #new_incomingmail(im, None) if isinstance(im.treating_groups, list): if len(im.treating_groups) > 1: logger.error( "More than one treating_groups %s for %s object" % (im.treating_groups, im)) keep = None for tg in im.treating_groups: if tg in good_values: keep = tg break logger.warn("Kept %s" % keep) im.treating_groups = keep elif not im.treating_groups: logger.warn( "Replaced old value %s by first good value %s for %s object" % (im.treating_groups[0], good_values.keys()[0], im)) im.treating_groups = good_values.keys()[0] elif im.treating_groups[0] in good_values: #elif catalog(UID=im.treating_groups[0]): im.treating_groups = im.treating_groups[0] else: logger.warn( "Replaced old value %s by first good value %s for %s object" % (im.treating_groups[0], good_values.keys()[0], im)) im.treating_groups = good_values.keys()[0] addOrUpdateIndexes(self.portal, indexInfos={ 'treating_groups': ('KeywordIndex', {}), 'recipient_groups': ('KeywordIndex', {}), 'organization_type': ('FieldIndex', {}), }) addOrUpdateColumns(self.portal, columns=('treating_groups', 'recipient_groups')) # a global recatalog is made after #brains = catalog.searchResults(portal_type='organization') #for brain in brains: # brain.getObject().reindexObject(idxs=['organization_type']) setupFacetedContacts(self.portal) changeSearchedTypes(self.portal) configure_actions_panel(self.portal) self.upgradeAll() self.refreshDatabase() self.finish()
def postInstall(context): """Called as at the end of the setup process. """ # the right place for your custom code if isNotMeetingAndenneProfile(context): return logStep("postInstall", context) site = context.getSite() # Create or update indexes addOrUpdateIndexes(site, indexInfos) addOrUpdateColumns(site, columnInfos) # Need to reinstall PloneMeeting after reinstalling MA workflows to re-apply wfAdaptations reinstallPloneMeeting(context, site) # Make sure the 'home' tab is shown showHomeTab(context, site) # reorder skins so we are sure that the meetingAndenne_xxx skins are just under custom reorderSkinsLayers(context, site) # reimport actions provider so that useless portal_tabs are not shown anymore reorderPortalTabs(context, site) # reimport plone.app.search javascript registry as some scripts are missing reorderScriptsRegistry(context, site) # Remove some types from the standard Plone search (live and advanced) props = site.portal_properties.site_properties nsTypes = props.getProperty('types_not_searched') if not nsTypes: nsTypes = [] else: nsTypes = list(nsTypes) for t in noSearchTypes: if t not in nsTypes: nsTypes.append(t) props.manage_changeProperties(types_not_searched=tuple(nsTypes)) # configure CKEditor configureCKEditor(context, site) # configure safe_html portal transform configureSafeHtml(context, site) # adapt gestion-courrier directory configureMailDirectory(context, site) # configure Products.cron4plone # add a call to @@run-docsplit-on-blobs that will run docsplit on a batch of # CourrierFile and MeetingFile objects until all migrated content is converted. # add a call to @@parse-converted-files that will monthly check that all convertable # objects are converted and that all conversion results are still linked to existing # objects. cron_configlet = queryUtility(ICronConfiguration, 'cron4plone_config') if not cron_configlet.cronjobs: cron_configlet.cronjobs = CRON_TASKS else: addCron = True cronView = CRON_TASKS[0].split(' ')[-1] for cron in cron_configlet.cronjobs: cron = cron.split(' ') if cron[-1] == cronView: addCron = False break if addCron: for task in CRON_TASKS: cron_configlet.cronjobs.append(task)