コード例 #1
0
def recursive_create_path(path):
    if path in ('/', ''):
        folder = site
    else:
        path = path.lstrip('/')
        folder = traverse(path)
        if folder is not None and not IFolder.providedBy(folder):
            api.content.delete(folder)
            folder = None
        if folder is None:
            # Need to create folders up to where we want content
            # we'll walk it up create folders as needed
            folder = site
            for part in path.split('/'):
                try:
                    ob = folder[part]
                    if not IFolder.providedBy(ob):
                        api.content.delete(ob)
                        raise KeyError()
                    else:
                        folder = ob
                except (KeyError, AttributeError):
                    fpath = os.path.join(args.export_directory,
                                         relpath(folder), part, '__folder__')

                    if os.path.exists(fpath):
                        fi = open(fpath)
                        data = mjson.loads(fi.read())
                        fi.close()
                        importtype = get_import_type(
                            data, fpath[len(args.export_directory):], None)
                        creation_data = importtype.get_data()
                        creation_data['container'] = folder
                        creation_data['id'] = part
                        try:
                            folder = api.content.create(**creation_data)
                        except api.exc.InvalidParameterError:
                            logger.error(
                                'Error creating content {}'.format(fpath),
                                exc_info=True)
                            return
                        importtype.post_creation(folder)
                        if data['state']:
                            try:
                                api.content.transition(folder,
                                                       to_state=data['state'])
                            except:
                                # maybe workflows do not match up
                                pass
                        folder.reindexObject()
                    else:
                        folder = api.content.create(type='Folder',
                                                    id=part,
                                                    title=part.capitalize(),
                                                    container=folder)
                        bdata = ILayoutAware(folder)
                        bdata.contentLayout = '++contentlayout++castle/folder-query.html'
    return folder
コード例 #2
0
    def import_object(self, filepath, container=None):
        fi = open(filepath)
        file_read = fi.read()
        fi.close()
        try:
            data = mjson.loads(file_read)
        except Exception:
            print("Skipping {}; Unable to read JSON data".format(filepath))
            return
        if filepath.endswith('__folder__'):
            filepath = '/'.join(filepath.split('/')[:-1])

        skipped = False
        if data['portal_type'] in skip_types:
            print('Skipping omitted type {type}'.format(
                type=data['portal_type']))
            skipped = True
        if only_types and data['portal_type'] not in only_types:
            print("Skipping {type} at {path}, not in only_types.".format(
                type=data['portal_type'], path=filepath))
            skipped = True
        if import_paths:
            do_import = False
            for import_path in import_paths:
                if filepath.startswith('{}/{}'.format(args.export_directory,
                                                      import_path)):
                    do_import = True
                if import_path.startswith(
                        filepath[len(args.export_directory):].lstrip('/') +
                        '/'):
                    # Don't skip folders on the way to import_paths
                    do_import = True
            if not do_import:
                print("Skipping {path}, not in import_paths".format(
                    path=filepath))
                skipped = True
        if skip_paths:
            for skip_path in skip_paths:
                if filepath.lower().startswith('{}/{}'.format(
                        args.export_directory, skip_path)):
                    print(
                        "Skipping {path}, in skip_paths".format(path=filepath))
                    skipped = True
        if skipped:
            if os.path.isdir(filepath) and len(os.listdir(filepath)):
                logger.warn('{path} contains additional content that will be '
                            'skipped.'.format(path=filepath))
            return

        original_path = filepath[len(args.export_directory):]
        if retain_paths:
            importtype = get_import_type(data, original_path, 'retain_paths')
        else:
            importtype = get_import_type(data, original_path)
        path = importtype.get_path()

        if container is None:
            logger.warn(
                'Skipped {} because of creation error'.format(filepath))
            return
        _id = path.split('/')[-1]

        create = True
        if _id in container.objectIds():
            if args.overwrite:
                existing = container[_id]
                if IFolder.providedBy(existing):
                    if len(existing.objectIds()):
                        print("OVERWRITE: Deleting non-empty container {path}".
                              format(path=path))
                else:
                    print("OVERWRITE: Deleting content item at {path}".format(
                        path=path))
                api.content.delete(container[_id])
            else:
                create = False

        creation_data = importtype.get_data()
        pc_data = importtype.get_post_creation_data()
        creation_data['container'] = container

        aspect = ISelectableConstrainTypes(container, None)
        if aspect:
            if (aspect.getConstrainTypesMode() != 1 or [creation_data['type']]
                    != aspect.getImmediatelyAddableTypes()):
                aspect.setConstrainTypesMode(1)
                aspect.setImmediatelyAddableTypes([creation_data['type']])
        if create:
            if ignore_uuids and '_plone.uuid' in creation_data:
                del creation_data['_plone.uuid']

            obj = None
            if not args.overwrite and (_id in container.objectIds()):
                print('Skipping {path}, already exists. Use --overwrite to'
                      ' create anyway.'.format(path=path))
                return
            elif (not ignore_uuids
                  and api.content.get(UID=creation_data['_plone.uuid'])
                  is not None):
                logger.warn(
                    'Skipping {path}, content with its UUID already exists.'
                    'Use --ignore-uuids to create anyway.'.format(path=path))
                return
            else:
                try:
                    obj = api.content.create(safe_id=True, **creation_data)
                    print('Created {path}'.format(path=path))
                    self.imported_count += 1
                    if self.imported_count % 50 == 0:
                        print('%i processed, committing' % self.imported_count)
                        transaction.commit()
                except api.exc.InvalidParameterError:
                    if stop_if_exception:
                        logger.error(
                            'Error creating content {}'.format(filepath),
                            exc_info=True)
                        if pdb_if_exception:
                            pdb.set_trace()
                        raise
                    logger.error('Error creating content {}'.format(filepath),
                                 exc_info=True)
                    return

    # TODO check default folder pages came over as folder with rich text tile
    # TODO any folder pages without default page should have content listing tile
        else:
            obj = container[_id]
            for key, value in creation_data.items():
                if key not in ('id', 'type'):
                    setattr(obj, key, value)

        if obj is not None:
            if path != original_path:
                storage = getUtility(IRedirectionStorage)
                rpath = os.path.join('/'.join(site.getPhysicalPath()),
                                     original_path.strip('/'))
                storage.add(rpath, "/".join(obj.getPhysicalPath()))

            obj.contentLayout = importtype.layout
            importtype.post_creation(obj, post_creation_data=pc_data)
            if not args.skip_transitioning and data['state']:
                # transition item only if it needs it
                state = api.content.get_state(obj=obj)
                if state != data['state']:
                    try:
                        print('Transitioning %s to %s' %
                              (obj.id, data['state']))
                        api.content.transition(obj, to_state=data['state'])
                    except Exception:
                        logger.error(
                            "Error transitioning %s to %s, maybe workflows"
                            " don't match up" % (obj.id, data['state']))
                        # pass
                        if stop_if_exception:
                            if pdb_if_exception:
                                pdb.set_trace()
                            raise

            # set workflow / review history
            if 'review_history' in data:
                review_history = data['review_history']
                wtool = api.portal.get_tool(name='portal_workflow')
                # loop over all workflow chains (usually only 1)
                for workflow_id in wtool.getChainFor(obj):
                    obj.workflow_history[workflow_id] = review_history
            else:
                logger.warn('No review history on {obj}'.format(obj=obj))

            fix_html_images(obj)
            obj.reindexObject()
            try:
                modification_date = data['data']['modification_date']
                obj.setModificationDate(modification_date)
                obj.reindexObject(idxs=['modified'])
                logger.info('    set modification date to %s' %
                            modification_date)
            except Exception:
                logger.info(
                    'Could not set modification date on {obj}'.format(obj=obj))
            return obj
