Example #1
0
class EditForm(base.EditForm):

    schema = ILatest
    label = _(u'Edit latest news portlet')
    description = _(
        u'This portlet displays the latest news that must be read.'
    )
Example #2
0
    def __call__(self, milestone=None):
        context = aq_inner(self.context)
        self.can_edit = api.user.has_permission('Modify portal content',
                                                obj=context)
        modified, errors = dexterity_update(context)
        self.workspace = parent_workspace(context)

        if self.workspace.is_case:
            if self.can_edit and milestone is not None \
               and milestone != context.milestone:
                context.milestone = milestone
                modified = True

        if modified:
            api.portal.show_message(
                _("Your changes have been saved."),
                request=self.request,
                type="success",
            )
            context.reindexObject()
            notify(ObjectModifiedEvent(context))

        if errors:
            api.portal.show_message(_("There was an error."),
                                    request=self.request,
                                    type="error")

        return super(TodoView, self).__call__()
Example #3
0
 def workspace_types(self):
     options = [{'value': '', 'content': _(u'All workspace types')}]
     translate = self.context.translate
     try:
         additional_filters = api.portal.get_registry_record(
             'ploneintranet.workspace.workspace_type_filters')
         # Sort them by the translated values
         for portal_type in sorted(
                 additional_filters,
                 key=lambda x: translate(_(additional_filters.get(x))),
         ):
             label = additional_filters[portal_type]
             options.append({'value': portal_type, 'content': _(label)})
     except api.exc.InvalidParameterError:
         # fallback if registry entry is not there
         options.extend([
             {
                 'value': 'ploneintranet.workspace.workspacefolder',
                 'content': _(u'Generic workspaces')
             },
             {
                 'value': 'ploneintranet.workspace.case',
                 'content': _(u'Cases')
             },
         ])
     return options
Example #4
0
    def likers(self):
        ''' The id of the people that like this content

        If it includes the current user, return Myself as the first element
        '''
        likers = []
        userid = api.user.get_current().id
        include_myself = False
        for likerid in self.likerids:
            if likerid == userid:
                include_myself = True
            else:
                liker = piapi.userprofile.get(likerid)
                if liker:
                    likers.append(liker.fullname)
                else:
                    likers.append(likerid)
        likers.sort()
        if include_myself:
            likers.insert(0, self.context.translate(_(u'Myself')))
        if not likers:
            return
        return _('liked_by',
                 default=u'Liked by: ${likers}',
                 mapping={'likers': u', '.join(likers)})
Example #5
0
class AddForm(add.DefaultAddForm, DexterityFormMixin):
    """ Custom add form for the Document content type.

        It's not necessary to override all the methods below, but we leave them
        there for now as reference.
    """
    template = ViewPageTemplateFile('templates/edit_document.pt')

    def render(self):
        """ The "contents" attribute of the AddView gets populated with the
            return results of this method.
        """
        return super(AddForm, self).render()

    def update(self):
        return super(AddForm, self).update()

    def extractData(self, setErrors=True):
        exclude_from_nav_id = ('form.widgets.IExcludeFromNavigation.exclude_'
                               'from_nav')
        if exclude_from_nav_id not in self.request:
            # XXX: This is a required field, but not in the form. Not yet sure
            # what the right approach to deal with it is.
            # Either we deal with it here, or add a hidden field in the
            # template.
            self.request.form[exclude_from_nav_id] = 'selected'
        return super(AddForm, self).extractData()

    @button.buttonAndHandler(_('Save'), name='save')
    def handleAdd(self, action):
        return super(EditForm, self).handleAdd(self, action)

    @button.buttonAndHandler(_(u'Cancel'), name='cancel')
    def handleCancel(self, action):
        return super(AddForm, self).handleCancel(self, action)
Example #6
0
    def __call__(self):
        """ write attributes, if any, set state, render
        """
        form = self.request.form
        ws = self.workspace()
        if self.request.method == 'POST' and form:
            if self.can_manage_workspace():
                modified, errors = dexterity_update(self.context)

                if modified and not errors:
                    api.portal.show_message(_("Attributes changed."),
                                            request=self.request,
                                            type="success")
                    ws.reindexObject()
                    notify(ObjectModifiedEvent(self.context))

                if errors:
                    api.portal.show_message(
                        _("There was a problem updating the content: %s." %
                          errors),
                        request=self.request,
                        type="error",
                    )

        return self.render()
Example #7
0
class View(BrowserView):

    _tabs = [
        {
            'view': 'search',
            'title': _('All'),
        },
        {
            'view': 'search_people',
            'title': _('People'),
        },
        {
            'view': 'search_images',
            'title': _('Images'),
        },
        {
            'view': 'search_files',
            'title': _('Files'),
        },
    ]

    def get_tabs(self):
        ''' Return the list of tabs
        '''
        params = {'SearchableText': self.request.get('SearchableText', '')}
        url_template = ''.join((self.context.absolute_url(), '/@@{view}'
                                '?', urlencode(params), '#results'))
        current_view = self.request.steps[-1].lstrip('@@')
        for tab in self._tabs:
            tab = tab.copy()
            tab['url'] = url_template.format(**tab)
            if tab['view'] == current_view:
                tab['extra_class'] = 'current'
            yield tab
