Пример #1
0
 def test_unicode(self):
     from karl.views.utils import make_name
     context = {}
     self.assertEqual(make_name(context, u'what?'), "what")
     self.assertEqual(make_name(context, u"\u0fff"), "-fff-")
     self.assertEqual(make_name(context, u"\u0081\u0082"), "-81-82-")
     self.assertEqual(make_name(context, u'foo\u008ab\u00c3ll'), "foosball")
Пример #2
0
 def test_unicode(self):
     from karl.views.utils import make_name
     context = {}
     self.assertEqual(make_name(context, u'what?'), "what")
     self.assertEqual(make_name(context, u"\u0fff"), "-fff-")
     self.assertEqual(make_name(context, u"\u0081\u0082"), "-81-82-")
     self.assertEqual(make_name(context, u'foo\u008ab\u00c3ll'), "foosball")
Пример #3
0
 def __call__(self, v):
     if v in self.exceptions:
         return
     try:
         make_name(self.container, v)
     except ValueError, why:
         raise Invalid(why[0])
Пример #4
0
 def __call__(self, v):
     if v in self.exceptions:
         return
     try:
         make_name(self.container, v)
     except ValueError, why:
         raise Invalid(why[0])
Пример #5
0
 def test_make_name_without_error(self):
     from karl.views.utils import make_name
     context = testing.DummyModel()
     context['foo.bar'] = testing.DummyModel()
     try:
         self.assertEqual(make_name(context, "foo.bar"), 'foo.bar')
     except ValueError:
         pass
     else:
         self.fail("Expected a ValueError")
     self.assertEqual(make_name(context, "Test 1", raise_error=False), 'test-1')
Пример #6
0
 def test_make_name_without_error(self):
     from karl.views.utils import make_name
     context = testing.DummyModel()
     context['foo.bar'] = testing.DummyModel()
     try:
         self.assertEqual(make_name(context, "foo.bar"), 'foo.bar')
     except ValueError:
         pass
     else:
         self.fail("Expected a ValueError")
     self.assertEqual(make_name(context, "Test 1", raise_error=False),
                      'test-1')
Пример #7
0
    def handle_submit(self, converted):
        request = self.request
        context = self.context
        workflow = self.workflow
        wikipage = create_content(
            IWikiPage,
            converted['title'],
            converted['text'],
            extract_description(converted['text']),
            authenticated_userid(request),
        )

        name = make_name(context, converted['title'])
        context[name] = wikipage

        if workflow is not None:
            workflow.initialize(wikipage)
            if 'security_state' in converted:
                workflow.transition_to_state(wikipage, request,
                                             converted['security_state'])

        # Save the tags on it.
        set_tags(wikipage, request, converted['tags'])

        relocate_temp_images(wikipage, request)

        if converted['sendalert']:
            alerts = queryUtility(IAlerts, default=Alerts())
            alerts.emit(wikipage, request)

        msg = '?status_message=Wiki%20Page%20created'
        location = resource_url(wikipage, request) + msg
        return HTTPFound(location=location)
Пример #8
0
    def create(self, container):
        """
        container is root['people']['categories'], or moral equivalent.
        """
        title = self._element_value(self.element, 'title')
        sync_id = self.element.get('id')
        name = make_name(container, title)
        description = self._element_value(self.element, 'description')

        category_element = self.element.find(self.NS_PREFIX + 'category')
        category_id = category_element.get('id')
        category = container.get(category_id, None)
        if category is None:
            category = PeopleCategory(category_element.text.strip())
            container[category_id] = category
            peopledir = find_peopledirectory(container)
            notify(PeopleDirectorySchemaChanged(peopledir))

        category_item = PeopleCategoryItem(title, description)
        if sync_id is not None:
            category_item.sync_id = sync_id  # OSI artifact

        if name in category:
            del category[name]
        category[name] = category_item