コード例 #3
0
def import_object(filepath, count):
    fi = open(filepath)
    data = mjson.loads(fi.read())
    fi.close()
    if filepath.endswith('__folder__'):
        filepath = '/'.join(filepath.split('/')[:-1])

    if data['portal_type'] in ('Topic', 'Collection', 'PressRoom'):
        return

    original_path = filepath[len(args.export_directory):]
    importtype = get_import_type(data, original_path, _read_phase)
    path = importtype.get_path()
    folder = recursive_create_path('/'.join(path.split('/')[:-1]))
    if folder is None:
        print('Skipped {} because of creation error'.format(filepath))
    _id = path.split('/')[-1]

    create = True
    if _id in folder.objectIds():
        if args.overwrite:
            if data['portal_type'] == 'Folder':
                cnt = folder[_id]
                if len(folder.objectIds()) == 1 or len(cnt.objectIds()) == 0:
                    api.content.delete(folder[_id])
            else:
                api.content.delete(folder[_id])
        else:
            create = False

    print('import path: %s' % path)
    creation_data = importtype.get_data()
    creation_data['container'] = folder

    aspect = ISelectableConstrainTypes(folder, None)
    if aspect:
        if (aspect.getConstrainTypesMode() != 1 or
            [creation_data['type']] != aspect.getImmediatelyAddableTypes()):
            aspect.setConstrainTypesMode(1)
            aspect.setImmediatelyAddableTypes([creation_data['type']])

    if create:
        try:
            obj = api.content.create(**creation_data)
        except api.exc.InvalidParameterError:
            return logger.error('Error creating content {}'.format(filepath),
                                exc_info=True)
    else:
        obj = folder[_id]
        for key, value in creation_data.items():
            if key not in ('id', 'type'):
                setattr(obj, key, value)

    if path != original_path:
        storage = getUtility(IRedirectionStorage)
        rpath = os.path.join('/'.join(site.getPhysicalPath()),
                             original_path.strip('/'))
        storage.add(rpath, "/".join(obj.getPhysicalPath()))

    importtype.post_creation(obj)
    if data['state']:
        try:
            api.content.transition(obj, to_state=data['state'])
        except:
            # maybe workflows do not match up
            pass

    fix_html_images(obj)
    obj.reindexObject()

    if count % 50 == 0:
        print('%i processed, committing' % count)
        transaction.commit()
        app._p_jar.invalidateCache()  # noqa
        transaction.begin()
        app._p_jar.sync()  # noqa