Example #8
0
    def __call__(self):
        """ """
        if not self.validate_id(self.item_id):
            return 'No valid item-id: %s' % self.item_id

        self.current_user_id = api.user.get_current().getId()
        if not self.current_user_id:
            return 'No user-id'

        self.is_liked = self.util.is_liked(
            self.like_type,
            user_id=self.current_user_id,
            item_id=self.item_id,
        )

        # toogle like only if the button is clicked
        if 'like_button' in self.request:
            self.handle_toggle()

        if self.is_liked:
            self.verb = self.context.translate(_(u'Unlike'))
        else:
            self.verb = self.context.translate(_(u'Like'))
        self.unique_id = uuid.uuid4().hex
        return self.index()
Example #9
0
    def __call__(self):
        self.util = getUtility(INetworkTool)
        self.followed_id = self.context.username
        self.follow_type = 'user'
        self.follower = plone_api.user.get_current().getUserName()

        self.is_followed = self.util.is_followed(
            self.follow_type, self.followed_id, self.follower)

        if 'do_toggle_follow' in self.request:
            self.toggle_follow()

        if self.is_followed:
            self.verb = _(u'Unfollow')
        else:
            self.verb = _(u'Follow')

        self.unique_id = uuid.uuid4().hex

        fullname = self.context.fullname
        self.msg_title_follow = self.context.translate(_(
            u'title_follow',
            default=u'Click to follow ${fullname}',
            mapping={'fullname': fullname},
        ))
        self.msg_title_unfollow = self.context.translate(_(
            u'title_unfollow',
            default=u'You are now following ${fullname}. Click to unfollow.',
            mapping={'fullname': fullname},
        ))
        return self.index()
Example #10
0
class MessageForm(extensible.ExtensibleForm, form.Form):

    ignoreContext = True  # don't use context to get widget data
    id = None
    label = _('Add a comment')
    fields = field.Fields(IMessage).select('recipient', 'text')
    template = ViewPageTemplateFile('send-message.pt')

    def updateActions(self):
        super(MessageForm, self).updateActions()
        self.actions['send'].addClass('standalone')

    @button.buttonAndHandler(_(u'label_sendmessage', default=u'Send Message'),
                             name='send')
    def handleMessage(self, action):

        # Validation form
        data, errors = self.extractData()
        if errors:
            return

        sender = api.user.get_current()
        recipient = api.user.get(username=data['recipient'])
        assert sender and recipient, 'nope'

        locator = getUtility(IMessagingLocator)
        inboxes = locator.get_inboxes()

        inboxes.send_message(sender.id, recipient.id, data['text'])

        # Redirect to portal home
        self.request.response.redirect(self.action)
Example #11
0
 def placeholder(self):
     if self.thread_id or 'thread_id' in self.request.form:
         placeholder = _(u"leave_a_comment", default=u"Leave a comment...")
     else:
         placeholder = _(u"add_statusupdate_button",
                         default=u"What are you doing?")
     return self.microblog_context.translate(placeholder)
Example #12
0
    def __call__(self):
        self.util = getUtility(INetworkTool)
        self.followed_id = self.context.username
        self.follow_type = 'user'
        self.follower = plone_api.user.get_current().getId()

        self.is_followed = self.util.is_followed(self.follow_type,
                                                 self.followed_id,
                                                 self.follower)

        if 'do_toggle_follow' in self.request:
            self.toggle_follow()

        if self.is_followed:
            self.verb = _(u'Unfollow')
        else:
            self.verb = _(u'Follow')

        self.unique_id = uuid.uuid4().hex

        fullname = self.context.fullname
        self.msg_title_follow = self.context.translate(
            _(
                u'title_follow',
                default=u'Click to follow ${fullname}',
                mapping={'fullname': fullname},
            ))
        self.msg_title_unfollow = self.context.translate(
            _(
                u'title_unfollow',
                default=
                u'You are now following ${fullname}. Click to unfollow.',
                mapping={'fullname': fullname},
            ))
        return self.index()
Example #13
0
    def maybe_update_tiles(self):
        ''' Update the custom tiles if needed
        '''
        if not self.has_custom_dashboard():
            self.show_message(_('Function not allowed'), type='error')
            return

        if self.request.form.get('restore', False):
            self.reset_custom_tiles()
            return self.show_message(_('Default dashboard restored'))

        requested_tiles = self.request.form.get('tiles_order') or []
        available = self.available_custom_tiles()
        tiles = OrderedDict()
        for tile in requested_tiles:
            tile_decoded = tile.decode('utf8')
            if tile_decoded in available:
                tiles[tile_decoded] = {
                    'display': self.request.get('display-%s' % tile, 'span-1'),
                }

        if tiles != self.custom_tiles():
            self.user.custom_tiles = tiles
            return self.show_message(_('Dashboard order changed'))

        return self.show_message(
            _('Dashboard order unchanged'),
            type='warning'
        )
Example #14
0
    def __call__(self, milestone=None):
        context = aq_inner(self.context)
        self.can_edit = api.user.has_permission(
            'Modify portal content', obj=context)
        modified, errors = dexterity_update(context)
        self.workspace = parent_workspace(context)

        if self.workspace.is_case:
            if self.can_edit and milestone is not None \
               and milestone != context.milestone:
                context.milestone = milestone
                modified = True

        if modified:
            api.portal.show_message(
                _("Your changes have been saved."),
                request=self.request,
                type="success",
            )
            context.reindexObject()
            notify(ObjectModifiedEvent(context))

        if errors:
            api.portal.show_message(
                _("There was an error."), request=self.request, type="error")

        return super(TodoView, self).__call__()