Пример #9
0
    def handle_submit(self, converted):
        request = self.request
        context = self.context
        workflow = self.workflow
        wikipage = create_content(
            IWikiPage,
            converted['title'],
            converted['text'],
            extract_description(converted['text']),
            authenticated_userid(request),
            )

        name = make_name(context, converted['title'])
        context[name] = wikipage

        if workflow is not None:
            workflow.initialize(wikipage)
            if 'security_state' in converted:
                workflow.transition_to_state(wikipage,
                                             request,
                                             converted['security_state'])

        # Save the tags on it.
        set_tags(wikipage, request, converted['tags'])

        relocate_temp_images(wikipage, request)

        if converted['sendalert']:
            alerts = queryUtility(IAlerts, default=Alerts())
            alerts.emit(wikipage, request)

        msg = '?status_message=Wiki%20Page%20created'
        location = model_url(wikipage, request) + msg
        return HTTPFound(location=location)
Пример #10
0
    def handle_submit(self, converted):
        request = self.request
        context = self.context
        name = make_name(context, converted['title'])
        userid = authenticated_userid(request)
        community = create_content(
            ICommunity,
            converted['title'],
            converted['description'],
            converted['text'],
            userid,
        )
        community.sendalert_default = converted.get('sendalert_default', True)
        # this *must* directly follow content creation because the
        # toolinfo add stuff depends on the community having a full
        # path.
        context[name] = community

        # required to use moderators_group_name and
        # members_group_name
        community.__name__ = name
        tools_present = []
        for toolinfo in self.available_tools:
            if toolinfo['name'] in converted.get('tools', []):
                toolinfo['component'].add(community, request)
                tools_present.append(toolinfo['name'])

        # Set the default tool
        if converted.get('default_tool') in tools_present:
            community.default_tool = converted['default_tool']
        else:
            community.default_tool = None

        users = find_users(context)
        moderators_group_name = community.moderators_group_name
        members_group_name = community.members_group_name

        for group_name in moderators_group_name, members_group_name:
            users.add_group(userid, group_name)

        if self.workflow is not None:
            if 'security_state' in converted:
                self.workflow.transition_to_state(community, request,
                                                  converted['security_state'])
        # Save the tags on it.
        set_tags(community, request, converted['tags'])
        # Adding a community should take you to the Add Existing
        # User screen, so the moderator can include some users.
        location = resource_url(community,
                                request,
                                'members',
                                'add_existing.html',
                                query={'status_message': 'Community added'})
        return HTTPFound(location=location)
Пример #11
0
    def handle_submit(self, converted):
        request = self.request
        context = self.context
        name = make_name(context, converted['title'])
        userid = authenticated_userid(request)
        community = create_content(ICommunity,
                                   converted['title'],
                                   converted['description'],
                                   converted['text'],
                                   userid,
                                   )
        community.sendalert_default = converted.get('sendalert_default', True)
        # this *must* directly follow content creation because the
        # toolinfo add stuff depends on the community having a full
        # path.
        context[name] = community

        # required to use moderators_group_name and
        # members_group_name
        community.__name__ = name
        tools_present = []
        for toolinfo in self.available_tools:
            if toolinfo['name'] in converted.get('tools', []):
                toolinfo['component'].add(community, request)
                tools_present.append(toolinfo['name'])

        # Set the default tool
        if converted.get('default_tool') in tools_present:
            community.default_tool = converted['default_tool']
        else:
            community.default_tool = None

        users = find_users(context)
        moderators_group_name = community.moderators_group_name
        members_group_name = community.members_group_name

        for group_name in moderators_group_name, members_group_name:
            users.add_group(userid, group_name)

        if self.workflow is not None:
            if 'security_state' in converted:
                self.workflow.transition_to_state(community, request,
                                                  converted['security_state'])
        # Save the tags on it.
        set_tags(community, request, converted['tags'])
        # Adding a community should take you to the Add Existing
        # User screen, so the moderator can include some users.
        location = resource_url(
            community, request,
            'members', 'add_existing.html',
            query={'status_message': 'Community added'})
        return HTTPFound(location=location)
