Esempio n. 1
0
    def setUpContent(self):
        pat.login(self.portal, testing.SITE_ADMIN)

        self.challenge = helpers.create_challenge(
            self.challenges, "a-real-challenge")

        for i in range(0, 20):
            wsId = "workspace_" + str(i)
            wsName = u"Workspace " + str(i)
            ws = ws_helpers.create_workspace(self.workspaces,
                wsId, title=wsName,
                challenges=[relatify(self.challenge)])
            modified(ws)

        for i in range(0, 5):
            projectId = 'project_' + str(i)
            projectName = u"Prøjėçt " + str(i)
            project = helpers.create_project(
                self.workspaces, projectId,
                title=projectName,
                challenges=[relatify(self.challenge)],
                description=u"A lengthy but interesting description",
                goals=u"Lorem ipsum. Add goals here.")
            ws_helpers.do_action_for(project, 'publish')

            for j in range(0,3):
                wsId = "project_workspace_" + str(i) + "_" + str(j)
                wsName = u"Project-Workspace " + str(i) + " " + str(j)
                ws = ws_helpers.create_workspace(self.workspaces,
                    wsId, title=wsName)
                project.add_workspace(ws)

        pat.logout()
    def test_challenge_stats_for_public_project(self):
        self.create_and_transition(
            "cnrd.Project", self.ws_folder, "p1", "publish", title=u"P1", 
            challenges=[relatify(self.challenge)])
        self.create_and_transition(
            "ixds.Workspace", self.ws_folder, "pws1", "publish", title=u"PWS1", 
            challenges=[relatify(self.challenge)])

        self.assertEqual(self.challenge.getNumWorkspaces(), 2)
    def test_challenge_stats_for_public_workspace(self):
        login(self.portal, testing.STUDENT)
        self.create_and_transition(
            "ixds.Workspace", self.ws_folder, "ws1", "publish", title=u"WS1", 
            challenges=[relatify(self.challenge)])

        self.assertEqual(self.challenge.getNumWorkspaces(), 1)
    def setUpContent(self):
        pat.login(self.portal, testing.SITE_ADMIN)
        self.challenge = helpers.create_challenge(
            self.challenges, "a-real-challenge")
        self.ws_owner = helpers.add_activated_student(
            self.people, u"Owen Owner")
        self.ws_admin = helpers.add_activated_student(
            self.people, u"Hörbert M@ier")
        self.ws_member = helpers.add_activated_student(
            self.people, u"Mandy Membr")

        pat.login(self.portal, self.ws_owner.id)
        self.ws = ws_helpers.create_workspace(
            self.workspaces,
            "workspace",
            title=u"Workspace",
            description=u"A lengthy but interesting description",
            goals=u"Lorem ipsum. Add goals here.",
            challenges=[relatify(self.challenge)])
        ws_helpers.do_action_for(self.ws,
            'publish-for-site-members-with-public-decription')
        self.ws.addManager(self.ws_admin.id)
        self.ws.addMember(self.ws_member.id)

        pat.logout()
    def save(self, action):
        data, errors = self.extractData()

        captcha = getMultiAdapter(
            (aq_inner(self.context), self.request),
            name='recaptcha'
        )
        if not captcha.verify():
            raise ActionExecutionError(Invalid(_(u"You must verify that you are no robot.")))

        if errors:
            self.status = self.formErrorsMessage
            return

        mtool = getToolByName(self.context, 'portal_membership')
        if mtool.isAnonymousUser():
            # Anonymous has the id None
            userId = None
        else:
            currentUser = mtool.getAuthenticatedMember()
            userId = currentUser.getId()

        # Check if the current user has 'Registrator' rights
        roles = list(self.context.get_local_roles_for_userid(userId))
        isRegistrator = 'Registrator' in roles or 'Manager' in roles or 'Site Administrator' in roles
        if not isRegistrator:
            roles.append('Registrator')
            self.context.manage_setLocalRoles(userId, roles)

        urltool = getToolByName(self.context, 'portal_url')
        portal = urltool.getPortalObject()

        member_folder = portal['people']
        member = add_member_object(member_folder, data['id'], data['title'], data['emailAddress'])
        member.role = data['role']
        member.recieveNotifications = data['recieveNotifications']
        if data['description'] is not None:
            member.description = data['description']
        if data['portrait'] is not None:
            member.portrait = data['portrait']
        if data['university'] is not None:
            member.university = relatify(data['university'])

        confirm = _(u"Thank you! Your registration request has been received " +
                    u"and we will respond as soon as possible.")
        IStatusMessage(self.request).add(confirm, type='info')
        self.request.response.redirect(portal.absolute_url())
        return u''