Example #15
0
    def _basic_save(self):
        ''' Performs a simple save of entered attributes.
            Not all sidebars need this
        '''
        form = self.request.form
        ws = self.workspace()
        if self.request.method == 'POST' and form:
            if self.can_manage_workspace():
                modified, errors = dexterity_update(self.context)

                if modified and not errors:
                    api.portal.show_message(_("Attributes changed."),
                                            request=self.request,
                                            type="success")
                    ws.reindexObject()
                    notify(ObjectModifiedEvent(self.context))
                    if form.get('hero_image', None):
                        self.request.response.redirect(
                            self.context.absolute_url())

                if errors:
                    api.portal.show_message(
                        _("There was a problem updating the content: %s." %
                          errors),
                        request=self.request,
                        type="error",
                    )
Example #16
0
    def actions(self):
        actions = []
        if self.context.can_delete:
            if self.context.thread_id:
                title = _('Delete comment')
            else:
                title = _('Delete post')
            actions.append({
                'icon': 'trash',
                'title': title,
                'data_pat_modal': 'class: small',
                'url': self.traverse + '/panel-delete-post.html',
            })
        if self.context.can_edit:
            if self.context.thread_id:
                title = _('Edit comment')
            else:
                title = _('Edit post')
            actions.append({
                'icon': 'edit',
                'title': title,
                'url': self.traverse + '/panel-edit-post.html',
                'data_pat_modal': 'panel-header-content: none',
            })

        # edit_tags not implemented yet
        # edit_mentions not implemented yet
        return actions
Example #17
0
def invitation_accepted(event):
    """
    When an invitation is accepted, add the user to the team
    """
    request = getRequest()
    storage = get_storage()
    if event.token_id not in storage:
        return

    ws_uid, username = storage[event.token_id]
    storage[event.token_id]
    acl_users = api.portal.get_tool('acl_users')
    acl_users.updateCredentials(request, request.response, username, None)
    catalog = api.portal.get_tool(name="portal_catalog")
    brain = catalog.unrestrictedSearchResults(UID=ws_uid)[0]
    with api.env.adopt_roles(["Manager"]):
        ws = IWorkspace(brain.getObject())
        for name in ws.members:
            member = api.user.get(username=name)
            if member is not None:
                if member.getUserName() == username:
                    api.portal.show_message(
                        _('Oh boy, oh boy, you are already a member'),
                        request,
                    )
                    break
        else:
            ws.add_to_team(user=username)
            api.portal.show_message(
                _('Welcome to our family, Stranger'),
                request,
            )
Example #18
0
    def delete(self):
        handled = []
        uids = self.request.form.get('uids', [])
        for uid in uids:
            obj = api.content.get(UID=uid)
            if obj:
                handled.append(u'"%s"' % safe_unicode(obj.Title()))
                api.content.delete(obj)

        if handled:
            titles = ', '.join(sorted(handled))
            msg = _(
                u"batch_delete_success",
                default=
                u"The following items have been deleted: ${title_elems}",  # noqa
                mapping={"title_elems": titles})
            api.portal.show_message(
                message=msg,
                request=self.request,
                type="success",
            )
        else:
            api.portal.show_message(
                message=_(u"No items could be deleted"),
                request=self.request,
                type="info",
            )
        return self.redirect()
    def __call__(self):
        """ write attributes, if any, set state, render
        """
        form = self.request.form
        ws = self.workspace()
        if self.request.method == 'POST' and form:
            if self.can_manage_workspace():
                modified, errors = dexterity_update(self.context)

                if modified and not errors:
                    api.portal.show_message(
                        _("Attributes changed."),
                        request=self.request,
                        type="success")
                    ws.reindexObject()
                    notify(ObjectModifiedEvent(self.context))

                if errors:
                    api.portal.show_message(
                        _("There was a problem updating the content: %s."
                            % errors),
                        request=self.request,
                        type="error",
                    )

        return self.render()
Example #20
0
    def __call__(self):
        """ """
        if not self.validate_id(self.item_id):
            return 'No valid item-id: %s' % self.item_id

        self.current_user_id = api.user.get_current().getId()
        if not self.current_user_id:
            return 'No user-id'

        self.is_liked = self.util.is_liked(
            self.like_type,
            user_id=self.current_user_id,
            item_id=self.item_id,
        )

        # toogle like only if the button is clicked
        if 'like_button' in self.request:
            self.handle_toggle()

        if self.is_liked:
            self.verb = self.context.translate(_(u'Unlike'))
        else:
            self.verb = self.context.translate(_(u'Like'))
        self.unique_id = uuid.uuid4().hex
        return self.index()
Example #21
0
    def create(self, container=None):
        """
        Create content in the given container and return url.
        Uses dexterity_update to set the
        appropriate fields after creation.
        """
        if not self.validate():
            # BBB: do something clever that works with pat-inject
            # at the moment the @@add_something form is not a complete page
            # but just some markup,
            # so we cannot show that one here
            pass
        new = self.get_new_object(container)
        modified, errors = self.update(new)

        if not errors:
            api.portal.show_message(
                _("Item created."),
                request=self.request,
                type="success"
            )
            new.reindexObject()
            notify(ObjectCreatedEvent(new))
        else:
            api.portal.show_message(
                _("There was a problem: %s." % errors),
                request=self.request,
                type="error",
            )

        return new.absolute_url()