Пример #12
0
 def menu_item(title, url, id=None, count=None, secondary=None):
     if id is None:
         id = make_name(EMPTY_CONTEXT, title)
     selected = request.url.startswith(url)
     if secondary is not None and not selected:
         selected = request.url.startswith(secondary)
     item = dict(title=title,
                 url=url,
                 id=id,
                 selected=selected and 'selected' or None)
     if count is not None:
         item['count'] = count
     return item
Пример #13
0
 def menu_item(title, url, id=None, count=None, secondary=None):
     if id is None:
         id = make_name(EMPTY_CONTEXT, title)
     selected = request.resource_url(context).startswith(url)
     if secondary is not None and not selected:
         selected = request.resource_url(context).startswith(secondary)
     item = dict(title=title,
                 url=url,
                 id=id,
                 selected=selected and 'selected' or None)
     if count is not None:
         item['count'] = count
     return item
Пример #14
0
    def handle_submit(self, converted):
        request = self.request
        context = self.context
        workflow = self.workflow

        creator = authenticated_userid(request)

        f = converted['file']

        if not f.file:
            raise ValidationError(file='Must upload a file')

        file = create_content(ICommunityFile,
                              title=converted['title'],
                              stream=f.file,
                              mimetype=get_mimetype(f.mimetype, f.filename),
                              filename=f.filename,
                              creator=creator,
                              )
        self.check_upload_size(context, file, 'file')

        # For file objects, OSI's policy is to store the upload file's
        # filename as the objectid, instead of basing __name__ on the
        # title field).
        filename = basename_of_filepath(f.filename)
        file.filename = filename
        name = make_name(context, filename, raise_error=False)
        if not name:
            msg = 'The filename must not be empty'
            raise ValidationError(file=msg)
        # Is there a key in context with that filename?
        if name in context:
            msg = 'Filename %s already exists in this folder' % filename
            raise ValidationError(file=msg)
        context[name] = file

        if workflow is not None:
            workflow.initialize(file)
            if 'security_state' in converted:
                workflow.transition_to_state(file, request,
                                             converted['security_state'])

        # Tags, attachments, alerts
        set_tags(file, request, converted['tags'])
        if converted.get('sendalert'):
            alerts = queryUtility(IAlerts, default=Alerts())
            alerts.emit(file, request)

        self.filestore.clear()
        location = model_url(file, request)
        return HTTPFound(location=location)
Пример #15
0
 def test_make_name(self):
     from karl.views.utils import make_name
     context = {}
     self.assertEqual(make_name(context, "foo.bar"), "foo.bar")
     self.assertEqual(make_name(context, "Harry 'Bigfoot' Henderson"),
                      "harry-bigfoot-henderson")
     self.assertEqual(make_name(context, "Which one?"), "which-one")
     self.assertEqual(make_name(context, "One/Two/Three"), "one-two-three")
     self.assertEqual(make_name(context, "Genesis 1:1"), "genesis-1-1")
     self.assertEqual(make_name(context, "'My Life'"), "-my-life-")
Пример #16
0
 def test_make_name(self):
     from karl.views.utils import make_name
     context = {}
     self.assertEqual(make_name(context, "foo.bar"), "foo.bar")
     self.assertEqual(make_name(context, "Harry 'Bigfoot' Henderson"),
                      "harry-bigfoot-henderson")
     self.assertEqual(make_name(context, "Which one?"), "which-one")
     self.assertEqual(make_name(context, "One/Two/Three"), "one-two-three")
     self.assertEqual(make_name(context, "Genesis 1:1"), "genesis-1-1")
     self.assertEqual(make_name(context, "'My Life'"), "-my-life-")
Пример #17
0
    def handle_submit(self, converted):
        request = self.request
        context = self.context

        intranets_parent = find_community(context)
        name = converted.get('name')
        if name:
            name_from = 'name'
        else:
            name = converted['title']
            name_from = 'title'
        try:
            name = make_name(intranets_parent, name)
        except ValueError, why:
            msg = why[0]
            raise ValidationError(**{name_from: msg})