def create_test_content(site):
    catalog = getToolByName(site, 'portal_catalog')
    portal_workflow = getToolByName(site, 'portal_workflow')

    print '### Creating test content on "%s" ###' % site

    print "creating challenges..."

    challenges = [
        {
            'portal_type': 'cnrd.Challenge',
            'title': u'Challenge 1',
            'description': u'Interesting description.',
            'icon': named_image(150, 150),
            'publish': False,
            'finalize': [challenge_finalizer],
        },
        {
            'portal_type': 'cnrd.Challenge',
            'title': u'Challenge 2',
            'description': u'Another interesting description.',
            'icon': named_image(150, 150),
            'publish': False,
            'finalize': [challenge_finalizer],
        },
    ]

    stats = build(challenges, site['challenges'])
    print '  %i created, %i modified, %i skipped, %i recursions.' % stats

    print "creating universities..."

    universities = [
        {
            'portal_type': 'cnrd.University',
            'title': u'University of Roma',
            'text': richtextify(u'<p>Some nice words.</p>'),
            'picture': named_image(150, 150),
            'location': 'Roma',
            'publish': True,
            'finalize': [university_finalizer],
        },
        {
            'portal_type': 'cnrd.University',
            'title': u'University of Helsinki',
            'text': richtextify(u'<p>Some nice words.</p>'),
            'picture': named_image(150, 150),
            'location': 'Helsinki',
            'publish': True,
            'finalize': [university_finalizer],
        },
    ]

    stats = build(universities, site['universities'])
    print '  %i created, %i modified, %i skipped, %i recursions.' % stats

    print "creating members..."

    members = [
        {
            'portal_type': 'cnrd.Member',
            'id': 'test_user_1',
            'title': u'Test User',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(150, 300, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'student',
            'publish': False,
            'finalize': [
                (covalent_utilities.add_plone_member, {'password': '******'}),
                covalent_utilities.activate_member_object],
        },
        {
            'portal_type': 'cnrd.Member',
            'id': 'test_user_2',
            'title': u'Karl Heinz',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(300, 150, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'student',
            'publish': False,
            'finalize': [
                (covalent_utilities.add_plone_member, {'password': '******'}),
                covalent_utilities.activate_member_object],
        },
        {
            'portal_type': 'cnrd.Member',
            'id': 'new-student',
            'title': u'New Student',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(300, 150, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'student',
            'as_user': '******',
            'publish': False,
        },
        {
            'portal_type': 'cnrd.Member',
            'id': 'rejected-student',
            'title': u'Rejected Student',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(300, 150, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'student',
            'as_user': '******',
            'publish': False,
            'finalize': [
                setToRejected],
        },
        {
            'portal_type': 'cnrd.Member',
            'id': 'pending-student',
            'title': u'Pending Student',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(300, 150, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'student',
            'publish': False,
        },
        {
            'portal_type': 'cnrd.Member',
            'id': 'expired-student',
            'title': u'Expired Student',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(300, 150, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'student',
            'publish': False,
            'finalize': [
                setToExpired],
        },
        {
            'portal_type': 'cnrd.Member',
            'id': 'active-student',
            'title': u'Active Student',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(300, 150, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'student',
            'publish': False,
            'finalize': [
                (covalent_utilities.add_plone_member, {'password': '******'}),
                covalent_utilities.activate_member_object],
        },
        {
            'portal_type': 'cnrd.Member',
            'id': 'inactive-student',
            'title': u'Inactive Student',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(300, 150, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'student',
            'publish': False,
            'finalize': [
                (covalent_utilities.add_plone_member, {'password': '******'}),
                covalent_utilities.activate_member_object,
                (portal_workflow.doActionFor, {'action': 'deactivate'})],
        },
        {
            'portal_type': 'cnrd.Member',
            'id': 'new_test_student_1',
            'title': u'New Test Student 1',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(300, 150, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'student',
            'as_user': '******',
            'publish': False,
            'finalize': [],
        },
        {
            'portal_type': 'cnrd.Member',
            'id': 'new_test_student_2',
            'title': u'New Test Student 2',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(300, 150, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'student',
            'as_user': '******',
            'publish': False,
            'finalize': [],
        },
        {
            'portal_type': 'cnrd.Member',
            'id': 'new_test_teacher',
            'title': u'New Test Teacher',
            'emailAddress': '*****@*****.**',
            'description': u'What are you lookin\' at?',
            'portrait': named_blob_image(300, 150, filename=u"member_img.png"),
            'university': relatify(site['universities'][utilities.find_possible_id(
                'University of Helsinki')]),
            'role': 'teacher',
            'as_user': '******',
            'publish': False,
            'finalize': [],
        },
    ]
    stats = build(members, site['people'])
    print '  %i created, %i modified, %i skipped, %i recursions.' % stats

    addSiteAdminsToAdminGroup(site)

    print "creating workspaces..."
    workspaces = [
        {
            'portal_type': 'ixds.Workspace',
            'title': u'My Workspace Draft',
            'description': u'Interesting description.',
            'challenges': [
                relatify(site['challenges']['challenge-1']),
            ],
            'members': set(),
            'previouslyEdited': True,
            'publish': False,
            'finalize': [
                (set_dates, {'date': DateTime() - 1})],
        },
        {
            'portal_type': 'ixds.Workspace',
            'title': u'Workspace 1',
            'description': u'Interesting description.',
            'challenges': [
                relatify(site['challenges']['challenge-1']),
            ],
            'members': set(['test_user_1', 'test_user_2', ]),
            'images': [named_image(150, 150), ],
            'previouslyEdited': True,
            'finalize': [
                update_workspace_image_fields,
                (set_dates, {'date': DateTime() - 80})],
        },
        {
            'portal_type': 'ixds.Workspace',
            'title': u'Workspace 2',
            'description': u'Another interesting description.',
            'challenges': [
                relatify(site['challenges']['challenge-2']),
            ],
            'members': set(['test_user_1', ]),
            'images': [named_image(150, 150), ],
            'previouslyEdited': True,
            'finalize': [
                update_workspace_image_fields,
                (set_dates, {'date': DateTime() - 70})],
        },
        {
            'portal_type': 'ixds.Workspace',
            'title': u'Empty workspace',
            'description': u'There is nothing in here, trust me.',
            'challenges': [
                relatify(site['challenges']['challenge-2']),
            ],
            'members': set(['test_user_1', ]),
            'images': [named_image(150, 150), ],
            'previouslyEdited': True,
            'finalize': [
                update_workspace_image_fields,
                (set_dates, {'date': DateTime() - 70})],
        },
        {
            'portal_type': 'ixds.Workspace',
            'title': u'Workspace with many posts',
            'description': u'This workspace certainly has a lot of posts.',
            'challenges': [
                relatify(site['challenges']['challenge-2']),
            ],
            'members': set(['test_user_1', ]),
            'images': [named_image(150, 150), ],
            'previouslyEdited': True,
            'finalize': [
                update_workspace_image_fields,
                (set_dates, {'date': DateTime() - 14})],
        },
        {
            'portal_type': 'ixds.Workspace',
            'title': u'Workspace with tasks',
            'description': u'',
            'challenges': [
                relatify(site['challenges']['challenge-2']),
            ],
            'members': set(['test_user_1', ]),
            'images': [named_image(150, 150), ],
            'previouslyEdited': True,
            'finalize': [
                update_workspace_image_fields,
                (set_dates, {'date': DateTime() - 14})],
        },
        {
            'portal_type': 'ixds.Workspace',
            'title': u'Workspace with polls',
            'description': u'',
            'challenges': [
                relatify(site['challenges']['challenge-2']),
            ],
            'members': set(['test_user_1', ]),
            'images': [named_image(150, 150), ],
            'previouslyEdited': True,
            'finalize': [
                update_workspace_image_fields,
                (set_dates, {'date': DateTime() - 14})],
        },
        {
            'portal_type': 'ixds.Workspace',
            'title': u'Workspace with files',
            'description': u'',
            'challenges': [
                relatify(site['challenges']['challenge-2']),
            ],
            'members': set(['test_user_2', ]),
            'images': [named_image(150, 150), ],
            'previouslyEdited': True,
            'finalize': [
                update_workspace_image_fields,
                (set_dates, {'date': DateTime() - 14})],
        },
    ]

    stats = build(workspaces, site['workspaces'])
    print '  %i created, %i modified, %i skipped, %i recursions.' % stats

    print "creating posts and files..."
    posts = [
        {
            'portal_type': 'ixds.Post',
            'title': u'Post 1',
            'text': richtextify(u'<p>This is text.</p>'),
            'parent': site['workspaces']['workspace-1'],
            'as_user': '******',
        },
        {
            'portal_type': 'ixds.Post',
            'title': u'Post 2',
            'text': richtextify(u'<p>This is more text.</p>'
                u'<p>More text, again.</p>'),
            'parent': site['workspaces']['workspace-1'],
            'as_user': '******',
            'items': [
                {
                    'portal_type': 'ixds.Reply',
                    'title': u'Reply 1',
                    'text': richtextify(u'<p>That\'s obvious.</p>'),
                    'as_user': '******',
                    'publish': False,
                    'finalize': [notify_form_completed],
                },
                {
                    'portal_type': 'ixds.Reply',
                    'title': u'Reply 2',
                    'text': richtextify(u'<p>Indeed.</p>'),
                    'as_user': '******',
                    'publish': False,
                    'finalize': [notify_form_completed],
                },
            ],
        },
        # tasks:
        {
            'portal_type': 'ixds.Task',
            'title': u'Task in the future',
            'text': richtextify(u'<p>This is fresh text.</p>'),
            'parent': site['workspaces']['workspace-with-tasks'],
            'date': DateTime() + 7,
            'finalize': [(covalent_utilities.set_owner_and_creator, {'userid': 'test_user_2'})],
        },
        {
            'portal_type': 'ixds.Task',
            'title': u'Task in the past',
            'text': richtextify(u'<p>This is text from long ago.</p>'),
            'parent': site['workspaces']['workspace-with-tasks'],
            'date': DateTime() - 7,
            'finalize': [(covalent_utilities.set_owner_and_creator, {'userid': 'test_user_2'})],
        },
        # polls and ratings:
        {
            'portal_type': 'ixds.Poll',
            'pollOrRating': 'poll',
            'options': set(['the one', 'the other']),
            'title': u'The poll from the past',
            'text': richtextify(u'<p>This is text from long ago.</p>'),
            'parent': site['workspaces']['workspace-with-polls'],
            'date': DateTime() - 7,
            'deadline': datetime.now() - timedelta(days=3),
            'finalize': [(covalent_utilities.set_owner_and_creator, {'userid': 'test_user_2'}),
                poll.initialize],
        },
        {
            'portal_type': 'ixds.Poll',
            'pollOrRating': 'rating',
            'options': set(range(1, 6)),
            'title': u'The rating from the past',
            'text': richtextify(u'<p>This is text from long ago.</p>'),
            'parent': site['workspaces']['workspace-with-polls'],
            'date': DateTime() - 6,
            'deadline': datetime.now() - timedelta(days=4),
            'finalize': [(covalent_utilities.set_owner_and_creator, {'userid': 'test_user_2'}),
                poll.initialize],
        },
        {
            'portal_type': 'ixds.Poll',
            'pollOrRating': 'poll',
            'options': set(['the one', 'the other']),
            'title': u'The poll',
            'text': richtextify(u'<p>This is text.</p>'),
            'parent': site['workspaces']['workspace-with-polls'],
            'date': DateTime() - 1,
            'deadline': datetime.now() + timedelta(days=7),
            'finalize': [(covalent_utilities.set_owner_and_creator, {'userid': 'test_user_2'}),
                poll.initialize],
        },
        {
            'portal_type': 'ixds.Poll',
            'pollOrRating': 'rating',
            'options': set(range(1, 6)),
            'title': u'The rating',
            'text': richtextify(u'<p>This is text.</p>'),
            'parent': site['workspaces']['workspace-with-polls'],
            'date': DateTime() - 2,
            'deadline': datetime.now() + timedelta(days=6),
            'finalize': [(covalent_utilities.set_owner_and_creator, {'userid': 'test_user_2'}),
                poll.initialize],
        },
        # (posts with) files:
        {
            'portal_type': 'ixds.Post',
            'title': u'Post with attached files',
            'text': richtextify(u'<p>This is text.</p>'),
            'parent': site['workspaces']['workspace-with-files'],
            'publish': False,
            'as_user': '******',
            'items': [
                {
                    'portal_type': 'RichFile',
                    'title': u'File with meta-data',
                    'rmMediaType': 'images',
                    'rmAuthor': u'Peter Müller',
                    'rmTags': ['scientific', 'handout'],
                    'public': True,
                    'fileData': namedfile.NamedBlobFile(dummy_image(50, 50),
                        filename=u"some_image.png"),
                    'publish': False,
                    'as_user': '******',
                    'finalize': [
                        notify_form_completed],
                },
                {
                    'portal_type': 'RichFile',
                    'title': u'Another File with meta-data',
                    'rmMediaType': 'images',
                    'rmAuthor': u'Peter Müller',
                    'rmTags': ['bachelor'],
                    'public': True,
                    'fileData': namedfile.NamedBlobFile(dummy_image(50, 50),
                        filename=u"some_other_image.png"),
                    'publish': False,
                    'as_user': '******',
                    'finalize': [
                        notify_form_completed],
                },
            ],
            'finalize_branch': [fileuploadcapable.publish_post],
        },
        {
            'portal_type': 'ixds.Post',
            'title': u'Post with attached file that has no meta-data',
            'text': richtextify(u'<p>This is text.</p>'),
            'parent': site['workspaces']['workspace-with-files'],
            'publish': False,
            'finalize': [(covalent_utilities.set_owner_and_creator, {'userid': 'test_user_2'})],
            'items': [
                {
                    'portal_type': 'RichFile',
                    'id': 'file_without_meta_data',
                    'fileData': namedfile.NamedBlobFile(dummy_image(50, 50),
                        filename=u"file_without_meta_data.png"),
                    'publish': False,
                    'finalize': [
                        (covalent_utilities.set_owner_and_creator, {'userid': 'test_user_2'})],
                },
                {
                    'portal_type': 'RichFile',
                    'id': 'another_file_without_meta_data',
                    'fileData': namedfile.NamedBlobFile(dummy_image(50, 50),
                        filename=u"another_file_without_meta_data.png"),
                    'publish': False,
                    'finalize': [
                        (covalent_utilities.set_owner_and_creator, {'userid': 'test_user_2'})],
                },
            ],
            'finalize_branch': [fileuploadcapable.publish_post],
        },
    ]

    for i in range(1, 25):
        posts.append({
            'portal_type': 'ixds.Post',
            'title': u'Post %d of many' % i,
            'text': richtextify(u'<p>This is text.</p>'),
            'parent': site['workspaces']['workspace-with-many-posts'],
            'finalize': [
                (covalent_utilities.set_owner_and_creator, {'userid': 'test_user_2'}),
                (set_dates, {'date': DateTime() - 25 + i}),
            ],
        })

    stats = build(posts)
    print '  %i created, %i modified, %i skipped, %i recursions.' % stats
    print
    print "reindexing... ",

    catalog.manage_catalogRebuild()

    print "done."
Esempio n. 7
0
def add_demo_content(
    context,
    minUsers=1,
    maxUsers=1,
    minCallenges=1,
    maxChallenges=1,
    minWorkspacePerChallenge=1,
    maxWorkspacePerChallenge=1,
    minMembersPerWorkspace=1,
    maxMembersPerWorkspace=1,
    minPostPerWorkspace=1,
    maxPostPerWorkspace=1,
):
    site = context
    catalog = getToolByName(site, "portal_catalog")

    print '### Creating demo content on "%s" ###' % site

    # create a 'demo-users'-group
    group_id = "demo-users"
    groups_tool = getToolByName(site, "portal_groups")
    if not group_id in groups_tool.getGroupIds():
        groups_tool.addGroup(group_id)

    # create users and add them to the 'demo-users'-group
    nUsers = random.randint(minUsers, maxUsers)
    for i in range(0, nUsers):
        first = get_word().title()
        last = get_word().title()
        uid = "_".join([first, last]).lower()
        email = "*****@*****.**" % (uid)
        passwd = "secret"
        portrait = None
        if random.choice([True, False]):
            portrait = namedfile.NamedBlobImage(
                random_image(random.randint(150, 300), random.randint(150, 300)), filename=u"%s.jpg" % (get_word())
            )
        add_cnrd_member(site, uid, last, first, email, passwd, portrait)
        groups_tool.addPrincipalToGroup(uid, group_id)
    print "### %i members created. ###" % nUsers

    # create challenges
    nChallenges = random.randint(minCallenges, maxChallenges)
    print "  creating %i challenges..." % (nChallenges)
    challenges = []
    for i in range(0, nChallenges):

        challenges.append(
            {
                "portal_type": "cnrd.Challenge",
                "title": get_words(1, 4),
                "description": get_words(4, 12),
                "icon": namedfile.NamedImage(random_image(150, 150), filename=u"nice_image.jpg"),
                "publish": False,
                "finalize": [challenge_finalizer, mark_as_democontent],
            }
        )

    stats = build(challenges, site["challenges"])
    print "  %i created, %i modified, %i skipped, %i recursions. ###" % stats

    # create workspaces
    workspaces = []
    for c in site["challenges"].listFolderContents():

        # leave this challenge alone if it's not demo-content
        if not IDemoContent.providedBy(c):
            continue

        print "challenge '%s' with %i items" % (c.title, c.getNumWorkspaces())

        nWorkspaces = random.randint(minWorkspacePerChallenge, maxWorkspacePerChallenge)
        print "  creating %i workspaces..." % (nWorkspaces)

        # create some workspaces
        for i in range(0, nWorkspaces):
            usersIds = site["people"].keys()
            nWsMembers = random.randint(
                min(minMembersPerWorkspace, len(usersIds)), min(maxMembersPerWorkspace, len(usersIds))
            )
            date = DateTime() - (nWorkspaces - i) * random.randint(6, 66)

            workspaces.append(
                {
                    "portal_type": "ixds.Workspace",
                    "title": get_words(1, 4),
                    "description": u"",
                    "challenges": [relatify(c)],
                    "members": set(random.sample(usersIds, nWsMembers)),
                    "images": [
                        namedfile.NamedImage(
                            random_image(random.randint(100, 400), random.randint(300, 800)),
                            filename=u"%s.jpg" % (get_word()),
                        )
                        for ii in range(0, random.randint(1, 2))
                    ],
                    "previouslyEdited": True,
                    "finalize": [update_workspace_image_fields, (set_dates, {"date": date}), mark_as_democontent],
                }
            )

    stats = build(workspaces, site["workspaces"])
    print "  %i created, %i modified, %i skipped, %i recursions. ###" % stats

    # create posts
    posts = []
    for ws in site["workspaces"].listFolderContents():

        # leave this workspace alone if it's not demo-content
        if not IDemoContent.providedBy(ws):
            continue

        print "workspace '%s' with %i entries" % (ws.title, ws.getNumEntries())

        nPosts = random.randint(minPostPerWorkspace, maxPostPerWorkspace)
        print "  creating %i posts..." % (nPosts)

        for i in range(0, nPosts):
            nParagraphs = random.randint(1, 2)
            text = u"".join((u"<p>%s</p>" % p for p in get_paragraphs(nParagraphs)))

            delta = DateTime() - ws.created()
            date = ws.created() + delta * random.random()

            posts.append(
                {
                    "portal_type": "ixds.Post",
                    "title": get_words(1, 6),
                    "text": richtextify(text),
                    "parent": ws,
                    "finalize": [
                        (set_dates, {"date": date}),
                        (set_owner_and_creator, {"userid": random.choice(list(ws.getMemberIds()))}),
                    ],
                }
            )

    stats = build(posts)
    print "  %i created, %i modified, %i skipped, %i recursions. ###" % stats
    print
    print "reindexing... ",

    catalog.manage_catalogRebuild()

    print "done."