Example #22
0
    def rename(self):
        handled = []
        uids = self.request.form.get('uids', [])
        for uid in uids:
            obj = api.content.get(UID=uid)
            new_title = self.request.form.get(uid)
            if obj and new_title:
                handled.append(
                    u'"%s" → "%s"' %
                    (safe_unicode(obj.Title()), safe_unicode(new_title)))
                obj.title = new_title
                obj.reindexObject()

        if handled:
            titles = ', '.join(sorted(handled))
            msg = _(
                u"batch_rename_success",
                default=
                u"The following items have been renamed: ${title_elems}",  # noqa
                mapping={"title_elems": titles})
            api.portal.show_message(
                message=msg,
                request=self.request,
                type="success",
            )
        else:
            api.portal.show_message(
                message=_(u"No items could be renamed"),
                request=self.request,
                type="info",
            )
        return self.redirect()
Example #23
0
    def __call__(self):
        """Cut all items currently in cart and add them to clipboard.

        The tricky part here is that the method that Plone uses
        (manage_cutObjects) was only ment to work on objects of the same
        parent. However, our use case allows cutting objects of different
        parents. Hence we need to go one level deeper and reimplement some
        stuff that manage_cutObjects does in our own way.

        """

        request = self.request
        obj_list = []
        cannot_cut = []
        for obj in self.items:
            if obj:
                is_allowed = api.user.has_permission('Delete objects', obj=obj)
                is_locked = obj.wl_isLocked()
                is_movable = obj.cb_isMoveable()
                can_cut = is_allowed and is_movable and not is_locked
                if can_cut:
                    m = Moniker(obj)
                    obj_list.append(m.dump())
                else:
                    cannot_cut.append(u'"%s"' % safe_unicode(obj.Title()))

        if obj_list:
            # now store cutdata into a cookie
            # TODO: what if there's nothing in the list?
            ct_data = (1, obj_list)
            ct_data = _cb_encode(ct_data)  # probably means "clipboard encode"?

            response = request.response
            path = '{0}'.format(cookie_path(request))
            response.setCookie('__cp', ct_data, path=path)
            request['__cp'] = ct_data

            msg = _(
                u"batch_cut_success",
                default=
                u"${num_elems} Files were cut and moved to your cloud clipboard.",  # noqa
                mapping={"num_elems": len(obj_list)})
            api.portal.show_message(
                message=msg,
                request=request,
                type="info",
            )

        if cannot_cut:
            msg = _(
                u"batch_cut_failure",
                default=u"The following items could not be cut: ${num_elems}",
                mapping={"num_elems": ', '.join(sorted(cannot_cut))})
            api.portal.show_message(
                message=msg,
                request=request,
                type="info",
            )
        return self.index()
Example #24
0
class SidebarSettingsSecurity(BaseTile):
    """
    A view to serve as the security settings in the sidebar
    """

    index = ViewPageTemplateFile('templates/sidebar-settings-security.pt')

    join_policy_label = _(u'join_policy_label', default=u'Join policy')
    external_visibility_label = _(u'external_visibility_label',
                                  default=u'External visibility')
    participant_policy_label = _(u'participant_policy_label',
                                 default=u'Participant policy')

    def __init__(self, context, request):
        """
        Set up local copies of the policies for the sidebar template
        """
        super(SidebarSettingsSecurity, self).__init__(context, request)
        self.external_visibility = EXTERNAL_VISIBILITY
        self.join_policy = JOIN_POLICY
        self.participant_policy = PARTICIPANT_POLICY

    def __call__(self):
        """
        Write attributes, if any, set state, render
        """
        form = self.request.form
        ws = self.workspace()

        def update_field(field_name):
            index = int(form.get(field_name)) - 1
            field = getattr(self, field_name)
            value = field.keys()[index]

            if value != getattr(ws, field_name):
                if field_name == 'external_visibility':
                    ws.set_external_visibility(value)
                else:
                    setattr(ws, field_name, value)
                api.portal.show_message(
                    _(u'Workspace security policy changes saved'),
                    self.request,
                    'success',
                )

        if self.request.method == 'POST':
            self.form_submitted = True
            if not self.can_manage_workspace():
                msg = _(u'You do not have permission to change the workspace '
                        u'policy')
                raise Unauthorized(msg)
            if form:
                for field in [
                        'external_visibility', 'join_policy',
                        'participant_policy'
                ]:
                    update_field(field)

        return self.render()
Example #25
0
 def title(self):
     m_context = piapi.microblog.get_microblog_context(self.context)
     if m_context:
         return m_context.Title() + ' updates'
     elif self.explore:
         return _(u'Explore')
     else:
         return _(u'My network')
Example #26
0
 def title(self):
     m_context = PLONEINTRANET.context(self.context)
     if m_context:
         return m_context.Title() + ' updates'
     elif self.explore:
         return _(u'Explore')
     else:
         return _(u'My network')
Example #27
0
 def title(self):
     m_context = piapi.microblog.get_microblog_context(self.context)
     if m_context:
         return m_context.Title() + ' updates'
     elif self.explore:
         return _(u'Explore')
     else:
         return _(u'My network')
Example #28
0
 def get_review_state_hr(self, wf, review_state):
     ''' Given a workflow and a review state, return a human readable title
     '''
     if not wf:
         return _(review_state)
     state = wf.states.get(review_state)
     if state:
         return _(state.title)
     return _(review_state)