Пример #18
0
 def relocate(match):
     matchdict = match.groupdict()
     tempid = matchdict['tempid']
     if tempid in relocated_images:
         # Already relocated this one
         url = relocated_images[tempid]
     else:
         # Move temp image to attachments folder
         image = tempfolder[tempid]
         del tempfolder[tempid]
         name = make_name(attachments, image.filename)
         attachments[name] = image
         size = (int(matchdict['width']), int(matchdict['height']))
         url = thumb_url(image, request, size)
         relocated_images[tempid] = url
     return ''.join([matchdict['pre'], url, matchdict['post'],])
Пример #19
0
    def handle_submit(self, converted):
        request = self.request
        context = self.context

        intranets_parent = find_community(context)
        name = converted.get('name')
        if name:
            name_from = 'name'
        else:
            name = converted['title']
            name_from = 'title'
        try:
            name = make_name(intranets_parent, name)
        except ValueError, why:
            msg = why[0]
            raise ValidationError(**{name_from: msg})
Пример #20
0
    def create(self, container):
        """
        container is root['people'].categories, or moral equivalent.
        """
        title = _element_value(self, self.element, 'title')
        sync_id = self.element.get('id')
        name = make_name(container, title)
        description = _element_value(self, self.element, 'description')

        category_element = self.element.find(self.NS_PREFIX + 'category')
        category_id = category_element.get('id')
        category = container.get(category_id, None)
        if category is None:
            category = PeopleCategory(category_element.text.strip())
            container[category_id] = category
            peopledir = find_peopledirectory(container)
            notify(PeopleDirectorySchemaChanged(peopledir))

        category_item = PeopleCategoryItem(title, description)
        if sync_id is not None:
            category_item.sync_id = sync_id # OSI artifact

        category[name] = category_item
Пример #21
0
def _fix_link_traverser(context, traversed, subpath):
    if not subpath:
        # We're done, return traversed path
        return '/' + '/'.join(traversed)

    next = subpath.pop(0)

    # Easy case, normal traversal
    if hasattr(context, '__getitem__') and next in context:
        traversed.append(next)
        return _fix_link_traverser(context[next], traversed, subpath)

    # Karl2 site was actually rooted at /Plone/public
    # Although you wouldn't normally include that in a link url,
    # because of acquisition you could!
    # If we find this or some variation at the beginning of a link
    # just try to skip it.
    skippable = (
        'Plone',
        'public',
    )
    if not traversed and next in skippable:
        return _fix_link_traverser(context, traversed, subpath)

    # An 'index_html' at the end is not necessary and skippable.
    # Some links inexplicably end with a '/&', which is also
    # skippable.
    skippable2 = (
        'index_html',
        '&',
    )
    if next in skippable2:
        return _fix_link_traverser(context, traversed, subpath)

    # Can't find next element.  Maybe it is a view
    if _check_view(context, next):
        # We can stop here, traversed path with view
        traversed.append(next)
        return '/' + '/'.join(traversed + subpath)

    # In Karl2 there was a content type for images that used a view
    # In Karl3, these are just files, so where we might have had a
    # view named 'image' in Karl2, we just have the 'dl' view in Karl3
    if next == 'image' and _check_view(context, 'dl'):
        # Got the view, we can stop here
        traversed.append('dl')
        return '/' + '/'.join(traversed + subpath)

    # Maybe next was resolved via acquisition in Karl2
    aq_context = _acquire(context, next)
    if aq_context:
        # Rewrite the leading part of this path as the model_path of the
        # acquired context.
        aq_path = model_path(aq_context)
        log.debug("Acquisition: rewrote path: %s -> %s", traversed, aq_path)
        traversed = aq_path[1:].split('/')
        return _fix_link_traverser(aq_context, traversed, subpath)

    # Next may have been processed through make_name in Karl3.  Try
    # processing the name and see if that finds the next element.
    if hasattr(context, '__getitem__'):
        # This fix only makes sense if current node is traversable
        try:
            name = make_name({}, urllib.unquote(next))
            if name in context:
                traversed.append(name)
                return _fix_link_traverser(context[name], traversed, subpath)
        except ValueError:
            # make_name will throw ValueError if there are no alphanumerics
            # in next
            pass

    # Some links in Karl2 are to /profile/<user> rather than
    # /profiles/<user>.  Try changing profile to profiles and
    # see if that fixes the problem.
    if next == 'profile':
        subpath.insert(0, 'profiles')
        return _fix_link_traverser(context, traversed, subpath)

    # Links to /osipeople_*.html can be rewritten as just /people
    if next.startswith('osipeople_') and next.endswith('.html'):
        subpath.insert(0, 'people')
        return _fix_link_traverser(context, traversed, subpath)

    # There are some links to just /network-news and /network-events.
    # These are located in /offices/files
    if next in ('network-news', 'network-events'):
        subpath.insert(0, next)
        subpath.insert(0, 'files')
        subpath.insert(0, 'offices')
        return _fix_link_traverser(context, traversed, subpath)

    # Out of tricks, give up
    log.debug("Couldn't fix")
    log.debug("Traversed: %s", traversed)
    log.debug("Not found: %s", next)

    return None
