def test_relations_are_migrated(self):
        from plone.app.contenttypes.migration.migration import (
            restoreReferences,
            migrate_documents,
        )

        # IIntIds is not registered in the test env. So register it here
        sm = getSiteManager(self.portal)
        addUtility(sm, IIntIds, IntIds, ofs_name='intids', findroot=False)

        # create ATDocuments
        self.portal.invokeFactory('Document', 'doc1')
        at_doc1 = self.portal['doc1']
        self.portal.invokeFactory('Document', 'doc2')
        at_doc2 = self.portal['doc2']
        self.portal.invokeFactory('Document', 'doc3')
        at_doc3 = self.portal['doc3']
        self.portal.invokeFactory('News Item', 'newsitem')
        at_newsitem = self.portal['newsitem']

        # relate them
        at_doc1.setRelatedItems([at_doc2])
        at_doc2.setRelatedItems([at_newsitem, at_doc3, at_doc1])
        at_doc3.setRelatedItems(at_doc1)

        # migrate content
        applyProfile(self.portal, 'plone.app.contenttypes:default')
        migrate_documents(self.portal)
        dx_doc1 = self.portal['doc1']
        dx_doc2 = self.portal['doc2']
        dx_doc3 = self.portal['doc3']

        # migrate references
        restoreReferences(self.portal)

        # assert single references
        dx_doc1_related = [x.to_object for x in dx_doc1.relatedItems]
        self.assertEqual(dx_doc1_related, [dx_doc2])

        dx_doc3_related = [x.to_object for x in dx_doc3.relatedItems]
        self.assertEqual(dx_doc3_related, [dx_doc1])

        # assert multi references, order is restored
        dx_doc2_related = [x.to_object for x in dx_doc2.relatedItems]
        self.assertEqual(dx_doc2_related, [at_newsitem, dx_doc3, dx_doc1])
Example #2
0
    def test_relations_are_migrated(self):
        from Products.ATContentTypes.content.document import ATDocument
        from plone.app.contenttypes.migration.migration import DocumentMigrator

        # IIntIds is not registered in the test env. So register it here
        sm = getSiteManager(self.portal)
        addUtility(sm, IIntIds, IntIds, ofs_name='intids', findroot=False)

        # create three ATDocument
        at_doc1 = self.createATCTobject(ATDocument, 'doc1')
        at_doc2 = self.createATCTobject(ATDocument, 'doc2')
        at_doc3 = self.createATCTobject(ATDocument, 'doc3')

        # relate them
        at_doc1.setRelatedItems([at_doc2.UID(), ])
        at_doc2.setRelatedItems([at_doc1, at_doc3])
        at_doc3.setRelatedItems(at_doc1)

        # migrate
        migrator = self.get_migrator(at_doc1, DocumentMigrator)
        migrator.migrate()
        migrator = self.get_migrator(at_doc2, DocumentMigrator)
        migrator.migrate()
        migrator = self.get_migrator(at_doc3, DocumentMigrator)
        migrator.migrate()
        restoreReferences(self.portal)

        # assertions
        new_doc1 = self.portal['doc1']
        new_doc2 = self.portal['doc2']
        new_doc3 = self.portal['doc3']

        self.assertEqual(len(new_doc1.relatedItems), 1)
        rel1 = new_doc1.relatedItems[0]
        self.assertEqual(rel1.to_object, new_doc2)
        self.assertEqual(len(new_doc2.relatedItems), 2)
        rel1 = new_doc2.relatedItems[0]
        rel2 = new_doc2.relatedItems[1]
        self.assertEqual(
            set([rel1.to_object, rel2.to_object]), set([new_doc1, new_doc3]))
        self.assertEqual(len(new_doc3.relatedItems), 1)
        rel1 = new_doc3.relatedItems[0]
        self.assertEqual(rel1.to_object, new_doc1)