Example #29
0
class AddForm(base.AddForm):

    schema = ILatest
    label = _(u'Add latest news portlet')
    description = _(
        u'This portlet displays the latest news that must be read.'
    )

    def create(self, data):
        return Assignment(count=data.get('count', 5))
Example #30
0
 def roles(self):
     ws_policy = self.context.participant_policy
     title = _(u"workspace_default_role",
               default=u'Default role for this workspace (${role})',
               mapping={u'role': PARTICIPANT_POLICY[ws_policy]['title']})
     yield {'id': ws_policy.title(), 'title': title}
     for policy_id, policy_info in PARTICIPANT_POLICY.items():
         if policy_id == ws_policy:
             continue
         yield {'id': policy_id.title(), 'title': policy_info['title']}
     yield {'id': 'Admins', 'title': _(u'Workspace Administrator')}
Example #31
0
 def title(self):
     ''' The tile title. If we have an homonymous request parameter, use it
     Otherwise return a default based on the workspace type
     '''
     title = self.request.form.get('title', '')
     if title:
         return _(title)
     workspace_type = self.workspace_type
     if isinstance(workspace_type, basestring):
         return _('tile_' + workspace_type)
     return _('tile_workspaces_default_tile', u'Workspaces')
Example #32
0
    def process(self, csvfile, update=False):
        """Process the input file, validate and
        create the users.
        """
        data = tablib.Dataset()
        try:
            data.csv = csvfile
        except tablib.core.InvalidDimensions:
            return self._show_message_redirect(
                _("File incorrectly formatted.")
            )

        try:
            self.validate(data)
        except custom_exc.MissingCoreFields as e:
            return self._show_message_redirect(_(e.message))
        except custom_exc.ExtraneousFields as e:
            return self._show_message_redirect(_(e.message))
        except tablib.core.HeadersNeeded as e:
            return self._show_message_redirect(_(e.message))

        message_type = 'error'
        try:
            count = self.create_update_users(data, update)
        except custom_exc.DuplicateUser as e:
            message = _(
                u"{} on row {}".format(
                    e.message, e.details['row'])
            )
        except custom_exc.RequiredMissing as e:
            message = _(
                u"Missing required field {} on row {}".format(
                    e.message, e.details['row'])
            )
        except custom_exc.ConstraintNotSatisfied as e:
            message = _(
                u"Constraint not satisfied for {} at row {}.".format(
                    e.details['field'], e.details['row'])
            )
        except custom_exc.WrongType as e:
            message = _(
                u"Wrong type for {} at row {}.".format(
                    e.details['field'], e.details['row'])
            )
        else:
            message_type = 'info'
            verb = update and "Updated" or "Created"
            message = _(u"{} user(s) {}.".format(count, verb))

        if message_type == 'error':
            transaction.abort()

        api.portal.show_message(
            message=message,
            request=self.request,
            type=message_type,
        )
        return self._redirect()
Example #33
0
 def placeholder(self):
     if 'thread_id' in self.request.form:
         placeholder = _(
             u"leave_a_comment",
             default=u"Leave a comment..."
         )
     else:
         placeholder = _(
             u"add_statusupdate_button",
             default=u"What are you doing?"
         )
     return self.context.translate(placeholder)
