def __call__( self, migrate=False, content_types='all', migrate_schemaextended_content=False, migrate_references=True, from_form=False, reindex_catalog=True, patch_searchabletext=False, ): portal = self.context if not from_form and migrate not in ['1', 'True', 'true', 1]: url1 = '{0}/@@migrate_from_atct?migrate=1'.format( portal.absolute_url()) url2 = '{0}/@@atct_migrator'.format(portal.absolute_url()) msg = u'Warning \n' msg += u'-------\n' msg += u'You are accessing "@@migrate_from_atct" directly. ' msg += u'This will migrate all content to dexterity!\n\n' msg += u'Really migrate all content now: {0}\n\n'.format(url1) msg += u'First select what to migrate: {0}'.format(url2) return msg helpers = getMultiAdapter((portal, self.request), name='atct_migrator_helpers') if helpers.linguaplone_installed(): msg = 'Warning\n' msg += 'Migration aborted since Products.LinguaPlone is ' msg += 'installed. See ' msg += 'http://github.com/plone/plone.app.contenttypes#migration ' msg += 'for more information.' return msg stats_before = self.stats() starttime = datetime.now() self.request['plone.app.contenttypes_migration_running'] = True msg = 'Starting Migration\n\n' msg += '\n-----------------------------\n' msg += 'Content statictics:\n' msg += pformat(stats_before) msg += '\n-----------------------------\n' msg += 'Types to be migrated:\n' msg += pformat(content_types) msg += '\n-----------------------------\n' logger.info(msg) # store references on the portal if migrate_references: store_references(portal) catalog = portal.portal_catalog # Patch various things that make migration harder (link_integrity, queue_indexing, patch_searchabletext) = patch_before_migration(patch_searchabletext) not_migrated = [] migrated_types = {} for (k, v) in ATCT_LIST.items(): if content_types != 'all' and k not in content_types: not_migrated.append(k) continue # test if the ct is extended beyond blobimage and blobfile if len(isSchemaExtended(v['iface'])) > len(v['extended_fields']) \ and not migrate_schemaextended_content: not_migrated.append(k) continue query = { 'object_provides': v['iface'].__identifier__, 'meta_type': v['old_meta_type'], } amount_to_be_migrated = len(catalog(query)) starttime_for_current = datetime.now() logger.info('Start migrating {0} objects from {1} to {2}'.format( amount_to_be_migrated, v['old_meta_type'], v['type_name'], )) installTypeIfNeeded(v['type_name']) # call the migrator v['migrator'](portal) # logging duration_current = datetime.now() - starttime_for_current duration_human = str(timedelta(seconds=duration_current.seconds)) logger.info( 'Finished migrating {0} objects from {1} to {2} in {3}'.format( amount_to_be_migrated, v['old_meta_type'], v['type_name'], duration_human), ) # some data for the results-page migrated_types[k] = {} migrated_types[k]['amount_migrated'] = amount_to_be_migrated migrated_types[k]['old_meta_type'] = v['old_meta_type'] migrated_types[k]['type_name'] = v['type_name'] # if there are blobnewsitems we just migrate them silently. migration.migrate_blobnewsitems(portal) # make sure the view-methods on the plone site are updated use_new_view_names(portal, types_to_fix=['Plone Site']) if reindex_catalog: catalog.clearFindAndRebuild() # restore references if migrate_references: restore_references(portal) # Revert to the original state undo_patch_after_migration(link_integrity, queue_indexing, patch_searchabletext) duration = str(timedelta(seconds=(datetime.now() - starttime).seconds)) if not_migrated: msg = ('The following types were not migrated: \n {0}'.format( '\n'.join(not_migrated))) else: msg = 'Migration successful\n\n' msg += '\n-----------------------------\n' msg += 'Migration finished in: {0}'.format(duration) msg += '\n-----------------------------\n' msg += 'Migration statictics:\n' msg += pformat(migrated_types) msg += '\n-----------------------------\n' msg += 'State before:\n' msg += pformat(stats_before) msg += '\n-----------------------------\n' msg += 'Stats after:\n' msg += pformat(self.stats()) msg += '\n-----------------------------\n' if not from_form: logger.info(msg) return msg else: stats = { 'duration': duration, 'before': stats_before, 'after': self.stats(), 'content_types': content_types, 'migrated_types': migrated_types, } logger.info(msg) return stats
def __call__(self, migrate=False, content_types='all', migrate_schemaextended_content=False, migrate_references=True, from_form=False, reindex_catalog=True, patch_searchabletext=False, ): portal = self.context if not from_form and migrate not in ['1', 'True', 'true', 1]: url1 = '{0}/@@migrate_from_atct?migrate=1'.format( portal.absolute_url()) url2 = '{0}/@@atct_migrator'.format(portal.absolute_url()) msg = u'Warning \n' msg += u'-------\n' msg += u'You are accessing "@@migrate_from_atct" directly. ' msg += u'This will migrate all content to dexterity!\n\n' msg += u'Really migrate all content now: {0}\n\n'.format(url1) msg += u'First select what to migrate: {0}'.format(url2) return msg helpers = getMultiAdapter((portal, self.request), name='atct_migrator_helpers') if helpers.linguaplone_installed(): msg = 'Warning\n' msg += 'Migration aborted since Products.LinguaPlone is ' msg += 'installed. See ' msg += 'http://github.com/plone/plone.app.contenttypes#migration ' msg += 'for more information.' return msg stats_before = self.stats() starttime = datetime.now() self.request['plone.app.contenttypes_migration_running'] = True msg = 'Starting Migration\n\n' msg += '\n-----------------------------\n' msg += 'Content statictics:\n' msg += pformat(stats_before) msg += '\n-----------------------------\n' msg += 'Types to be migrated:\n' msg += pformat(content_types) msg += '\n-----------------------------\n' logger.info(msg) # store references on the portal if migrate_references: store_references(portal) catalog = portal.portal_catalog # Patch various things that make migration harder (link_integrity, queue_indexing, patch_searchabletext) = patch_before_migration(patch_searchabletext) not_migrated = [] migrated_types = {} for (k, v) in ATCT_LIST.items(): if content_types != 'all' and k not in content_types: not_migrated.append(k) continue # test if the ct is extended beyond blobimage and blobfile if len(isSchemaExtended(v['iface'])) > len(v['extended_fields']) \ and not migrate_schemaextended_content: not_migrated.append(k) continue query = { 'object_provides': v['iface'].__identifier__, 'meta_type': v['old_meta_type'], } amount_to_be_migrated = len(catalog(query)) starttime_for_current = datetime.now() logger.info( 'Start migrating {0} objects from {1} to {2}'.format( amount_to_be_migrated, v['old_meta_type'], v['type_name'], ) ) installTypeIfNeeded(v['type_name']) # call the migrator v['migrator'](portal) # logging duration_current = datetime.now() - starttime_for_current duration_human = str(timedelta(seconds=duration_current.seconds)) logger.info( 'Finished migrating {0} objects from {1} to {2} in {3}'.format( amount_to_be_migrated, v['old_meta_type'], v['type_name'], duration_human), ) # some data for the results-page migrated_types[k] = {} migrated_types[k]['amount_migrated'] = amount_to_be_migrated migrated_types[k]['old_meta_type'] = v['old_meta_type'] migrated_types[k]['type_name'] = v['type_name'] # if there are blobnewsitems we just migrate them silently. migration.migrate_blobnewsitems(portal) # make sure the view-methods on the plone site are updated use_new_view_names(portal, types_to_fix=['Plone Site']) if reindex_catalog: catalog.clearFindAndRebuild() # restore references if migrate_references: restore_references(portal) # Revert to the original state undo_patch_after_migration( link_integrity, queue_indexing, patch_searchabletext) duration = str(timedelta(seconds=(datetime.now() - starttime).seconds)) if not_migrated: msg = ( 'The following types were not migrated: \n {0}'.format( '\n'.join(not_migrated) ) ) else: msg = 'Migration successful\n\n' msg += '\n-----------------------------\n' msg += 'Migration finished in: {0}'.format(duration) msg += '\n-----------------------------\n' msg += 'Migration statictics:\n' msg += pformat(migrated_types) msg += '\n-----------------------------\n' msg += 'State before:\n' msg += pformat(stats_before) msg += '\n-----------------------------\n' msg += 'Stats after:\n' msg += pformat(self.stats()) msg += '\n-----------------------------\n' if not from_form: logger.info(msg) return msg else: stats = { 'duration': duration, 'before': stats_before, 'after': self.stats(), 'content_types': content_types, 'migrated_types': migrated_types, } logger.info(msg) return stats
def migrateCustomAT( fields_mapping, src_type, dst_type, dry_run=False, patch_linkintegrity=False, patch_searchabletext=False, query=None, ): """ Try to get types infos from archetype_tool, then set a migrator and pass it given values. There is a dry_run mode that allows to check the success of a migration without committing. """ portal = getSite() # Patch various things that make migration harder (link_integrity, queue_indexing, patch_searchabletext) = patch_before_migration(patch_searchabletext) # if the type still exists get the src_meta_type from the portal_type portal_types = getToolByName(portal, 'portal_types') fti = portal_types.get(src_type, None) # Check if the fti was removed or replaced by a DX-implementation if fti is None or IDexterityFTI.providedBy(fti): # Get the needed info from an instance of the type catalog = portal.portal_catalog brains = catalog(portal_type=src_type, sort_limit=1) if not brains: # no item? assume stuff is_folderish = False src_meta_type = src_type else: try: src_obj = brains[0].getObject() except (KeyError, NotFound): logger.error('Could not find the object for brain at %s', brains[0].getURL()) return if IDexterityContent.providedBy(src_obj): logger.error('%s should not be dexterity object!', src_obj.absolute_url()) is_folderish = getattr(src_obj, 'isPrincipiaFolderish', False) src_meta_type = src_obj.meta_type else: # fallback is_folderish = False # Get info from at-fti src_meta_type = fti.content_meta_type archetype_tool = getToolByName(portal, 'archetype_tool', None) for info in archetype_tool.listRegisteredTypes(): # lookup registered type in archetype_tool with meta_type # because several portal_types can use same meta_type if info.get('meta_type') == src_meta_type: klass = info.get('klass', None) is_folderish = klass.isPrincipiaFolderish break migrator = makeCustomATMigrator(context=portal, src_type=src_type, dst_type=dst_type, fields_mapping=fields_mapping, is_folderish=is_folderish, dry_run=dry_run) walker_infos = None if migrator: migrator.src_meta_type = src_meta_type migrator.dst_meta_type = '' walker_settings = { 'portal': portal, 'migrator': migrator, 'src_portal_type': src_type, 'dst_portal_type': dst_type, 'src_meta_type': src_meta_type, 'dst_meta_type': '', 'use_savepoint': True } if query: walker_settings['query'] = query if dry_run: walker_settings['limit'] = 1 walker = CustomQueryWalker(**walker_settings) walker.go() walker_infos = { 'errors': walker.errors, 'msg': walker.getOutput().splitlines(), 'counter': walker.counter } for error in walker.errors: logger.error(error.get('message')) if dry_run: transaction.abort() # Revert to the original state undo_patch_after_migration(link_integrity, queue_indexing, patch_searchabletext) return walker_infos
def migrateCustomAT(fields_mapping, src_type, dst_type, dry_run=False, patch_linkintegrity=False, patch_searchabletext=False, ): """ Try to get types infos from archetype_tool, then set a migrator and pass it given values. There is a dry_run mode that allows to check the success of a migration without committing. """ portal = getSite() # Patch various things that make migration harder (link_integrity, queue_indexing, patch_searchabletext) = patch_before_migration(patch_searchabletext) # if the type still exists get the src_meta_type from the portal_type portal_types = getToolByName(portal, 'portal_types') fti = portal_types.get(src_type, None) # Check if the fti was removed or replaced by a DX-implementation if fti is None or IDexterityFTI.providedBy(fti): # Get the needed info from an instance of the type catalog = portal.portal_catalog brains = catalog(portal_type=src_type, sort_limit=1) if not brains: # no item? assume stuff is_folderish = False src_meta_type = src_type else: try: src_obj = brains[0].getObject() except (KeyError, NotFound): logger.error( 'Could not find the object for brain at %s', brains[0].getURL()) return if IDexterityContent.providedBy(src_obj): logger.error( '%s should not be dexterity object!', src_obj.absolute_url()) is_folderish = getattr(src_obj, 'isPrincipiaFolderish', False) src_meta_type = src_obj.meta_type else: # Get info from at-fti src_meta_type = fti.content_meta_type archetype_tool = getToolByName(portal, 'archetype_tool', None) for info in archetype_tool.listRegisteredTypes(): # lookup registered type in archetype_tool with meta_type # because several portal_types can use same meta_type if info.get('meta_type') == src_meta_type: klass = info.get('klass', None) is_folderish = klass.isPrincipiaFolderish migrator = makeCustomATMigrator(context=portal, src_type=src_type, dst_type=dst_type, fields_mapping=fields_mapping, is_folderish=is_folderish, dry_run=dry_run) walker_infos = None if migrator: migrator.src_meta_type = src_meta_type migrator.dst_meta_type = '' walker_settings = {'portal': portal, 'migrator': migrator, 'src_portal_type': src_type, 'dst_portal_type': dst_type, 'src_meta_type': src_meta_type, 'dst_meta_type': '', 'use_savepoint': True} if dry_run: walker_settings['limit'] = 1 walker = CustomQueryWalker(**walker_settings) walker.go() walker_infos = {'errors': walker.errors, 'msg': walker.getOutput().splitlines(), 'counter': walker.counter} for error in walker.errors: logger.error(error.get('message')) if dry_run: transaction.abort() # Revert to the original state undo_patch_after_migration( link_integrity, queue_indexing, patch_searchabletext) return walker_infos