Пример #22
0
def drawer_upload_view(context, request,
                       check_upload_size=check_upload_size,
                       get_image_info=get_image_info,
                       batch_images=batch_images,
                       ):
    """Drawer posts a file with the parameter name "file".
    """

    ## XXX The rest is copied from add_file_view. A common denominator
    ## would be desirable.

    creator = authenticated_userid(request)

    fieldstorage = request.params.get('file')
    if not hasattr(fieldstorage, 'filename'):
        msg = 'You must select a file before clicking Upload.'
        return dict(error = msg)

    stream = fieldstorage.file
    title = fieldstorage.filename
    image = create_content(ICommunityFile,
                          title=title,
                          stream=stream,
                          mimetype=get_upload_mimetype(fieldstorage),
                          filename=fieldstorage.filename,
                          creator=creator,
                          )
    check_upload_size(context, image, 'file')

    if hasattr(context, 'get_attachments'):
        target_folder = context.get_attachments()
        if not has_permission('create', target_folder, request):
            msg = 'You do not have permission to upload files here.'
            return dict(error=msg)

        # For file objects, OSI's policy is to store the upload file's
        # filename as the objectid, instead of basing __name__ on the
        # title field).
        filename = basename_of_filepath(fieldstorage.filename)
        image.filename = filename
        name = make_name(target_folder, filename, raise_error=False)
        if not name:
            msg = 'The filename must not be empty'
            return dict(error=msg)

        # Is there a key in context with that filename?
        if name in target_folder:
            msg = 'Filename %s already exists in this folder' % filename
            return dict(error=msg)

        target_folder[name] = image

    else:
        tempfolder = find_tempfolder(context)
        tempfolder.add_document(image)

    workflow = get_workflow(ICommunityFile, 'security', context)
    if workflow is not None:
        workflow.initialize(image)

    # Update the thumbnails
    return dict(
        upload_image_info=get_image_info(image, request),
        images_info=batch_images(context, request),
    )