Example #34
0
class ISearchResponse(Interface):
    """Defines a common API for search query responses."""

    spell_corrected_search = schema.TextLine(
        title=_(u'Spell corrected search string'))

    facets = schema.Dict(
        title=_(u'A dictionary of facets and available values'))

    total_results = schema.Int(
        title=_(u'The total number of results generated from the query'))

    def __iter__():
        """Search responses should implement the `Iterable` protocol.
Example #35
0
class PIDeleteConfirmationForm(DeleteConfirmationForm):
    ''' We need to override this
    because of some problems with the original delete_confirmation form
    See: https://github.com/plone/plone.app.content/issues/38

    Caveat: we need to reimplement all the actions while overriding,
    because of the button.buttonAndHandler implementation
    '''
    template = ViewPageTemplateFile('templates/delete_confirmation.pt')

    def view_url(self):
        ''' Facade to the homonymous plone_context_state method
        '''
        context_state = getMultiAdapter(
            (self.context, self.request),
            name='plone_context_state'
        )
        return context_state.view_url()

    def updateActions(self):
        ''' This method updates the actions to enable some dynamic behaviours

        In particular it understands the request parametes:
         - pat-modal
         - pat-inject

        If pat-modal is truish we add to the action buttons the class
        'close-panel'
        If pat-inject is truish the pat-inject class is added to the form
        and a data attribute data-pat-inject is filled we the value
        read from the request
        '''
        super(PIDeleteConfirmationForm, self).updateActions()

        if self.request.get('pat-modal'):
            self.actions['Delete'].klass = 'close-panel icon-ok-circle'
            self.actions['Cancel'].klass = 'close-panel icon-cancel-circle'
        else:
            self.actions['Delete'].klass = 'icon-ok-circle'
            self.actions['Cancel'].klass = 'icon-cancel-circle'

    @button.buttonAndHandler(_(u'I am sure, delete now'), name='Delete')
    def handle_delete(self, action):
        base_handler = super(PIDeleteConfirmationForm, self).handle_delete
        return base_handler(self, action)

    @button.buttonAndHandler(
        _(u'label_cancel', default=u'Cancel'), name='Cancel')
    def handle_cancel(self, action):
        return self.request.response.redirect(self.view_url())
Example #36
0
class IWorkspaceFolder(IBaseWorkspaceFolder):
    ''' A workspace folder can be a division,
    while other objects inheriting from IBaseWorkspaceFolder cannot,
    e.g. cases
    '''
    is_division = schema.Bool(
        title=_(u"label_workspace_is_division",
                u"Is this workspace representing a division?"),
        description=_(u"Divisions represent sections of the overall "
                      u"organisation and appear "
                      u"as groupings on the workspace overview."),
        required=False,
        default=False,
    )
Example #37
0
class ITransferMembershipForm(form.Schema):
    """
    the form to handle transferring membership
    """

    workspace = schema.Choice(
        title=_(u"Select workspace"),
        source=workspaces_provider,
    )

    move = schema.Bool(
        title=_(u"Move"),
        description=_(u"If checked, users will be removed from workspace"),
        required=False,
    )
Example #38
0
class IWorkspaceFolder(form.Schema, IImageScaleTraversable):
    """
    Interface for WorkspaceFolder
    """
    calendar_visible = schema.Bool(
        title=_(u"label_workspace_calendar_visibility",
                u"Calendar visible in central calendar"),
        required=False,
        default=False,
    )
    email = schema.TextLine(
        title=_(u'label_workspace_email', u'E-mail address'),
        required=False,
        default=u'',
    )
 def execute_batch_function(self):
     form = self.request.form
     ws = self.workspace()
     user_ids = form.get('user_id')
     if isinstance(user_ids, basestring):
         user_ids = user_ids.split(',')
     batch_function = form.get('batch-function')
     if user_ids:
         if not self.can_manage_roster():
             msg = _(u'You do not have permission to change the workspace '
                     u'policy')
             raise Unauthorized(msg)
         else:
             if batch_function == 'add':
                 for user_id in user_ids:
                     IWorkspace(ws).add_to_team(user=user_id)
                 api.portal.show_message(
                     _(u'Member(s) added'),
                     self.request,
                     'success',
                 )
             elif batch_function == 'remove':
                 for user_id in user_ids:
                     IWorkspace(ws).remove_from_team(user=user_id)
                 api.portal.show_message(
                     _(u'Member(s) removed'),
                     self.request,
                     'success',
                 )
             elif batch_function == 'role':
                 role = self.request.get('role')
                 if role:
                     groups = {role}
                 else:
                     groups = None
                 for user_id in user_ids:
                     IWorkspace(ws).add_to_team(user=user_id, groups=groups)
                 api.portal.show_message(
                     _(u'Role updated'),
                     self.request,
                     'success',
                 )
             else:
                 api.portal.show_message(
                     _(u'Unknown function'),
                     self.request,
                     'error',
                 )
Example #40
0
def get_workspace_activities(brain, limit=1):
    """ Return the workspace activities sorted by reverse chronological
    order

    Regarding the time value:
     - the datetime value contains the time in international format
       (machine readable)
     - the title value contains the absolute date and time of the post
    """
    mb = queryUtility(IMicroblogTool)
    items = mb.context_values(brain.getObject(), limit=limit)
    mtool = api.portal.get_tool('portal_membership')
    results = []
    for item in items:
        user_data = mtool.getMemberInfo(item.creator)
        creator = user_data.get('fullname') if user_data else item.creator
        results.append(dict(
            subject=creator,
            verb=_(u'posted'),
            object=item.text,
            time={
                'datetime': item.date.strftime('%Y-%m-%d'),
                'title': item.date.strftime('%d %B %Y, %H:%M')}
        ))
    return results
Example #41
0
 def __call__(self):
     """Sync a single user profile with external property providers"""
     alsoProvides(self.request, IDisableCSRFProtection)
     userprofile = self.context
     IUserProfileManager(userprofile).sync()
     api.portal.show_message(message=_("External property sync complete."), request=self.request)
     return self.request.response.redirect(userprofile.absolute_url())
Example #42
0
 def roles(self):
     ws_policy = self.context.participant_policy
     title = _(
         u"workspace_default_role",
         default=u'Default role for this workspace (${role})',
         mapping={
             u'role': PARTICIPANT_POLICY[ws_policy]['title']})
     yield {'id': ws_policy.title(),
            'title': title}
     for policy_id, policy_info in PARTICIPANT_POLICY.items():
         if policy_id == ws_policy:
             continue
         yield {'id': policy_id.title(),
                'title': policy_info['title']}
     yield {'id': 'Admins',
            'title': _(u'Workspace Administrator')}
Example #43
0
def accept_invitation(event):
    """
    Event handler for :class:`AcceptToken` event fired by invitation framework

    :param event: The event object
    :type event: :class:`AcceptToken`
    :return:
    """
    request = getRequest()
    email = _get_storage().get(event.token_id)
    if email is None:
        api.portal.show_message(_('The token has expired.'), request)
        return
    acl_users = api.portal.get_tool('acl_users')
    if api.user.get(username=email) is None:
        api.user.create(
            email=email,
            username=email,
        )
    acl_users.updateCredentials(
        request,
        request.response,
        email,
        None
    )
Example #44
0
    def update(self):
        """ """
        context = aq_inner(self.context)
        modified = False
        errors = None
        messages = []
        if (
                self.request.get('workflow_action') and
                not self.request.get('form.submitted')):
            api.content.transition(
                obj=context,
                transition=self.request.get('workflow_action')
            )
            # re-calculate can_edit after the workflow state change
            self.can_edit = api.user.has_permission(
                'Modify portal content',
                obj=context
            )
            modified = True
            messages.append(
                context.translate(_("The workflow state has been changed.")))

        if self.can_edit:
            mod = False
            if self.validate():
                mod, errors = dexterity_update(context)
                if mod:
                    messages.append(
                        context.translate(_("Your changes have been saved.")))
            modified = modified or mod

        if errors:
            error_msg = context.translate(_("There was a problem:"))
            api.portal.show_message(
                u"{} {}".format(error_msg, errors),
                request=self.request,
                type="error",
            )

        elif modified:
            api.portal.show_message(
                ' '.join(messages), request=self.request,
                type="success")
            context.reindexObject()
            notify(ObjectModifiedEvent(context))
Example #45
0
 def __call__(self):
     """Because self.item_id is set via publishTraverse we need
     an extra check"""
     if not getattr(self, 'item_id', False):
         raise KeyError(
             _('No item id given in sub-path. '
               'Use .../@@toggle_like/123456')
         )
     return super(ToggleLikeStatusUpdate, self).__call__()
Example #46
0
    def validate(self, value, force=False):
        membrane_tool = plone_api.portal.get_tool('membrane_tool')
        usernames = membrane_tool._catalog.uniqueValuesFor('exact_getUserName')
        if value in usernames:
            brains = membrane_tool.searchResults(exact_getUserName=value)
            if brains and self.context != brains[0].getObject():
                raise Invalid(_("A user with this username already exists"))

        return super(UsernameValidator, self).validate(value)
Example #47
0
    def __call__(self):
        if not self.context.join_policy == "self":
            msg = _(u"Workspace join policy doesn't allow self join")
            raise Unauthorized(msg)

        field = "button.join"
        req_method = self.request.method.lower()
        if req_method == "post" and field in self.request.form:
            user = api.user.get_current()
            workspace = IWorkspace(self.context)
            workspace.add_to_team(user=user.getId())
            msg = _(u"You are a member of this workspace now")
            api.portal.show_message(message=_(msg),
                                    request=self.request)

        referer = self.request.get("HTTP_REFERER", "").strip()
        if not referer:
            referer = self.context.absolute_url()
        return self.request.response.redirect(referer)
Example #48
0
    def __call__(self):
        self.util = getUtility(INetworkTool)
        self.followed_id = self.context.username
        self.follow_type = 'user'
        self.follower = plone_api.user.get_current().getUserName()

        self.is_followed = self.util.is_followed(
            self.follow_type, self.followed_id, self.follower)

        if 'do_toggle_follow' in self.request:
            self.toggle_follow()

        if self.is_followed:
            self.verb = _(u'Unfollow')
        else:
            self.verb = _(u'Follow')

        self.unique_id = uuid.uuid4().hex

        return self.index()
Example #49
0
def user_has_email(username):
    """ make sure, that given user has an email associated """
    user = api.user.get(username=username)
    if not user.getProperty("email"):
        msg = _(
            "This user doesn't have an email associated "
            "with their account."
        )
        raise Invalid(msg)

    return True
Example #50
0
    def edit(self):
        """
        Edit content and return url. Uses dexterity_update to set the
        appropriate fields after creation.
        """
        modified, errors = dexterity_update(self.context, self.request)
        if modified and not errors:
            api.portal.show_message(
                _("Item edited."), request=self.request, type="success")
            self.context.reindexObject()
            notify(ObjectModifiedEvent(self.context))

        if errors:
            api.portal.show_message(
                _("There was a problem: %s." % errors),
                request=self.request,
                type="error",
            )

        return self.context.absolute_url()
    def __call__(self):
        """
        Write attributes, if any, set state, render
        """
        form = self.request.form
        if self.request.method == 'POST' and form:
            ws = self.workspace()
            self.set_grouping_cookie()
            # wft = api.portal.get_tool("portal_workflow")
            section = self.request.form.get('section', None)
            do_reindex = False

            # Do the workflow transitions based on what tasks the user checked
            # or unchecked
            if section == 'task':
                update_task_status(self)

            # Do the property editing. Edits only if there is something to edit
            # in form
            if self.can_manage_workspace() and form:
                modified, errors = dexterity_update(self.context)

                if modified and not errors:
                    api.portal.show_message(
                        _("Attributes changed."),
                        request=self.request,
                        type="success")
                    do_reindex = True
                    notify(ObjectModifiedEvent(self.context))

                if errors:
                    api.portal.show_message(
                        _("There was a problem updating the content: %s."
                            % errors),
                        request=self.request,
                        type="error",
                    )

            if do_reindex:
                ws.reindexObject()
        return self.render()
    def logical_parent(self):
        """
        Needed for the back button in the sidebar.
        Depending on the selected grouping, this returns the information
        needed to get one step back.
        """
        grouping = self.grouping()
        workspace = parent_workspace(self.context)

        if grouping == 'folder':
            if self.context != workspace:
                parent = self.request.PARENTS[1]
                return dict(title=parent.Title(), url=parent.absolute_url())
            else:
                return
        else:
            if self.request.get('groupname'):
                if grouping == 'date':
                    title = _(u'All Dates')
                elif grouping == 'label':
                    title = _(u'All Tags')
                elif grouping == 'author':
                    title = _(u'All Authors')
                elif grouping == 'type':
                    title = _(u'All Types')
                elif grouping == 'first_letter':
                    title = _(u'All Letters')
                else:
                    title = _(u'Back')
                return dict(title=title, url=workspace.absolute_url())
            else:
                return
Example #53
0
    def execute_batch_function(self):
        if not self.can_manage_roster():
            msg = _(u'You do not have permission to change the workspace '
                    u'policy')
            raise Unauthorized(msg)

        form = self.request.form
        user_ids = form.get('user_id')
        if not user_ids:
            return

        if isinstance(user_ids, basestring):
            user_ids = user_ids.split(',')

        ws = self.workspace()
        batch_function = form.get('batch-function')
        if batch_function == 'add':
            for user_id in user_ids:
                IWorkspace(ws).add_to_team(user=user_id)
            msg = _(u'Member(s) added')
            msg_type = 'success'
        elif batch_function == 'remove':
            for user_id in user_ids:
                IWorkspace(ws).remove_from_team(user=user_id)
            msg = _(u'Member(s) removed')
            msg_type = 'success'
        elif batch_function == 'role':
            role = self.request.get('role')
            groups = role and {role} or None
            for user_id in user_ids:
                IWorkspace(ws).add_to_team(user=user_id, groups=groups)
            msg = _(u'Role updated')
            msg_type = 'success'
        else:
            msg = _(u'Unknown function')
            msg_type = 'error'

        api.portal.show_message(msg, self.request, msg_type)
        notify(WorkspaceRosterChangedEvent(self.context))
Example #54
0
    def validate(self):
        ''' Override base content validation

        Return truish if valid
        '''
        if self.request.get('start') <= self.request.get('end'):
            return True

        api.portal.show_message(
            _('Start date should be lower than end date'),
            request=self.request,
            type="error"
        )
        return False
Example #55
0
def invitation_accepted(event):
    """
    When an invitation is accepted, add the user to the team
    """
    request = getRequest()
    storage = get_storage()
    if event.token_id not in storage:
        return

    ws_uid, username = storage[event.token_id]
    storage[event.token_id]
    acl_users = api.portal.get_tool('acl_users')
    acl_users.updateCredentials(
        request,
        request.response,
        username,
        None
    )
    catalog = api.portal.get_tool(name="portal_catalog")
    brain = catalog.unrestrictedSearchResults(UID=ws_uid)[0]
    with api.env.adopt_roles(["Manager"]):
        ws = IWorkspace(brain.getObject())
        for name in ws.members:
            member = api.user.get(username=name)
            if member is not None:
                if member.getUserName() == username:
                    api.portal.show_message(
                        _('Oh boy, oh boy, you are already a member'),
                        request,
                    )
                    break
        else:
            ws.add_to_team(user=username)
            api.portal.show_message(
                _('Welcome to our family, Stranger'),
                request,
            )
Example #56
0
 def update_roster(self, REQUEST=None):
     """
     If workspace is team managed, users can add/remove participants.
     Any user with the manage workspace permission can add/remove
     participants and admins.
     """
     CheckAuthenticator(self.request)
     PostOnly(self.request)
     form = self.request.form
     entries = form.get('entries', [])
     self.update_users(entries)
     api.portal.show_message(message=_(u'Roster updated.'),
                             request=self.request)
     return self.request.response.redirect(
         '%s/@@edit-roster' % self.context.absolute_url())
        def update_field(field_name):
            index = int(form.get(field_name)) - 1
            field = getattr(self, field_name)
            value = field.keys()[index]

            if value != getattr(ws, field_name):
                if field_name == 'external_visibility':
                    ws.set_external_visibility(value)
                else:
                    setattr(ws, field_name, value)
                api.portal.show_message(
                    _(u'Workspace security policy changes saved'),
                    self.request,
                    'success',
                )
Example #58
0
 def __call__(self):
     if self.token_id is None:
         raise KeyError(
             _("No token id given in sub-path."
               "Use .../@@accept-token/tokenid")
         )
     util = getUtility(ITokenUtility)
     portal = api.portal.get()
     if util.valid(self.token_id):
         notify(TokenAccepted(self.token_id))
         util._consume_token(self.token_id)
         token = util._fetch_token(self.token_id)
         if token.redirect_path is not None:
             return self.request.response.redirect('%s/%s' % (
                 portal.absolute_url(),
                 token.redirect_path
             ))
     else:
         api.portal.show_message(
             _('Token no longer valid'),
             self.request,
             type='error'
         )
     return self.request.response.redirect(portal.absolute_url())
Example #59
0
 def update(self):
     """ """
     if ('task_action' in self.request and
             not self.request.get('form.submitted')):
         task_action = self.request.get('task_action')
         if task_action == 'close':
             api.content.transition(
                 obj=self.context,
                 transition='finish'
             )
         elif task_action == 'reopen':
             self.context.reopen()
         api.portal.show_message(_(
             'Changes applied'), request=self.request,
             type="success")
     super(TodoView, self).update()
Example #60
0
    def format_event_date(self, event):
        """
        We need to show only the starting time, or in case of an all day event
        'All day' in the time tag. Not the date.

        In case of a multi day event, we can show "2015-08-30 - 2015-08-31"
        """
        # whole_day isn't a metadata field (yet)
        event_obj = event.getObject()
        if is_single_day(event) and event_obj.whole_day:
            return _(u'All day')
        elif is_single_day(event):
            return event.start.strftime('%H:%M')
        else:  # multi day event
            return '{} - {}'.format(
                event.start.strftime('%Y-%m-%d'),
                event.end.strftime('%Y-%m-%d'),
            )