def _registerMeetingFactoryTypes(self): """Make sure every relevant portal_types are correctly registered in portal_factory.""" logger.info("Registering every Meeting types into portal_factory...") self.ps.runImportStepFromProfile('profile-Products.PloneMeeting:default', 'factorytool') # This will register portal_types to portal_factory self.reloadMeetingConfigs() logger.info('Done.')
def run(self, extra_omitted=[], from_migration_to_41=False): logger.info('Migrating to PloneMeeting 4101...') self._updateFacetedFilters() self._updateSearchLastDecisionsQuery() self._updateOrgsDashboardCollectionColumns() self._allowDashboardPODTemplateInDirectoryPortalType() self._addDashboardPODTemplateExportOrganizations() self._removeSelectableForPlonegroupFieldOnOrganizations() self._removeTagsParameterInCallToJSCallViewAndReloadInCloneToOtherMCActions( ) self._moveToMeetingConfigOnMeetingTransitionItemActionToExecute() self._migrateContactOrganizationPersonsKlass() self._correctAccessToPODTemplates() self.cleanRegistries() # holidays 2020 were added self.updateHolidays() # refresh if we are not coming from migration to 4.1, # in this case it was already refreshed if not from_migration_to_41: self.reindexIndexesFor(idxs=['get_full_title'], **{'portal_type': ['organization']}) reindexIndexes(self.portal, idxs=['getTakenOverBy', 'getConfigId']) # re-run the Meeting workflows update as there was a bug in Migrator.refreshDatabase meeting_wf_ids = self.getWorkflows(meta_types=['Meeting']) self.refreshDatabase(catalogs=False, workflows=True, workflowsToUpdate=meeting_wf_ids) self.tool.invalidateAllCache()
def run(self, from_migration_to_41=False): logger.info('Migrating to PloneMeeting 4107...') self._moveToItemCreatedOnlyUsingTemplate() self._registerMeetingFactoryTypes() self._updateUpdateDelayAwareAdvicecsCronJobTime() # reapply typeinfo as imio.zamqp.pm typeinfo was merged into Products.PloneMeeting self.ps.runImportStepFromProfile('profile-Products.PloneMeeting:default', 'typeinfo')
def run(self, extra_omitted=[]): logger.info('Migrating to PloneMeeting 4100...') self._updateFacetedFilters() # update new getAssociatedGroups metadata, as field is never used, # we only create the metadata but do not reindex it self.addCatalogIndexesAndColumns(update_metadata=False) set_use_stream(False)
def _updateFTWLabelsStorage(self): """ftw.labels jar was created using dict we need PersistentMappings...""" logger.info("Updating ftw.labels jar for every MeetingConfigs...") for cfg in self.tool.objectValues('MeetingConfig'): jar_storage = ILabelJar(cfg).storage for k, v in jar_storage.items(): jar_storage[k] = PersistentMapping(v) logger.info('Done.')
def run(self, from_migration_to_41=False): logger.info('Migrating to PloneMeeting 4108...') self._correctDashboardCollectionsQuery() # fix wrong condition for 'searchmyitemstakenover' # that used omittedSuffixes instead omitted_suffixes self.updateTALConditions(old_word='omittedSuffixes', new_word='omitted_suffixes') self.fix_email_from_address()
def _removeTagsParameterInCallToJSCallViewAndReloadInCloneToOtherMCActions( self): '''Parameter was remove from JS callViewAndReload, this is stored in clone to other mc actions on MeetingItem portal_types.''' logger.info("Calling registerPortalTypes for every MeetingConfigs...") for cfg in self.tool.objectValues('MeetingConfig'): cfg.registerPortalTypes() logger.info('Done.')
def _enableDateinputJSResource(self): """Make sure '++resource++plone.app.jquerytools.dateinput.js' is enabled in portal_javascripts.""" logger.info( "Enabling '++resource++plone.app.jquerytools.dateinput.js' in portal_javascripts..." ) resource = self.portal.portal_javascripts.getResource( '++resource++plone.app.jquerytools.dateinput.js') resource.setEnabled(True) logger.info('Done.')
def run(self, extra_omitted=[], from_migration_to_4200=False): logger.info('Migrating to PloneMeeting 4203...') # not necessary if executing the full upgrade to 4200 # as problem was introduced after 4200... if not from_migration_to_4200: self._adaptInternalImagesLinkToUseResolveUID() logger.info('Done.')
def run(self, extra_omitted=[], from_migration_to_4200=False): logger.info('Migrating to PloneMeeting 4201...') self._disableWscForCKeditor() # refresh if we are not coming from migration to 4200, # in this case it was already refreshed if not from_migration_to_4200: self._fixWFsUsingReturnedToProposingGroupWFAdaptation()
def _removeSelectableForPlonegroupFieldOnOrganizations(self): '''Remove attribute 'selectable_for_plonegroup' on organizations.''' logger.info( "Removing attribute 'selectable_for_plonegroup' on every organizations..." ) for brain in self.catalog(portal_type='organization'): org = brain.getObject() if hasattr(org, 'selectable_for_plonegroup'): delattr(org, 'selectable_for_plonegroup') logger.info('Done.')
def fix_email_from_address(self): logger.info("Fixing email from address...") mail_panel_adapter = MailControlPanelAdapter(self.portal) mail_address = mail_panel_adapter.get_email_from_address().strip() if "imio.be" in mail_address: public_url = get_public_url(self.portal) mail_address = public_url.replace("https://", "")\ .replace("-pm.imio-app", "-delib@imio") mail_panel_adapter.set_email_from_address(mail_address.strip(" /.")) logger.info('Done.')
def run(self, extra_omitted=[], from_migration_to_4200=False): logger.info('Migrating to PloneMeeting 4202...') # not necessary if executing the full upgrade to 4200 if not from_migration_to_4200: self._updateFacetedFilters() self._fixPreAcceptedWFA() # this is not managed by the main upgrade to 4200 self._fixFacetedFoldersConstrainTypes()
def _correctDashboardCollectionsQuery(self): """Format of DashboardCollection query is sometimes broken, instead containing list of <dict>, it contains list of <instance> ???.""" logger.info("Correcting query for DashboardCollections...") for cfg in self.tool.objectValues('MeetingConfig'): for subfolder in cfg.searches.objectValues(): for search in subfolder.objectValues(): query = deepcopy(search.query) query = [dict(crit) for crit in query] search.setQuery(query) logger.info('Done.')
def _allowDashboardPODTemplateInDirectoryPortalType(self): """Add 'DashboardPODTemplate' to 'allowed_content_types' of 'directory' portal_type.""" logger.info( "Adding 'DashboardPODTemplate' to 'allowed_content_types' of 'directory' portal_type..." ) pType = self.portal.portal_types['directory'] allowed_types = list(pType.allowed_content_types) if 'DashboardPODTemplate' not in allowed_types: allowed_types.append('DashboardPODTemplate') pType.allowed_content_types = allowed_types logger.info('Done.')
def _initMeetingsItemAttendeesOrder(self): """Initialize the item_attendees_order attribute for existing meetings.""" logger.info( 'Initializing "item_attendees_order" for every meetings...') brains = self.catalog(object_provides=IMeeting.__identifier__) for brain in brains: meeting = brain.getObject() if base_hasattr(meeting, "item_attendees_order"): continue meeting.item_attendees_order = PersistentMapping() meeting._p_changed = True logger.info('Done.')
def run(self, from_migration_to_41=False): logger.info('Migrating to PloneMeeting 4110...') self._migrateMeetingCategoryToDX() self._updateOrgsDashboardCollectionColumns() self._enableDateinputJSResource() self._addPageBreakStyleToCKEditor() self._migrateToMeetingItemTemplatesToStoreAsAnnex() # update collective.contact.plonegroup self.upgradeAll(omit=[ 'Products.PloneMeeting:default', self.profile_name.replace('profile-', '') ])
def _adaptHolidaysWarningMessage(self): '''Adapt holidays warning message to be less panicking...''' logger.info("Adapting content for message 'Holidays warning'...") message = self.portal.get('messages-config').get('holidays_warning') text = translate('holidays_warning_message', domain='PloneMeeting', context=self.request) message.text = RichTextValue(raw=text, mimeType='text/html', outputMimeType='text/html', encoding='utf-8') logger.info('Done.')
def _updateFacetedFilters(self): """Update vocabulary used for "Taken over by".""" logger.info( "Updating faceted filter \"Taken over by\" for every MeetingConfigs..." ) for cfg in self.tool.objectValues('MeetingConfig'): criteria = ICriteria(cfg.searches.searches_items) criteria.edit( 'c12', **{ 'vocabulary': 'Products.PloneMeeting.vocabularies.creatorswithnobodyforfacetedfiltervocabulary' }) logger.info('Done.')
def _updateOrgsDashboardCollectionColumns(self): """Make sure the 'review_state' column is not displayed in dashboards displaying organizations.""" logger.info( "Updating dashboard organization collections to remove the \"review_state\" column..." ) orgs_searches_folder = self.portal.contacts.get('orgs-searches') # hide the 'review_state' column for orgs related collections for org_coll in orgs_searches_folder.objectValues(): org_coll.customViewFields = [ col_name for col_name in org_coll.customViewFields if col_name != u'review_state' ] logger.info('Done.')
def _reloadItemTemplateAndRecurringTypes(self): """Reload MeetingItemTemplate/MeetingItemRecurring portal_types to fix the allowed_content_types to only accept "Image".""" logger.info( 'Reloading MeetingItemTemplate/MeetingItemRecurring portal_types...' ) # first update MeetingItemTemplate/MeetingItemRecurring base portal_types load_type_from_package('MeetingItemTemplate', 'Products.PloneMeeting:default') load_type_from_package('MeetingItemRecurring', 'Products.PloneMeeting:default') for cfg in self.tool.objectValues('MeetingConfig'): cfg.at_post_edit_script() logger.info('Done.')
def _updateFacetedFilters(self): """ """ logger.info("Updating faceted filters for every MeetingConfigs...") xmlpath_items = os.path.join( os.path.dirname(__file__), '../faceted_conf/upgrade_step_add_item_widgets.xml') for cfg in self.tool.objectValues('MeetingConfig'): obj = cfg.searches.searches_items # add new faceted filters for searches_items obj.unrestrictedTraverse('@@faceted_exportimport').import_xml( import_file=open(xmlpath_items)) logger.info('Done.')
def _migrateToMeetingItemTemplatesToStoreAsAnnex(self): """Single value field MeetingConfig.meetingItemTemplateToStoreAsAnnex was moved to multi valued field MeetingConfig.meetingItemTemplatesToStoreAsAnnex.""" logger.info( "Migrating MeetingConfig.meetingItemTemplateToStoreAsAnnex to " "MeetingConfig.meetingItemTemplatesToStoreAsAnnex...") old_field_name = 'meetingItemTemplateToStoreAsAnnex' new_field_name = 'meetingItemTemplatesToStoreAsAnnex' for cfg in self.tool.objectValues('MeetingConfig'): if base_hasattr(cfg, old_field_name): old_field_value = getattr(cfg, old_field_name) if old_field_value: setattr(cfg, new_field_name, [old_field_value]) logger.info('Done.')
def _umarkCreationFlagForEveryItems(self): """ """ brains = self.catalog(meta_type='MeetingItem') pghandler = ZLogHandler(steps=100) pghandler.init('Cleaning ftw.labels wrong annotations...', len(brains)) pghandler.info("Unmarking _at_creation_flag for every items...") i = 0 for brain in brains: i += 1 pghandler.report(i) item = brain.getObject() item.unmarkCreationFlag() pghandler.finish() logger.info('Done.')
def _updateFacetedFilters(self): """Update vocabulary used for "Taken over by". Make sure the default for contacts 'c5' widget is not a list.""" logger.info( "Updating faceted filter \"Taken over by\" for every MeetingConfigs..." ) for cfg in self.tool.objectValues('MeetingConfig'): obj = cfg.searches.searches_items # update vocabulary for relevant filters criteria = ICriteria(obj) criteria.edit( 'c12', **{ 'vocabulary': 'Products.PloneMeeting.vocabularies.creatorswithnobodyforfacetedfiltervocabulary' }) criteria.edit( 'c27', **{ 'vocabulary': 'Products.PloneMeeting.vocabularies.associatedgroupsvocabulary' }) logger.info('Done.') logger.info("Updating faceted filter \"Defined in\" for 'c5' " "criterion of contacts/orgs-searches...") obj = self.portal.contacts.get('orgs-searches') # as default is not correct (a string instead a list, we can not use edit or it fails to validate) criteria = ICriteria(obj) criterion = criteria.get('c5') criterion.default = u'collective.contact.plonegroup.interfaces.IPloneGroupContact' logger.info('Done.')
def run(self, extra_omitted=[], from_migration_to_4200=False): logger.info('Migrating to PloneMeeting 4204...') # not necessary if executing the full upgrade to 4200 if not from_migration_to_4200: _configurePortalRepository() self._reloadItemTemplateAndRecurringTypes() self._initMeetingsItemAttendeesOrder() # remove field MeetingConfig.transitionsForPresentingAnItem self.cleanMeetingConfigs( field_names=['transitionsForPresentingAnItem']) logger.info('Done.')
def _remapContactsWokflows(self): """Use 'plonemeeting_activity_managers_workflow' instead 'collective_contact_core_workflow' for person and held_position portal_types.""" logger.info( "Changing workflow for person and held_position portal_types...") person_wf = self.wfTool.getWorkflowsFor('person')[0] if person_wf.getId() != 'plonemeeting_activity_managers_workflow': remap_workflow(context=self.portal, type_ids=['person', 'held_position'], chain=['plonemeeting_activity_managers_workflow'], state_map={ 'active': 'active', 'deactivated': 'inactive' }) logger.info('Done.')
def _updateOrgsDashboardCollectionColumns(self): """Enable column 'PloneGroupUsersGroupsColumn' in contacts collections displaying organizations.""" logger.info( "Updating dashboard organization collections to remove the \"review_state\" column..." ) orgs_searches_folder = self.portal.contacts.get('orgs-searches') # enable 'PloneGroupUsersGroupsColumn' just after 'SelectedInPlonegroupColumn' for org_coll in orgs_searches_folder.objectValues(): customViewFields = list(org_coll.customViewFields) if 'PloneGroupUsersGroupsColumn' not in customViewFields: customViewFields.insert( customViewFields.index('SelectedInPlonegroupColumn') + 1, 'PloneGroupUsersGroupsColumn') org_coll.customViewFields = customViewFields logger.info('Done.')
def _moveToItemCreatedOnlyUsingTemplate(self): """Empty item are now also created using an itemTemplate, move to it.""" logger.info("Moving to empty item created from an item template...") for cfg in self.tool.objectValues('MeetingConfig'): default_template = cfg._create_default_item_template() if default_template: # move it to the top folder = default_template.aq_inner.aq_parent folder.folder_position_typeaware(position='top', id=default_template.getId()) # if cfg.itemCreatedOnlyUsingTemplate was True, disable created default template if getattr(cfg, 'itemCreatedOnlyUsingTemplate', False) is True: api.content.transition(default_template, transition='deactivate') # remove useless MeetingConfig.itemCreatedOnlyUsingTemplate field self.cleanMeetingConfigs(field_names=['itemCreatedOnlyUsingTemplate']) logger.info('Done.')
def force_email_from_address(self): logger.info("Fixing email from address...") mail_panel_adapter = MailControlPanelAdapter(self.portal) smtp_host = mail_panel_adapter.smtp_host or u'' if smtp_host.strip() != u'localhost': logger.info("Bypassing, smtp_host is not localhost...") else: public_url = get_public_url(self.portal) mail_address = public_url.replace("https://", "") if "-pm" not in mail_address: logger.info("Bypassing, \"-pm\" not found in public_url...") else: index = mail_address.index("-pm") mail_address = "*****@*****.**" % mail_address[:index] logger.info("Setting \"{0}\" as email_from_address.".format(mail_address)) mail_panel_adapter.set_email_from_address(mail_address) logger.info('Done.')