Example #3
0
def migrateAT2DX(context):
    """
    @param context: Products.GenericSetup.context.DirectoryImportContext instance
    """

    # We check from our GenericSetup context whether we are running
    # add-on installation for your product or any other proudct
    if context.readDataFile('migrateAT2DX.txt') is None:
        # Not your add-on
        return

    portal = context.getSite()
    migration.migrate_folders(portal)
    migration.migrate_documents(portal)
    migration.migrate_collections(portal)
    migration.migrate_blobimages(portal)
    migration.migrate_blobfiles(portal)
    migration.migrate_blobnewsitems(portal)
    migration.restoreReferences(portal)
    migration.restoreReferencesOrder(portal)
    def __call__(self,
                 migrate=False,
                 content_types="all",
                 migrate_schemaextended_content=False,
                 migrate_references=True,
                 from_form=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()
        catalog = portal.portal_catalog

        # switch linkintegrity temp off
        ptool = queryUtility(IPropertiesTool)
        site_props = getattr(ptool, 'site_properties', None)
        link_integrity = site_props.getProperty('enable_link_integrity_checks',
                                                False)
        site_props.manage_changeProperties(enable_link_integrity_checks=False)

        # switch of setModificationDate on changes
        self.patchNotifyModified()

        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'],
            }
            if HAS_MULTILINGUAL and 'Language' in catalog.indexes():
                query['Language'] = 'all'
            amount_to_be_migrated = len(catalog(query))
            starttime_for_current = datetime.now()
            logger.info("Start migrating %s objects from %s to %s" % (
                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 %s objects from %s to %s in %s" % (
                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)

        if migrate_references:
            migration.restoreReferences(portal)

        # switch linkintegrity back to what it was before migrating
        site_props.manage_changeProperties(
            enable_link_integrity_checks=link_integrity
        )

        # switch on setModificationDate on changes
        self.resetNotifyModified()

        duration = str(timedelta(seconds=(datetime.now() - starttime).seconds))
        if not_migrated:
            msg = ("The following types were not migrated: \n %s"
                   % "\n".join(not_migrated))
        else:
            msg = "Migration successful\n\n"
        msg += '\n-----------------------------\n'
        msg += 'Migration finished in: %s' % 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,
            }
            return stats
Example #5
0
    def __call__(self,
                 content_types="all",
                 migrate_schemaextended_content=False,
                 migrate_references=True,
                 from_form=False):

        stats_before = self.stats()
        starttime = datetime.now()
        portal = self.context
        helpers = getMultiAdapter((portal, self.context),
                                  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

        # switch linkintegrity temp off
        ptool = queryUtility(IPropertiesTool)
        site_props = getattr(ptool, 'site_properties', None)
        link_integrity = site_props.getProperty('enable_link_integrity_checks',
                                                False)
        site_props.manage_changeProperties(enable_link_integrity_checks=False)

        not_migrated = []

        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
            # call the migrator
            v['migrator'](portal)

        # if there are blobnewsitems we just migrate them silently.
        migration.migrate_blobnewsitems(portal)

        if migrate_references:
            migration.restoreReferences(portal)
            migration.restoreReferencesOrder(portal)

        # switch linkintegrity back to what it was before migrating
        site_props.manage_changeProperties(
            enable_link_integrity_checks=link_integrity
        )
        endtime = datetime.now()
        duration = (endtime - starttime).seconds
        if not from_form:
            if not_migrated:
                msg = ("The following were not migrated as they "
                       "have extended schemas (from "
                       "archetypes.schemaextender): \n %s"
                       % "\n".join(not_migrated))
            else:
                msg = "Default content types successfully migrated\n\n"

            msg += 'Migration finished in %s seconds' % duration
            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'
            return msg
        else:
            stats = {
                'duration': duration,
                'before': stats_before,
                'after': self.stats()
            }
            return stats
Example #6
0
    def __call__(self,
                 migrate=False,
                 content_types="all",
                 migrate_schemaextended_content=False,
                 migrate_references=True,
                 from_form=False):

        portal = self.context
        if content_types == 'all':
            content_types = DEFAULT_TYPES

        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()
        catalog = portal.portal_catalog

        # switch linkintegrity temp off
        ptool = queryUtility(IPropertiesTool)
        site_props = getattr(ptool, 'site_properties', None)
        link_integrity = site_props.getProperty('enable_link_integrity_checks',
                                                False)
        site_props.manage_changeProperties(enable_link_integrity_checks=False)

        # switch of setModificationDate on changes
        self.patchNotifyModified()

        # patch UUIDIndex
        patch(UUIDIndex, 'insertForwardIndexEntry',
              patched_insertForwardIndexEntry)

        not_migrated = []
        migrated_types = {}

        for (k, v) in ATCT_LIST.items():
            if 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'],
            }
            if HAS_MULTILINGUAL and 'Language' in catalog.indexes():
                query['Language'] = 'all'
            amount_to_be_migrated = len(catalog(query))
            starttime_for_current = datetime.now()
            logger.info(
                "Start migrating %s objects from %s to %s" %
                (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 %s objects from %s to %s in %s" %
                        (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)

        catalog.clearFindAndRebuild()

        # rebuild catalog, restore references and cleanup
        migration.restoreReferences(portal, migrate_references, content_types)

        # switch linkintegrity back to what it was before migrating
        site_props.manage_changeProperties(
            enable_link_integrity_checks=link_integrity)

        # switch on setModificationDate on changes
        self.resetNotifyModified()

        # unpatch UUIDIndex
        undoPatch(UUIDIndex, 'insertForwardIndexEntry')

        duration = str(timedelta(seconds=(datetime.now() - starttime).seconds))
        if not_migrated:
            msg = ("The following types were not migrated: \n %s" %
                   "\n".join(not_migrated))
        else:
            msg = "Migration successful\n\n"
        msg += '\n-----------------------------\n'
        msg += 'Migration finished in: %s' % 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