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