Пример #23
0
def drawer_upload_view(context, request,
                       check_upload_size=check_upload_size,
                       get_image_info=get_image_info,
                       batch_images=batch_images,
                       ):
    """Drawer posts a file with the parameter name "file".
    """

    ## XXX The rest is copied from add_file_view. A common denominator
    ## would be desirable.

    creator = authenticated_userid(request)

    fieldstorage = request.params.get('file')
    if not hasattr(fieldstorage, 'filename'):
        msg = 'You must select a file before clicking Upload.'
        return dict(error = msg)

    # For file objects, OSI's policy is to store the upload file's
    # filename as the objectid, instead of basing __name__ on the
    # title field).
    filename = basename_of_filepath(fieldstorage.filename)

    stream = fieldstorage.file
    # use parameter, as the title (or basename, if missing).
    title = request.params.get('title', filename)
    image = create_content(ICommunityFile,
                          title=title,
                          stream=stream,
                          mimetype=get_upload_mimetype(fieldstorage),
                          filename=fieldstorage.filename,
                          creator=creator,
                          )
    # Check if it's an image.
    if not IImage.providedBy(image):
        msg = 'File %s is not an image' % filename
        return dict(error=msg)

    check_upload_size(context, image, 'file')

    if hasattr(context, 'get_attachments'):
        target_folder = context.get_attachments()
        if not has_permission('create', target_folder, request):
            msg = 'You do not have permission to upload files here.'
            return dict(error=msg)

        image.filename = filename
        name = make_name(target_folder, filename, raise_error=False)
        if not name:
            msg = 'The filename must not be empty'
            return dict(error=msg)

        # Is there a key in context with that filename?
        if name in target_folder:
            msg = 'Filename %s already exists in this folder' % filename
            return dict(error=msg)

        target_folder[name] = image

        workflow = get_workflow(ICommunityFile, 'security', context)
        if workflow is not None:
            workflow.initialize(image)

    # In cases where the image is to live in a piece of content which has not
    # yet been created (like when using an 'Add' form), the context is going
    # to be the eventual parent of the not yet created content, which will be
    # the eventual parent of the just now created image.  Since we have nowhere
    # to put the image, we put it in a tempfolder and later move it over after
    # the content is created.  Normal ContentAdded event handlers are not
    # called at this stage and workflow is not yet initialized.  These will
    # occur when the content is moved over.
    else:
        image.modified = datetime.datetime.now()
        tempfolder = find_tempfolder(context)
        tempfolder.add_document(image)


    # Return info about the image uploaded
    return dict(
        upload_image_info=get_image_info(image, request, thumb_size=LARGE_THUMB_SIZE),
    )
Пример #24
0
def drawer_upload_view(context, request,
                       check_upload_size=check_upload_size,
                       get_image_info=get_image_info,
                       batch_images=batch_images,
                       ):
    """Drawer posts a file with the parameter name "file".
    """

    ## XXX The rest is copied from add_file_view. A common denominator
    ## would be desirable.

    creator = authenticated_userid(request)

    fieldstorage = request.params.get('file')
    if not hasattr(fieldstorage, 'filename'):
        msg = 'You must select a file before clicking Upload.'
        return dict(error = msg)

    # For file objects, OSI's policy is to store the upload file's
    # filename as the objectid, instead of basing __name__ on the
    # title field).
    filename = basename_of_filepath(fieldstorage.filename)

    stream = fieldstorage.file
    # use parameter, as the title (or basename, if missing).
    title = request.params.get('title', filename)
    image = create_content(ICommunityFile,
                          title=title,
                          stream=stream,
                          mimetype=get_upload_mimetype(fieldstorage),
                          filename=fieldstorage.filename,
                          creator=creator,
                          )
    # Check if it's an image.
    if not IImage.providedBy(image):
        msg = 'File %s is not an image' % filename
        return dict(error=msg)

    check_upload_size(context, image, 'file')

    if hasattr(context, 'get_attachments'):
        target_folder = context.get_attachments()
        if not has_permission('create', target_folder, request):
            msg = 'You do not have permission to upload files here.'
            return dict(error=msg)

        image.filename = filename
        name = make_name(target_folder, filename, raise_error=False)
        if not name:
            msg = 'The filename must not be empty'
            return dict(error=msg)

        # Is there a key in context with that filename?
        if name in target_folder:
            msg = 'Filename %s already exists in this folder' % filename
            return dict(error=msg)

        target_folder[name] = image

        workflow = get_workflow(ICommunityFile, 'security', context)
        if workflow is not None:
            workflow.initialize(image)

    # In cases where the image is to live in a piece of content which has not
    # yet been created (like when using an 'Add' form), the context is going
    # to be the eventual parent of the not yet created content, which will be
    # the eventual parent of the just now created image.  Since we have nowhere
    # to put the image, we put it in a tempfolder and later move it over after
    # the content is created.  Normal ContentAdded event handlers are not
    # called at this stage and workflow is not yet initialized.  These will
    # occur when the content is moved over.
    else:
        image.modified = datetime.datetime.now()
        tempfolder = find_tempfolder(context)
        tempfolder.add_document(image)


    # Return info about the image uploaded
    return dict(
        upload_image_info=get_image_info(image, request, thumb_size=LARGE_THUMB_SIZE),
    )