Ejemplo n.º 1
0
    def __call__(self):
        response = self.request.response
        title = self.context.Title()
        ftitle = "/tmp/%s_CV.pdf" % (title)
        filename = ftitle

        attachment = 'attachment; filename=%s' % (ftitle)
        f = file(filename, "wb")
        pdf_template = ViewPageTemplateFile('pdf-view.pt')(self)

        response.setHeader('Content-Type', 'application/pdf')
        response.setHeader('Content-Disposition', attachment);
        pdf = pisa.CreatePDF(pdf_template.encode("UTF-8"), response)
        f.flush()
        f.close()

        if not pdf.err:
            return response
        else:
            # Something is wrong 
            # Fledge this out later
            pass
Ejemplo n.º 2
0
class UserAssignmentView(forms.common.BaseForm):
    """View for user assignments. Allows users with adequate permissions
    to edit the assignments
    """
    form_fields = []
    render = ViewPageTemplateFile("templates/assignment.pt")

    def __init__(self, context, request):
        self._assignable_roles = []
        self.principal = utils.common.get_request_principal()
        self.context_roles = common.get_context_roles(context, self.principal)
        self.context = removeSecurityProxy(context)
        self.prm = IPrincipalRoleMap(self.context)
        super(UserAssignmentView, self).__init__(context, request)

    def __call__(self):
        self.update()
        return self.render()

    def get_object_type_info(self):
        return capi.get_type_info(self.context.__class__)

    def get_config_roles(self, role_type):
        ti = self.get_object_type_info()
        workflow = ti.workflow
        if workflow.has_feature("user_assignment"):
            feature = None
            for f in workflow.features:
                if f.name == "user_assignment":
                    feature = f
        if feature:
            if role_type == "assigner":
                return capi.schema.qualified_roles(
                    feature.params["assigner_roles"])
            elif role_type == "assignable":
                return capi.schema.qualified_roles(
                    feature.params["assignable_roles"])
        return []

    def assignable_roles(self):
        """Returns a list of role ids that this user can assign to
        """
        if self._assignable_roles:
            return self._assignable_roles
        # the assigner roles that this user has
        assigner_roles = []
        # all the assigner roles that are in the workflow config
        config_assigner_roles = self.get_config_roles("assigner")
        for c_a_role in config_assigner_roles:
            role = getUtility(IRole, c_a_role)
            if role.id in self.context_roles:
                assigner_roles.append(role.id)
        # the assignable roles that this user can assign to
        assignable_roles = []
        # all the assignable roles that are in the workflow config
        config_assignable_roles = self.get_config_roles("assignable")
        # Only assign to roles that have the same parent or are children
        # of assigner roles that this user has
        for assigner_role in assigner_roles:
            assigner_role_annt = ISubRoleAnnotations(
                getUtility(IRole, assigner_role))
            if assigner_role_annt.is_sub_role:
                for c_assignable_role in config_assignable_roles:
                    c_assignable_role_annt = ISubRoleAnnotations(
                        getUtility(IRole, c_assignable_role))
                    if (c_assignable_role_annt.parent ==
                            assigner_role_annt.parent):
                        assignable_roles.append(c_assignable_role)
            else:
                for c_assignable_role in config_assignable_roles:
                    if (c_assignable_role in assigner_role_annt.sub_roles):
                        assignable_roles.append(c_assignable_role)
        self._assignable_roles = assignable_roles
        return self._assignable_roles

    def can_edit(self, action=None):
        return checkPermission("bungeni.user_assignment.Edit", self.context)

    @property
    def columns(self):
        return [
            column.GetterColumn(
                title=_("user name"),
                getter=lambda i, f: i.get("title")
            ),
            column.GetterColumn(
                title=_("assigned"),
                getter=lambda i, f: i,
                cell_formatter=lambda g, i, f: \
                    '<input type="checkbox" name="%s" %s %s/>' % (
                        i["name"],
                        i["is_assigned"] and ' checked="checked"' or "",
                        not i["editable"] and ' disabled="disabled"' or "")
                )
            ]

    @property
    def checkbox_prefix(self):
        return "assignment_users"

    def make_id(self, role_id, user_login_id):
        return ".".join((self.checkbox_prefix, role_id, user_login_id))

    def user_is_assigned(self, user_login, role_id):
        if self.prm.getSetting(role_id, user_login) == Allow:
            return True
        return False

    def role_listing(self, role_id, editable):
        listing = []
        users = common.get_users(role_id)
        if not users:
            return _("No users available for this role.")
        for user in users:
            data = {}
            data["title"] = IDCDescriptiveProperties(user).title
            data["name"] = self.make_id(user.login, role_id)
            data["is_assigned"] = self.user_is_assigned(user.login, role_id)
            data["editable"] = editable
            listing.append(data)
        formatter = TableFormatter(self.context,
                                   self.request,
                                   listing,
                                   prefix="assignment",
                                   columns=self.columns)
        formatter.updateBatching()
        return formatter()

    def update(self):
        self.tables = []
        assignable_roles = self.assignable_roles()
        for role_id in assignable_roles:
            if role_id in assignable_roles:
                editable = True
            else:
                editable = False
            self.tables.append({
                "title": getUtility(IRole, role_id).title,
                "table": self.role_listing(role_id, editable)
            })
        forms.common.BaseForm.update(self)

    def get_selected(self):
        selected = [
            (k[len(self.checkbox_prefix) + 1:].split(".")[0].decode("base64"),
             k[len(self.checkbox_prefix) + 1:].split(".")[1].decode("base64"))
            for k in self.request.form.keys()
            if k.startswith(self.checkbox_prefix) and self.request.form.get(k)
        ]
        return selected

    def process_assignment(self):
        for role_id in self.assignable_roles():
            for user in common.get_users(role_id):
                key = self.make_id(user.login, role_id)
                if key in self.request.form.keys():
                    self.prm.assignRoleToPrincipal(role_id, user.login)
                else:
                    self.prm.unsetRoleForPrincipal(role_id, user.login)

    @formlib.form.action(label=_("Save"), name="save", condition=can_edit)
    def handle_save(self, action, data):
        self.process_assignment()
        next_url = url.absoluteURL(self.context, self.request)
        self.request.response.redirect(next_url)

    @formlib.form.action(label=_("Cancel"), name="", condition=can_edit)
    def handle_cancel(self, action, data):
        next_url = url.absoluteURL(self.context, self.request)
        self.request.response.redirect(next_url)
Ejemplo n.º 3
0
class WorkflowActionViewlet(browser.BungeniBrowserView, BaseForm,
                            viewlet.ViewletBase):
    """Display workflow status and actions.
    """
    # stores old_url of object before transition change
    # we could use HTTP_REFERER but that would mean relying on client input
    _old_url = None

    render = ViewPageTemplateFile("templates/viewlet.pt")

    class IWorkflowForm(zope.interface.Interface):
        note = zope.schema.Text(title=_("Comment on workflow change"),
                                required=False)
        date_active = zope.schema.Datetime(title=_("Active Date"),
                                           required=True)
        registry_number = zope.schema.TextLine(title=_("Registry number"),
                                               required=False)

    form_name = "Workflow"
    form_fields = form.Fields(IWorkflowForm)
    note_widget = TextAreaWidget
    note_widget.height = 1
    form_fields["note"].custom_widget = note_widget
    form_fields["date_active"].custom_widget = TextDateTimeWidget
    actions = ()

    def get_min_date_active(self):
        """Determine the min_date_active to validate against.
        """
        def is_workflowed_and_draft(instance):
            """is item workflowed, and if so is it in a logical draft state?
            """
            if interfaces.IWorkflowed.providedBy(instance):
                wf = interfaces.IWorkflow(instance)
                return instance.status in wf.get_state_ids(tagged=["draft"],
                                                           restrict=False)
            return False

        min_date_active = None
        if IAuditable.providedBy(self.context):
            instance = removeSecurityProxy(self.context)
            # !+PASTDATAENTRY(mr, jun-2011) offers a way to enter past data
            # for workflowed items via the UI -- note, ideally we should be
            # able to also control the item's creation active_date.
            #
            # If a workflowed item is in draft state, we do NOT take the
            # date_active of its last change as the min_date_active, but
            # let that min fallback to parliament's creation date...
            if not is_workflowed_and_draft(instance):
                changes = get_changes(instance, "workflow")
                if changes:
                    # then use the "date_active" of the most recent entry
                    min_date_active = changes[-1].date_active
        if not min_date_active:
            # fallback to current parliament's start_date (cast to a datetime)
            min_date_active = datetime.datetime.combine(
                globalsettings.get_current_parliament().start_date,
                datetime.time())
        # As the precision of the UI-submitted datetime is only to the minute,
        # we adjust min_date_active by a margin of 59 secs earlier to avoid
        # issues of doing 2 transitions in quick succession (within same minute)
        # the 2nd of which could be taken to be too old...
        return min_date_active - datetime.timedelta(seconds=59)

    def validate(self, action, data):
        # submitted data is actually updated in following call to super.validate
        # !+PASTDATAENTRY(mr, jun-2011) enhancement? see Issue 612 Comment 6:
        # unrequire, allow active_date=None,
        # get_effective_active_date -> last workflow non-None active_date
        errors = super(WorkflowActionViewlet, self).validate(action, data)
        if "date_active" in data.keys():
            min_date_active = self.get_min_date_active()
            if data.get("date_active") < min_date_active:
                errors.append(
                    zope.interface.Invalid(_("Active Date is in the past.")))
            elif data.get("date_active") > datetime.datetime.now():
                errors.append(
                    zope.interface.Invalid(_("Active Date is in the future.")))
        if "registry_number" in data.keys():
            reg_number = data.get("registry_number")
            if reg_number:
                session = Session()
                num = session.query(ParliamentaryItem).filter(
                    ParliamentaryItem.registry_number == reg_number).count()
                if num != 0:
                    errors.append(
                        zope.interface.Invalid(
                            "This registry number is already taken."))
        return errors

    def setUpWidgets(self, ignore_request=False):
        class WorkflowForm:
            note = None
            date_active = None
            registry_number = None

        self.adapters = {
            self.IWorkflowForm: WorkflowForm,
        }
        self.widgets = form.setUpDataWidgets(self.form_fields,
                                             self.prefix,
                                             self.context,
                                             self.request,
                                             ignore_request=ignore_request)

    def update(self, transition_id=None):
        if IWorkspaceContainer.providedBy(self.context.__parent__):
            self._old_url = WorkspaceAbsoluteURLView(self.context,
                                                     self.request)()
        workflow = interfaces.IWorkflow(self.context)
        if transition_id:
            transition = workflow.get_transition(transition_id)
            title = translate(_(transition.title), context=self.request)
            self.status = translate(_(
                u"Confirmation required for workflow transition: '${title}'",
                mapping={"title": title}),
                                    context=self.request)
        self.setupActions(transition_id)

        if (IBungeniParliamentaryContent.providedBy(self.context)
                and get_mask(self.context) == "manual"
                and not self.context.registry_number):
            self.form_fields = self.form_fields.omit("note", "date_active")
        else:
            self.form_fields = self.form_fields.omit("registry_number")

        if not self.actions:
            self.form_fields = self.form_fields.omit("note", "date_active")
        elif not IAuditable.providedBy(self.context):
            self.form_fields = self.form_fields.omit("note", "date_active")
        # !+SUPERFLUOUS_ObejctModifiedEvent(mr, nov-2011) the following update()
        # is causing a ModifiedEvent to be fired, causing a modify change to be
        # logged (while this workflow change should be just that).
        super(WorkflowActionViewlet, self).update()

    @property
    def next_url(self):
        if IWorkspaceContainer.providedBy(self.context.__parent__):
            # check if the object is in the same tab as before.
            # if it is redirect to the object, if not redirect to the listing
            if (WorkspaceAbsoluteURLView(self.context,
                                         self.request)() == self._old_url):
                self._next_url = self._old_url
            else:
                self._next_url = absoluteURL(self.context.__parent__,
                                             self.request)
        return self._next_url

    def setupActions(self, transition_id):
        # !+RENAME(mr, apr-2011) should be transition_id
        wfc = interfaces.IWorkflowController(self.context)
        if transition_id is None:
            transition_ids = wfc.getManualTransitionIds()
        else:
            transition_ids = (transition_id, )
        self.actions = bindTransitions(self, transition_ids, wfc.workflow)
Ejemplo n.º 4
0
class PagedSearch(Pager, Search):
    template = ViewPageTemplateFile('templates/pagedsearch.pt')
Ejemplo n.º 5
0
class AdvancedPagedSearch(PagedSearch):
    template = ViewPageTemplateFile('templates/advanced-pagedsearch.pt')
    form_fields = form.Fields(IAdvancedSearch)
    form_fields["status_date"].custom_widget = SelectDateWidget

    def __init__(self, *args):
        super(AdvancedPagedSearch, self).__init__(*args)

        #print "Language:", translate("Language", domain="bungeni", context=self.request)
        statuses = SimpleVocabulary([])
        indexed_fields = [
            'all',
        ]
        content_type = self.request.get('form.content_type', '')
        if content_type:
            dotted_name = "bungeni.models.domain.%s" % content_type
            domain_class = resolve.resolve(dotted_name)
            statuses = get_statuses_vocabulary(domain_class)
            f = IIndexer(domain_class()).fields()
            indexed_fields = indexed_fields + [i for i, fld in f]

        self.form_fields += \
            form.Fields(
                schema.Choice(__name__='owner', title=_("Owner"),
                    vocabulary=get_users_vocabulary(), required=False),
                schema.Choice(__name__='status', title=_("Status"),
                    vocabulary=statuses, required=False),
                schema.Choice(__name__='field', title=_('Field'),
                    values=indexed_fields, required=False),
                IHighLight
            )

    @form.action(label=_(u"Search"))
    def handle_search(self, action, data):
        self.searcher = component.getUtility(interfaces.IIndexSearch)()
        search_term = data['full_text']
        content_type = data['content_type']
        lang = data['language']
        indexed_field = data.get('field', '')
        status = data.get('status', '')
        status_date = data['status_date']
        owner = data.get('owner', '')

        if not lang:
            lang = 'en'

        if not search_term:
            self.status = _(u"Invalid Query")
            return

        # compose query
        t = time.time()

        if content_type and indexed_field and indexed_field != 'all':
            text_query = self.searcher.query_field(indexed_field, search_term)
            lang_query = self.searcher.query_field('language', lang)
            self.query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (text_query, lang_query,))
        else:
            text_query = self.searcher.query_parse(search_term)
            lang_query = self.searcher.query_field('language', lang)
            self.query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (text_query, lang_query,))

        if content_type:
            content_type_query = self.searcher.query_field(
                'object_type', content_type)
            self.query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, content_type_query,))

        if content_type and status:
            status_query = self.searcher.query_field('status', status)
            self.query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, status_query,))

        if status_date:
            status_date_query = self.searcher.query_field(
                'status_date', index.date_value(status_date))
            self.query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, status_date_query,))

        if owner:
            owner_query = self.searcher.query_field('owner', str(owner))
            self.query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, owner_query,))

        self.results = self._results
        self.search_time = time.time() - t

        # spelling suggestions
        suggestion = self.searcher.spell_correct(search_term)
        self.spelling_suggestion = (search_term != suggestion and suggestion
                                    or None)
Ejemplo n.º 6
0
class ShareForm(form.SchemaForm):
    """ A page to share a country with a group or user
    """
    implements(ICheckoutSharePage)

    schema = IShareSchema
    ignoreContext = True

    label = u"Share this country for checkout editing"
    description = u"""Here it is possible to choose the Eionet groups or
individual users that have special checkout, edit and reviewing rights in this
location."""

    template = ViewPageTemplateFile("pt/share.pt")

    status = ''

    @button.buttonAndHandler(u"Save")
    def handleApply(self, action):
        print "doing handle apply"
        data, errors = self.extractData()
        if errors:
            self.status = self.formErrorsMessage
            return

        principal_id = data['principal_id']
        role = PLONE_ROLES[data['role_id']]

        try:
            principal = self._search_principal(principal_id)
        except NoResultsException:
            msg = u'No results found.'
            self.status = msg
            print self.status
            raise ActionExecutionError(Invalid(msg))
        except MultipleResultsException:
            msg = 'The user/group id is not precise enough.'
            self.status = msg
            print self.status
            raise ActionExecutionError(Invalid(msg))

        self.status = u"Saved."

        self.share_with_principal(principal['id'], role)

    @button.buttonAndHandler(u"Cancel")
    def handleCancel(self, action):
        return self.request.response.redirect(self.context.absolute_url())

    def get_wc(self, context):
        policy = ICheckinCheckoutPolicy(context, None)

        if policy is None:
            return False

        wc = policy.getWorkingCopy()
        return wc

    def share_with_principal(self, principal_id, role):
        """ Setup proper share role for this principal
        """
        logger.info("Setting up proper %s role for %s", role, principal_id)
        print "Sharing", principal_id, role

        contexts = [self.context]
        wc = self.get_wc(self.context)
        if wc:
            contexts.append(wc)

        site = getSite()
        for location in PLONE_LOCATIONS:
            if self.context.aq_parent.id != 'countries':
                continue
            obj = site.unrestrictedTraverse(location + self.context.id)
            if obj:
                contexts.append(obj)
        for folder in contexts:
            self.assign_role_to_principal(folder, role, principal_id)
            if ICountryPage not in list(providedBy(folder)):
                mark(folder, ICountryPage)

    def assign_role_to_principal(self, context, role, principal_id):
        roles = set(context.get_local_roles_for_userid(userid=principal_id))
        roles.add(role)
        roles = list(roles)
        context.manage_setLocalRoles(principal_id, roles)

    def _search_principal(self, term):
        search = getMultiAdapter((self.context, self.request),
                                 name='pas_search')
        users = search.searchUsers(id=term)
        groups = search.searchGroups(id=term)

        result = users + groups
        if len(result) > 1:
            raise MultipleResultsException
        if len(result) == 0:
            raise NoResultsException

        return result[0]
Ejemplo n.º 7
0
class LibraryViewlet(viewlet.ViewletBase):

    render = ViewPageTemplateFile("templates/attached-files.pt")
    form_name = _("attached files")

    for_display = True
    weight = 50

    def __init__(self, context, request, view, manager):
        self.context = []
        trusted = removeSecurityProxy(context)
        # !+(murithi, mar-2010 )Attached file versions implement IVersion
        # but have no attached files - an adapter on all content
        # might make sense to fetch attachments.
        # here we conditionaly skip attachment versions
        if not IAttachedFileVersion.providedBy(trusted):
            for f in trusted.attached_files:
                if IAttachedFileVersion.providedBy(f):
                    self.context.append(f)
                else:
                    if f.attached_file_type != "system":
                        self.context.append(f)
        self.request = request
        self.__parent__ = context
        self.manager = manager
        self.query = None
        self.for_display = len(self.context) > 0
        self.interaction = getInteraction()
        self.formatter = utils.date.getLocaleFormatter(self.request, "date",
                                                       "long")

    def results(self):
        for data in self.context:
            yield {
                "title": data.file_title,
                "url": "./files/obj-%i" % data.attached_file_id,
                "name": data.file_name,
                "type": _(data.attached_file_type),
                "status_date": self.formatter.format(data.status_date),
                "menu": self.generate_file_manipulation_menu(data)
            }

    def generate_file_manipulation_menu(self, context):
        menu_items = []
        view_item = self.create_view_menu_item(context)
        if view_item:
            menu_items.append(view_item)
        edit_item = self.create_edit_menu_item(context)
        if edit_item:
            menu_items.append(edit_item)
        delete_item = self.create_delete_menu_item(context)
        if delete_item:
            menu_items.append(delete_item)
        download_item = self.create_download_menu_item(context)
        if download_item:
            menu_items.append(download_item)
        return menu_items

    def create_view_menu_item(self, context):
        permission_name = "bungeni.fileattachment.View"
        if self.interaction.checkPermission(permission_name, self.__parent__):
            return {
                "title": _("VIEW"),
                "url": "./files/obj-%i" % context.attached_file_id,
                "active": True
            }
        return None

    def create_edit_menu_item(self, context):
        permission_name = "bungeni.fileattachment.Edit"
        if self.interaction.checkPermission(permission_name, self.__parent__):
            return {
                "title": _("EDIT"),
                "url": "./files/obj-%i/edit" % context.attached_file_id,
                "active": True
            }
        return None

    def create_delete_menu_item(self, context):
        permission_name = "bungeni.fileattachment.Delete"
        if self.interaction.checkPermission(permission_name, self.__parent__):
            return {
                "title": _("DELETE"),
                "url": "./files/obj-%i/deactivate" % context.attached_file_id,
                "active": context.status != "inactive"
            }
        return None

    def create_download_menu_item(self, context):
        permission_name = "bungeni.fileattachment.View"
        if self.interaction.checkPermission(permission_name, self.__parent__):
            return {
                "title": _("DOWNLOAD"),
                "url": "./files/obj-%i/download" % context.attached_file_id,
                "active": True
            }
        return None
Ejemplo n.º 8
0
class DiffEditForm(EditForm):
    """ Form to display diff view if timestamp was changes.
    """
    CustomValidation = validations.diff_validator
    template = ViewPageTemplateFile("templates/diff-form.pt")

    def __init__(self, context, request):
        self.diff_widgets = []
        self.diff = False
        self.last_timestamp = None
        super(DiffEditForm, self).__init__(context, request)
        need("diff-form")

    def update(self):
        """ Checks if we have Modified errors and renders split view 
            with display widgets for db values and normal for input 
        """
        super(DiffEditForm, self).update()
        for error in self.errors:
            if error.__class__ == Modified:
                # Set flag that form is in diff mode
                if not self.diff:
                    self.diff = True

        if self.diff:
            # Set last timestamp which we store in hidden field because
            # document may be modified during diff and from.timestamp field
            # contains old value
            self.last_timestamp = self.context.timestamp
            for widget in self.widgets:
                try:
                    value = widget.getInputValue()
                except:
                    value = ""

                # Get widget's field
                form_field = self.form_fields.get(widget.context.__name__)
                field = form_field.field.bind(self.context)

                # Form display widget for our field
                if form_field.custom_widget is not None:
                    display_widget = form_field.custom_widget(
                        field, self.request)
                else:
                    display_widget = component.getMultiAdapter(
                        (field, self.request), IDisplayWidget)

                # If field is Text or TextLine we display HTML diff
                if IText.providedBy(field) or ITextLine.providedBy(field):
                    if value:
                        diff_val = textDiff(field.get(self.context), value)
                    else:
                        diff_val = ""
                    display_widget = component.getMultiAdapter(
                        (field, self.request), IDiffDisplayWidget)
                    display_widget.setRenderedValue(diff_val)
                else:
                    display_widget.setRenderedValue(field.get(self.context))
                display_widget.name = widget.name + ".diff.display"
                # Add display - input widgets pair to list of diff widgets
                self.diff_widgets.append((widget, display_widget))
Ejemplo n.º 9
0
class DeleteForm(PageForm):
    """Delete-form for Bungeni content.

    Confirmation

        The user is presented with a confirmation form which details
        the items that are going to be deleted.

    Subobjects

        Recursively, a permission check is carried out for each item
        that is going to be deleted. If a permission check fails, an
        error message is displayed to the user.

    Will redirect back to the container on success.
    """
    form_template = NamedTemplate("alchemist.form")
    template = ViewPageTemplateFile("templates/delete.pt")
    #template = z3evoque.PageViewTemplateFile("delete.html")

    _next_url = None
    form_fields = formlib.form.Fields()

    def _can_delete_item(self, action):
        return True

    def nextURL(self):
        return self._next_url

    def update(self):
        self.subobjects = self.get_subobjects()
        super(DeleteForm, self).update()

    def get_subobjects(self):
        return ()

    def delete_subobjects(self):
        return 0

    @formlib.form.action(_(u"Delete"),
                         name="delete",
                         condition=_can_delete_item)
    def handle_delete(self, action, data):
        count = self.delete_subobjects()
        container = self.context.__parent__
        trusted = removeSecurityProxy(self.context)
        session = Session()
        session.delete(trusted)
        count += 1
        try:
            session.flush()
        except IntegrityError, e:
            # this should not happen in production; it's a critical
            # error, because the transaction might have failed in the
            # second phase of the commit
            session.rollback()
            log.critical(e)
            self.status = _(
                "Could not delete item due to database integrity error. "
                "You may wish to try deleting any related sub-records first?")
            return self.render()

        #TODO: check that it is removed from the index!
        notify(
            ObjectRemovedEvent(self.context,
                               oldParent=container,
                               oldName=self.context.__name__))
        # we have to switch our context here otherwise the deleted object will
        # be merged into the session again and reappear magically
        self.context = container
        #cascade_modifications(container)
        next_url = self.nextURL()

        if next_url is None:
            next_url = url.absoluteURL(container, self.request) + \
                       "/?portal_status_message=%d items deleted" % count
        if self.is_headless:
            log.info("Deleting in headless mode - No redirection")
        else:
            self.request.response.redirect(next_url)
Ejemplo n.º 10
0
class WhatsOnBrowserView(BrowserView):
    __call__ = ViewPageTemplateFile("templates/whatson.pt")

    def __init__(self, context, request):
        super(WhatsOnBrowserView, self).__init__(context, request)
        parliament_id = getCurrentParliamentId()
        if parliament_id:
            session = Session()
            parliament = session.query(domain.Parliament).get(parliament_id)
            self.context = parliament
            self.context.__parent__ = context
            self.context.__name__ = ""
        start_date, end_date = get_date_range(request)
        if type(start_date) != datetime.date:
            self.start_date = datetime.date.today()
        else:
            self.start_date = start_date
        if type(end_date) != datetime.date:
            end_date = datetime.date.today() + datetime.timedelta(10)
            self.end_date = datetime.datetime(end_date.year, end_date.month,
                                              end_date.day, 23, 59)
        else:
            self.end_date = datetime.datetime(end_date.year, end_date.month,
                                              end_date.day, 23, 59)
        self.get_items()

    def get_end_date(self):
        formatter = self.request.locale.dates.getFormatter('date', 'full')
        return formatter.format(self.end_date)

    def get_start_date(self):
        formatter = self.request.locale.dates.getFormatter('date', 'full')
        return formatter.format(self.start_date)

    def get_sitting_items(self, sitting):
        s_list = []
        for schedule in sitting.item_schedule:
            s_list.append({
                'name':
                schedule.item.short_name,
                'status':
                misc.get_wf_state(schedule.item),
                'url':
                url.set_url_context(
                    ('/business/' + schedule.item.type + 's/obj-' +
                     str(schedule.item.parliamentary_item_id))),
                'item_type':
                schedule.item.type,
            })
        return s_list

    def get_sittings(self):
        formatter = self.request.locale.dates.getFormatter('date', 'full')
        session = Session()
        query = session.query(domain.GroupSitting).filter(
            sql.and_(
                schema.sittings.c.status.in_(
                    get_states('groupsitting', tagged=['public'])),
                sql.between(schema.sittings.c.start_date, self.start_date,
                            self.end_date))).order_by(
                                schema.sittings.c.start_date).options(
                                    eagerload('group'),
                                    #eagerload('sitting_type'),
                                    eagerload('item_schedule'),
                                    eagerload('item_schedule.item'))
        sittings = query.all()
        day = u''
        day_list = []
        s_dict = {}
        for sitting in sittings:
            sday = formatter.format(sitting.start_date)
            if sday != day:
                s_list = []
                day = sday
                if s_dict:
                    day_list.append(s_dict)
                s_dict = {}
            if sitting.group.type == 'parliament':
                _url = url.set_url_context('/business/sittings/obj-%i' %
                                           (sitting.sitting_id))
            elif sitting.group.type == 'committee':
                _url = url.set_url_context(
                    '/business/committees/obj-%i/sittings/obj-%i' %
                    (sitting.group.group_id, sitting.sitting_id))
            else:
                _url = '#'
            s_list.append({
                'start': sitting.start_date.strftime("%H:%M"),
                'end': sitting.end_date.strftime("%H:%M"),
                'type': sitting.group.type,
                'name': sitting.group.short_name,
                'url': _url,
                'items': self.get_sitting_items(sitting),
            })
            s_dict['day'] = day
            s_dict['sittings'] = s_list
        else:
            if s_dict:
                day_list.append(s_dict)
        return day_list

    def get_items(self):
        session = Session()
        where_clause = sql.and_(
            schema.sittings.c.status.in_(
                get_states("groupsitting", tagged=["public"])),
            sql.between(schema.sittings.c.start_date, self.start_date,
                        self.end_date))

        query = session.query(domain.ItemSchedule).join(
            domain.GroupSitting).filter(where_clause).order_by(
                schema.sittings.c.start_date).options(
                    eagerload('sitting'),
                    eagerload('item'),
                    #eagerload('sitting.sitting_type'),
                    lazyload('item.owner'))
        self.itemschedules = query.all()

    def get_items_by_type(self, item_type):
        day = u''
        day_list = []
        s_dict = {}
        formatter = self.request.locale.dates.getFormatter('date', 'full')
        for schedule in self.itemschedules:
            if type(schedule.item) == item_type:
                sday = formatter.format(schedule.sitting.start_date)
                if sday != day:
                    s_list = []
                    day = sday
                    if s_dict:
                        day_list.append(s_dict)
                    s_dict = {}
                s_list.append({
                    'name':
                    schedule.item.short_name,
                    'status':
                    misc.get_wf_state(schedule.item),
                    'url':
                    url.set_url_context("/business/%ss/obj-%s" %
                                        (schedule.item.type,
                                         schedule.item.parliamentary_item_id)),
                    'group_type':
                    schedule.sitting.group.type,
                    'group_name':
                    schedule.sitting.group.short_name
                })
                s_dict['day'] = day
                s_dict['items'] = s_list
        if s_dict:
            day_list.append(s_dict)
        return day_list

    def get_questions(self):
        return self.get_items_by_type(domain.Question)

    def get_bills(self):
        return self.get_items_by_type(domain.Bill)

    def get_motions(self):
        return self.get_items_by_type(domain.Motion)

    def get_tableddocuments(self):
        return self.get_items_by_type(domain.TabledDocument)

    def get_agendaitems(self):
        return self.get_items_by_type(domain.AgendaItem)
    def render(self):
        if not self.__updated:
            raise UpdateNotCalled

        pageTemplate = ViewPageTemplateFile(self.pageTemplateFileName)
        return pageTemplate(self)
Ejemplo n.º 12
0
class WorkflowActionViewlet(BaseForm, viewlet.ViewletBase):
    """Display workflow status and actions."""

    class IWorkflowComment(zope.interface.Interface):
        note = zope.schema.Text(
            title=_("Comment on workflow change"), required=True )

    form_name = "Workflow"
    form_fields = form.Fields(IWorkflowComment)
    actions = ()
    
    render = ViewPageTemplateFile ('templates/viewlet.pt')
    
    def update(self, transition=None):
        self.adapters = {
            self.IWorkflowComment: WorkflowComment(),
            }

        wf = interfaces.IWorkflow(self.context) 
        
        if transition is not None:
            state_transition = wf.getTransitionById(transition)
            self.status = _(
                u"Confirmation required for workflow transition: '${title}'",
                mapping={'title': _(state_transition.title)})

        self.setupActions(transition)
        super(WorkflowActionViewlet, self).update()

        # after we transition we have different actions
        self.setupActions(transition)
        # only display the notes field to comment if there is an action
        # and a log table
        auditor = audit.getAuditor( self.context )
        if len(self.actions) == 0: 
            self.form_fields = self.form_fields.omit('note')
        elif auditor is None:
            self.form_fields = self.form_fields.omit('note')
        else:
            note_widget = TextAreaWidget
            note_widget.height = 1
            self.form_fields['note'].custom_widget = note_widget
                        
        self.setUpWidgets()

    def setupActions(self, transition):
        self.wf = interfaces.IWorkflowInfo( self.context )

        if transition is None:
            transitions = self.wf.getManualTransitionIds()
        else:
            transitions = (transition,)
            
        self.actions = bindTransitions(
            self, transitions, None, interfaces.IWorkflow(self.context))

    def setUpWidgets(self, ignore_request=False):
        # setup widgets in data entry mode not bound to context
        self.widgets = form.setUpDataWidgets(
            self.form_fields, self.prefix, self.context, self.request,
            ignore_request = ignore_request )
Ejemplo n.º 13
0
class GlobalTaskListingTab(grok.View, OpengeverTab, ListingView):
    """A tabbed view mixing which brings support for listing tasks from
    the SQL (globally over all clients).

    There is support for searching, batching and ordering.
    """

    implements(IGlobalTaskTableSourceConfig)

    grok.context(IJournalizable)
    grok.require('zope2.View')

    template = ViewPageTemplateFile("generic_task.pt")

    sort_on = 'modified'
    sort_reverse = False
    #lazy must be false otherwise there will be no correct batching
    lazy = False

    # the model attributes is used for a dynamic textfiltering functionality
    model = Task
    enabled_actions = []
    major_actions = []

    select_all_template = ViewPageTemplateFile('select_all_globaltasks.pt')
    selection = ViewPageTemplateFile("selection_tasks.pt")

    open_states = [
        'task-state-open',
        'task-state-in-progress',
        'task-state-resolved',
        'task-state-rejected',
        'forwarding-state-open',
        'forwarding-state-refused',
    ]

    state_filter_name = 'task_state_filter'

    columns = (
        ('', task_id_checkbox_helper),
        {
            'column': 'review_state',
            'column_title': _(u'column_review_state', default=u'Review state'),
            'transform': workflow_state
        },
        {
            'column': 'title',
            'column_title': _(u'column_title', default=u'Title'),
            'transform': indexed_task_link_helper
        },
        {
            'column': 'task_type',
            'column_title': _(u'column_task_type', default=u'Task type'),
            'transform': task_type_helper
        },
        {
            'column': 'deadline',
            'column_title': _(u'column_deadline', default=u'Deadline'),
            'transform': overdue_date_helper
        },
        {
            'column':
            'completed',
            'column_title':
            _(u'column_date_of_completion', default=u'Date of completion'),
            'transform':
            readable_date_set_invisibles
        },
        {
            'column': 'responsible',
            'column_title': _(u'label_responsible_task',
                              default=u'Responsible'),
            'transform': readable_ogds_author
        },
        {
            'column': 'issuer',
            'column_title': _(u'label_issuer', default=u'Issuer'),
            'transform': readable_ogds_author
        },
        {
            'column': 'created',
            'column_title': _(u'column_issued_at', default=u'Issued at'),
            'transform': helper.readable_date
        },
        {
            'column': 'containing_dossier',
            'column_title': _('containing_dossier', 'Dossier'),
        },
        {
            'column': 'client_id',
            'column_title': _('column_client', default=u'Client'),
            'transform': client_title_helper,
            'condition': display_client_title_condition
        },
        {
            'column':
            'sequence_number',
            'column_title':
            _(u'column_sequence_number', default=u'Sequence number')
        },
    )

    __call__ = ListingView.__call__
    update = ListingView.update
    render = __call__
Ejemplo n.º 14
0
class DhtmlxCalendarSittings(BrowserView):
    """This view returns xml of the sittings for the week and group 
    requested in a format acceptable by DHTMLX scheduler"""
    interface.implements(IStructuralView)

    content_mimetype = "text/xml"
    template = ViewPageTemplateFile("templates/dhtmlxcalendarxml.pt")

    def __init__(self, context, request):
        super(DhtmlxCalendarSittings,
              self).__init__(ISchedulingContext(context), request)
        self.context.__name__ = self.__name__
        interface.alsoProvides(self.context, ILocation)
        interface.alsoProvides(self.context, IDCDescriptiveProperties)
        self.__parent__ = context

    def get_sessions(self):
        sessions = [
            removeSecurityProxy(session)
            for key, session in self.context.get_group().sessions.items()
            if checkPermission("bungeni.session.View", session)
        ]
        sessions.sort(key=lambda sess: sess.start_date)
        return sessions

    def get_colour(self, event):
        hx = event.colour if hasattr(event, "colour") else self.event_colour
        return "#%s" % hx

    def get_event_type(self, event):
        return event.__class__.__name__.lower()

    def get_end_date(self, event):
        """Get formatted end time of event.
        For sessions, we set the end time to last hour of last day.
        """
        if model_interfaces.ISession.providedBy(event):
            return event.end_date.strftime('%Y-%m-%d 24:00')
        return event.end_date.strftime(DT_FORMAT)

    def get_event_id(self, event):
        """This ensures no collission between sessions and sittings
        """
        return create_id(event)

    def is_readonly(self, event):
        """Return true if event is readonly
        """
        readonly = 'true'
        if not model_interfaces.ISession.providedBy(event):
            if checkPermission("bungeni.sitting.Edit", event):
                readonly = ''
        return readonly

    @property
    def event_colour(self):
        if not hasattr(self, "event_color"):
            rq_color = unicode(self.request.form.get("color", ""))
            if rq_color:
                assert len(rq_color) <= 6
                self._event_color = rq_color
        return self._event_color if hasattr(self, "_event_color") else ""

    @property
    def sittings_and_sessions(self):
        event_list = []
        try:
            date = self.request.get("from")
            dateobj = datetime.datetime(*time.strptime(date, "%Y-%m-%d")[0:5])
            start_date = utils.datetimedict.fromdate(dateobj)
        except:
            start_date = None

        try:
            date = self.request.get("to")
            dateobj = datetime.datetime(*time.strptime(date, "%Y-%m-%d")[0:5])
            end_date = utils.datetimedict.fromdate(dateobj)
        except:
            end_date = None

        if start_date is None:
            start_date = utils.datetimedict.fromdate(datetime.date.today())
            days = tuple(start_date + timedelta(days=d) for d in range(7))
            end_date = days[-1]
        elif end_date is None:
            start_date = utils.datetimedict.fromdate(datetime.date.today())
            days = tuple(start_date + timedelta(days=d) for d in range(7))
            end_date = days[-1]
        sittings = self.context.get_sittings(start_date, end_date)
        for sitting in sittings.values():
            if checkPermission("bungeni.sitting.View", sitting):
                trusted = removeSecurityProxy(sitting)
                trusted.text = dict(sitting_status=_(
                    misc.get_wf_state(trusted, trusted.status)))
                event_list.append(trusted)
        if model_interfaces.IChamber.providedBy(self.context.get_group()):
            return event_list + self.get_sessions()
        else:
            return event_list

    def __call__(self):
        self.request.response.setHeader("Content-type", self.content_mimetype)
        return self.render()

    def render(self, template=None):
        return self.template()
Ejemplo n.º 15
0
class DhtmlxCalendarSittingsEdit(form.PageForm):
    """Form to add, edit or delete a sitting that works with
    DHTMLX scheduler"""

    #!+ CALENDAR(miano, dec-2010) Add recurrence to the model so that
    # sittings added as part of a recurrence can be modified as a part of that
    # recurrence a la google calendar.

    prefix = ""
    xml_template = ViewPageTemplateFile(
        "templates/dhtmlxcalendar_edit_form.pt")
    template_data = []

    def __init__(self, context, request):
        #dhtmlxscheduler posts the field names prefixed with the id
        #of the sitting, the code below removes the prefix and set the action to
        #be performed
        data = request.form
        for key in request.form.keys():
            t = key.partition("_")
            request.form[t[2]] = data[key]
        if request.form.get("event_pid"):
            request.form["event_pid"] = get_real_id(request.form["event_pid"])
        if request.form.get("rec_type") == "none":
            request.form["!nativeeditor_status"] = "deleted"
        if "!nativeeditor_status" in request.form.keys():
            if request.form["!nativeeditor_status"] == "inserted":
                request.form["actions.insert"] = "insert"
            elif request.form["!nativeeditor_status"] == "updated":
                request.form["actions.update"] = "update"
            elif request.form["!nativeeditor_status"] == "deleted":
                request.form["actions.delete"] = "delete"
        super(DhtmlxCalendarSittingsEdit, self).__init__(context, request)

    @property
    def sittings_container(self):
        traverser = component.getMultiAdapter((self.context, self.request),
                                              IPublishTraverse)
        return traverser.publishTraverse(self.request, "sittings")

    form_fields = form.Fields(interfaces.IDhtmlxCalendarSittingsEditForm)

    def setUpWidgets(self, ignore_request=False):
        class context:
            ids = None
            event_pid = None
            short_name = None
            start_date = None
            end_date = None
            location = None
            language = None
            venue = None
            rec_type = None
            event_length = None
            nativeeditor_status = None
            activity_type = None
            meeting_type = None
            convocation_type = None

        context.__parent__ = self.context
        self.adapters = {interfaces.IDhtmlxCalendarSittingsEditForm: context}
        self.widgets = form.setUpEditWidgets(self.form_fields,
                                             "",
                                             self.context,
                                             self.request,
                                             adapters=self.adapters,
                                             ignore_request=ignore_request)

    def insert_sitting_failure_handler(self, action, data, errors):
        error_message = _(u"Unable to add a sitting. Please make corrections.")
        error_string = u""
        for error in errors:
            if error.message not in ("", None):
                error_string += error.message + "\n"
            else:
                error_string += error.__str__() + "\n"
        #!+CALENDAR(mb, oct-2011) Include error messages in XML
        log.error(error_message)
        log.error(error_string)
        self.template_data.append(
            dict(action="invalid", ids=data["ids"], sitting_id=data["ids"]))
        self.request.response.setHeader("Content-type", "text/xml")
        return self.xml_template()

    def generate_dates(self, data):
        trusted = removeSecurityProxy(ISchedulingContext(self.context))
        recurrence_start_date = data["start_date"].replace(tzinfo=None)
        recurrence_end_date = data["rec_end_date"].replace(tzinfo=None)
        group = trusted.get_group()
        # If group is none then there is a big problem
        assert group is not None
        year = timedelta(days=365)
        now = datetime.datetime.now()
        if (((group.end_date is not None) and ((now + year) < group.end_date))
                or (group.end_date is None)):
            end = now + year
        else:
            end = group.end_date
        if recurrence_end_date > end:
            recurrence_end_date = end
        return utils.generate_recurrence_dates(recurrence_start_date,
                                               recurrence_end_date,
                                               data["rec_type"])

    # The form action strings below do not need to be translated because they are
    # not visible in the UI.
    @form.action(u"insert", failure="insert_sitting_failure_handler")
    def handle_insert(self, action, data):
        session = Session()
        data["rec_end_date"] = data["end_date"]
        self.template_data = []
        initial_sitting = None
        length = data["event_length"]
        venue_id = unicode(data["venue"]) if data['venue'] else None
        if data.get("rec_type") not in [None, "none"]:
            data["end_date"] = data["start_date"] + timedelta(seconds=length)
            self.request.form["end_date"] = data["end_date"].strftime(
                DT_FORMAT)
        data["headless"] = "true"
        self.request.form["venue_id"] = data["venue_id"] = venue_id
        self.request.form["headless"] = "true"
        add_form = AddForm(self.sittings_container, self.request)
        add_form.update()
        if not add_form.errors:
            initial_sitting = removeSecurityProxy(add_form.created_object)
        else:
            return self.insert_sitting_failure_handler(action, data,
                                                       add_form.errors)
        if ("rec_type" in data.keys()) and (data["rec_type"]
                                            not in [None, "none"]):
            # create recurring sittings
            #base_sitting_length = sitting_length + timedelta(hours=1)
            sitting_length = timedelta(seconds=length)
            base_sitting_length = timedelta(seconds=length) + timedelta(
                hours=1)
            dates = self.generate_dates(data)
            initial_sitting.recurring_type = data.get("rec_type")
            initial_sitting.recurring_id = 0
            initial_sitting.sitting_length = length
            for count, date in enumerate(dates):
                if not count:
                    #we've already added the initial sitting
                    initial_sitting.recurring_end_date = (
                        dates[len(dates) - 1] + base_sitting_length)
                    session.merge(initial_sitting)
                    continue

                sitting_data = copy(data)
                sitting_data["start_date"] = date.strftime(DT_FORMAT)
                sitting_data["end_date"] = (date +
                                            sitting_length).strftime(DT_FORMAT)

                request_copy = copy(self.request)
                request_copy.form = sitting_data
                add_form = AddForm(self.sittings_container, request_copy)
                add_form.update()
                if not add_form.errors:
                    # use finishConstruction API here
                    obj = add_form.created_object
                    obj.sitting_length = int(time.mktime(date.timetuple()))
                    obj.recurring_id = initial_sitting.sitting_id
                    session.merge(obj)
        else:
            initial_sitting.recurring_type = data.get("rec_type")
            initial_sitting.recurring_id = data.get("event_pid", 0)
            if data.get("event_length"):
                initial_sitting.sitting_length = data.get("event_length")
            session.merge(initial_sitting)
            wfc = IWorkflowController(initial_sitting)
            wfc.fireAutomatic()
        sitting_action = "inserted"
        if data["rec_type"] == "none":
            sitting_action = "deleted"
            session.merge(initial_sitting)
        self.template_data.append({
            "sitting_id": initial_sitting.sitting_id,
            "action": sitting_action,
            "ids": data["ids"],
        })
        self.request.response.setHeader("Content-type", "text/xml")
        return self.xml_template()

    def update_sitting_failure_handler(self, action, data, errors):
        error_string = u""
        error_message = _(u"Error Updating Sitting")
        for error in errors:
            if error.message not in ("", None):
                error_string += error.message + "\n"
            else:
                error_string += error.__str__() + "\n"
        log.error(error_message)
        log.error(error_string)
        self.template_data.append(
            dict(action="invalid", ids=data["ids"], sitting_id=data["ids"]))
        self.request.response.setHeader("Content-type", "text/xml")
        return self.xml_template()

    @form.action(u"update", failure="update_sitting_failure_handler")
    def handle_update(self, action, data):
        session = Session()
        self.template_data = []
        venue_id = unicode(data["venue"]) if data['venue'] else None
        data["rec_end_date"] = data["end_date"]
        data["headless"] = 'true'
        self.request.form["venue_id"] = data["venue_id"] = venue_id
        self.request.form["headless"] = "true"
        if ("rec_type" in data.keys()) and (data["rec_type"] is not None):
            # updating recurring events - we assume existing events fall
            # at the beginning of the sequence and offer in place update.
            parent_sitting_id = get_real_id(data["ids"] or data["event_pid"])
            length = data["event_length"]
            sitting_length = timedelta(seconds=length)
            base_sitting_length = sitting_length + timedelta(hours=1)
            siblings_filter = or_(
                domain.Sitting.recurring_id == parent_sitting_id,
                domain.Sitting.sitting_id == parent_sitting_id)
            siblings = [
                sitting for sitting in self.sittings_container.batch(
                    order_by=(domain.Sitting.sitting_id),
                    limit=None,
                    filter=siblings_filter)
            ]
            dates = self.generate_dates(data)
            current_count = len(siblings)
            for count, date in enumerate(dates):
                is_new = not count < current_count
                sitting_data = copy(data)
                sitting_data["start_date"] = date.strftime(DT_FORMAT)
                sitting_data["end_date"] = (date +
                                            sitting_length).strftime(DT_FORMAT)
                request_copy = copy(self.request)
                request_copy.form = sitting_data
                if is_new:
                    add_form = AddForm(self.sittings_container, request_copy)
                    add_form.update()
                    if add_form.errors:
                        log.error("Could not add sitting in sequence: %s",
                                  sitting_data)
                        continue
                    else:
                        sitting = add_form.created_object
                        sitting.recurring_id = parent_sitting_id
                else:
                    sitting = siblings[count]
                if not count:
                    sitting.recurring_end_date = dates[len(dates) -
                                                       1] + base_sitting_length
                    sitting.recurring_type = data.get("rec_type")
                    sitting.recurring_id = 0
                    sitting.sitting_length = length
                else:
                    sitting.sitting_length = int(time.mktime(date.timetuple()))
                    sitting.recurring_type = None
                if not is_new:
                    edit_form = EditForm(sitting, request_copy)
                    edit_form.update()
                    if edit_form.errors:
                        continue
                    else:
                        session.merge(edit_form.context)
                else:
                    session.merge(sitting)
                self.template_data.append({
                    "sitting_id":
                    sitting.sitting_id,
                    "action": (is_new and "inserted" or "updated"),
                    "ids":
                    create_id(sitting)
                })
            #delete any sittings outside recurring bounds
            for del_sibling in siblings[len(dates):]:
                delete_form = DeleteForm(del_sibling, self.request)
                delete_form.update()
                if delete_form.errors:
                    continue
                else:
                    self.template_data.append({
                        "sitting_id": del_sibling.sitting_id,
                        "action": "deleted",
                        "ids": create_id(del_sibling)
                    })
        else:
            sitting_id = get_real_id(data["ids"])
            parent_id = get_real_id(data["event_pid"])
            sitting = self.sittings_container.get(sitting_id)
            if sitting is None:
                sitting = self.sittings_container.get(int(parent_id))
            edit_form = EditForm(sitting, self.request)
            edit_form.update()
            if edit_form.errors:
                return self.update_sitting_failure_handler(
                    action, data, edit_form.errors)
            else:
                sitting.sitting_length = data.get("event_length")
                sitting = removeSecurityProxy(sitting)
                session.merge(sitting)
                self.template_data.append({
                    "sitting_id": sitting.sitting_id,
                    "action": "updated",
                    "ids": data["ids"],
                })
        self.request.response.setHeader("Content-type", "text/xml")
        return self.xml_template()

    def delete_sitting_failure_handler(self, action, data, errors):
        error_string = u""
        error_message = _(u"Error Deleting Sitting")
        for error in errors:
            if error.message not in ("", None):
                error_string += error.message + "\n"
            else:
                error_string += error.__str__() + "\n"
        log.error(error_message)
        log.error(error_string)
        self.template_data.append(
            dict(action="inserted", ids=data["ids"], sitting_id=data["ids"]))
        self.request.response.setHeader("Content-type", "text/xml")
        return self.xml_template()

    @form.action(u"delete", failure="delete_sitting_failure_handler")
    def handle_delete(self, action, data):
        self.template_data = []
        if ISchedulingContext.providedBy(self.context):
            container = removeSecurityProxy(self.context.__parent__).sittings
        else:
            container = self.context.publishTraverse(self.request, "sittings")
        sitting = (container.get(get_real_id(data["ids"])) or container.get(
            get_real_id(self.request.form["event_pid"])))
        self.template_data = []
        if sitting is not None:
            self.request.form["headless"] = "true"
            delete_form = DeleteForm(sitting, self.request)
            delete_form.update()
            if not delete_form.errors:
                self.template_data.append({
                    "sitting_id": sitting.sitting_id,
                    "action": "deleted",
                    "ids": data["ids"],
                })
            else:
                return self.delete_sitting_failure_handler(
                    action, data, delete_form.errors)
        self.request.response.setHeader("Content-type", "text/xml")
        return self.xml_template()
Ejemplo n.º 16
0
class BungeniCalendarMacros(BrowserView):

    template = ViewPageTemplateFile('calendar/templates/macros.pt')

    def __getitem__(self, key):
        return self.template.macros[key]
Ejemplo n.º 17
0
from bungeni.ui.forms.common import ReorderForm
from bungeni.ui.forms.common import PageForm
from bungeni.ui.forms.common import AddForm
from bungeni.ui.forms.common import EditForm
from bungeni.ui.forms.common import DeleteForm
from bungeni.ui.forms.common import DisplayForm

from interfaces import Modified
from zope import component
from zope.formlib.interfaces import IDisplayWidget
from zope.schema.interfaces import IText, ITextLine
from bungeni.ui.widgets import IDiffDisplayWidget
from bungeni.ui.diff import textDiff

FormTemplate = namedtemplate.NamedTemplateImplementation(
    ViewPageTemplateFile("templates/form.pt"))

ContentTemplate = namedtemplate.NamedTemplateImplementation(
    ViewPageTemplateFile("templates/content.pt"))


def hasDeletePermission(context):
    """Generic check if the user has rights to delete the object. The
    permission must follow the convention:
    ``bungeni.<classname>.Delete`` where "classname" is the lowercase
    of the name of the python class.
    """
    interaction = zope.security.management.getInteraction()
    class_name = context.__class__.__name__
    permission_name = "bungeni.%s.Delete" % class_name.lower()
    return interaction.checkPermission(permission_name, context)
Ejemplo n.º 18
0
class Search(forms.common.BaseForm, ResultListing, HighlightMixin):
    """  basic content search form and results
    """
    template = ViewPageTemplateFile('templates/search.pt')
    form_fields = form.Fields(ISearch, IHighLight)

    #selection_column = columns[0]

    def setUpWidgets(self, ignore_request=False):
        # setup widgets in data entry mode not bound to context
        self.adapters = {}
        self.widgets = form.setUpDataWidgets(self.form_fields,
                                             self.prefix,
                                             self.context,
                                             self.request,
                                             ignore_request=ignore_request)

    @property
    def doc_count(self):
        return len(self._searchresults)

    def authorized(self, result):
        obj = result.object()
        defaultview = getDefaultViewName(obj, self.request)
        view = queryMultiAdapter((ProxyFactory(obj), self.request),
                                 name=defaultview)
        return canAccess(view, "__call__")

    def get_description(self, item):
        return item.description

    def get_title(self, item):
        return "%s %s" % (translate_obj(
            item.origin,
            self.request.locale.id.language).short_name, _(u"changes from"))

    def get_url(self, item):
        site = getSite()
        base_url = absoluteURL(site, self.request)
        return base_url + "/business/%ss/obj-%s" % (
            item.origin.type, item.origin.parliamentary_item_id)

    def get_user_subscriptions(self):
        """ Getting user subscribed items
        """
        session = Session()
        user = session.query(domain.User).filter(
            domain.User.login == self.request.principal.id).first()
        return user.subscriptions

    def workspace_search(self):
        """ Search in workspace section, based on views from bungeni.ui.viewlets.workspace
        """
        application = common.get_application()
        parliament = get_current_parliament(None)
        parliament.__parent__ = application
        principal = get_principal()
        roles = common.get_context_roles(parliament, principal)

        # minister role, filtering by states and object_type and ministry_id
        if not roles:
            user_id = get_db_user_id()
            government_id = get_current_parliament_governments(
                parliament)[0].group_id
            ministries = get_ministries_for_user_in_government(
                user_id, government_id)
            if ministries:
                states = workspace.MinistryArchiveViewlet.states + \
                         workspace.OralMinistryQuestionsViewlet.states + \
                         workspace.WrittenMinistryQuestionsViewlet.states + \
                         workspace.InProgressMinistryItemsViewlet.states
                states = set(states)

                ministry_ids = [m.group_id for m in ministries]

                # filter by object_type (questions only)
                type_query = self.searcher.query_field('object_type',
                                                       "Question")
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, type_query,))

                subqueries = []

                for state in states:
                    subqueries.append(
                        self.searcher.query_field('status', state))

                state_query = self.searcher.query_composite(
                    self.searcher.OP_OR, subqueries)
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                           (query, state_query,))

                #filter for ministries
                ministries_queries = []

                for mid in ministry_ids:
                    ministries_queries.append(
                        self.searcher.query_field('ministry_id', str(mid)))

                m_query = self.searcher.query_composite(
                    self.searcher.OP_OR, ministries_queries)
                query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                           (query, m_query,))

                try:
                    results = self.searcher.search(
                        query, 0, self.searcher.get_doccount())
                except:
                    results = []

                return list(results)

        # filtering by states and owner
        if 'bungeni.MP' in roles:
            states = workspace.MPItemActionRequiredViewlet.states + \
                     workspace.MPItemDraftViewlet.states + \
                     workspace.MPItemInProgressViewlet.states + \
                     workspace.ItemArchiveViewlet.states
            states = set(states)
            # filter by owner of PI
            owner_query = self.searcher.query_field('owner',
                                                    str(get_db_user_id()))
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, owner_query,))

            subqueries = []

            for state in states:
                subqueries.append(self.searcher.query_field('status', state))

            state_query = self.searcher.query_composite(
                self.searcher.OP_OR, subqueries)
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (query, state_query,))

            try:
                results = self.searcher.search(query, 0,
                                               self.searcher.get_doccount())
            except:
                results = []

            return list(results)

        # filtering by states
        if 'bungeni.Clerk' in roles:
            states = workspace.ClerkItemActionRequiredViewlet.states + \
                     workspace.ClerkItemsWorkingDraftViewlet.states + \
                     workspace.ClerkReviewedItemViewlet.states + \
                     workspace.ItemsApprovedViewlet.states + \
                     workspace.ItemsPendingScheduleViewlet.states + \
                     workspace.ItemsScheduledViewlet.states + \
                     workspace.AllItemArchiveViewlet.states

            states = set(states)

            subqueries = []

            for state in states:
                subqueries.append(self.searcher.query_field('status', state))

            state_query = self.searcher.query_composite(
                self.searcher.OP_OR, subqueries)
            query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, state_query,))

            try:
                results = self.searcher.search(query, 0,
                                               self.searcher.get_doccount())
            except:
                results = []

            return list(results)
        # no results
        return False

    @CachedProperty
    def _searchresults(self):
        section = get_section_name()
        subqueries = []

        # Filter items allowed in current section
        for tq in ALLOWED_TYPES[section]:
            subqueries.append(self.searcher.query_field('object_type', tq))

        type_query = self.searcher.query_composite(self.searcher.OP_OR,
                                                   subqueries)

        self.query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, type_query,))

        try:
            results = self.searcher.search(self.query, 0,
                                           self.searcher.get_doccount())
        except:
            results = []

        results = filter(self.authorized, results)

        # in workspace section we are using different search filters based on states
        if section == 'workspace':
            extra = self.workspace_search()
            # if no results - use common search
            if extra:
                return extra

        return results

    @property
    def _results(self):
        return map(lambda x: x.object(), self._searchresults)

    @form.action(label=_(u"Search"))
    def handle_search(self, action, data):
        self.searcher = component.getUtility(interfaces.IIndexSearch)()
        search_term = data['full_text']

        if not search_term:
            self.status = _(u"Invalid Query")
            return

        # compose query
        t = time.time()
        lang = self.request.locale.getLocaleID()
        if lang == "en_US": lang = "en"
        if lang == "en_KE": lang = "en-ke"
        text_query = self.searcher.query_parse(search_term)
        lang_query = self.searcher.query_field('language', lang)
        self.query = self.searcher.query_composite(self.searcher.OP_AND, (
            text_query,
            lang_query,
        ))
        self.results = self._results
        self.search_time = time.time() - t

        # spelling suggestions
        suggestion = self.searcher.spell_correct(search_term)
        self.spelling_suggestion = (search_term != suggestion and suggestion
                                    or None)
Ejemplo n.º 19
0
class AttendanceEditor(BungeniBrowserView, ui.BaseForm):
    """Multiple attendance record editor for sittings"""

    form_fields = []

    render = ViewPageTemplateFile("templates/attendance.pt")

    def __init__(self, context, request):
        super(AttendanceEditor, self).__init__(context, request)

    @property
    def radio_prefix(self):
        return "sitting_attendance_radio"

    @property
    def columns(self):
        listing_columns = [
            column.GetterColumn(title=_("full names"),
                                getter=lambda i, f: i.get("attendee"))
        ]
        for rcount, at_type in enumerate(self.attendance_types):
            at_column = column.GetterColumn(
                title=at_type.title,
                getter=lambda i, f: i,
                cell_formatter=lambda g, i, f, rc=rcount: \
                    '<input type="radio" name="%s" value="%s"%s/>' % (
                        i["records"][rc]["name"],
                        i["records"][rc]["value"],
                        i["records"][rc]["checked"] and ' checked="checked"' or ""
                )
            )
            listing_columns.append(at_column)
        return listing_columns

    def make_id(self, value):
        return "".join(
            (self.radio_prefix, "".join(str(value).encode("base64").split())))

    @property
    def column_titles(self):
        return [at.title for at in self.attendance_types]

    @property
    def attendance_types(self):
        """ () -> zope.schema.vocabulary.SimpleVocabulary."""
        from bungeni.ui import vocabulary  # !+
        return vocabulary.attendance_type

    @property
    def formatted_listing(self):
        formatter = TableFormatter(
            self.context,
            self.request,
            self.listing,
            prefix="attendance",
            visible_column_names=[c.name for c in self.columns],
            columns=self.columns)
        formatter.updateBatching()
        return formatter()

    @property
    def listing(self):
        list_data = []
        trusted = removeSecurityProxy(self.context)
        current_attendance = list(trusted.attendance.values())
        for member in trusted.group.group_members:
            attd = filter(lambda i: i.member_id == member.user_id,
                          current_attendance)
            m_data = {}
            m_data["attendee"] = IDCDescriptiveProperties(member).title
            m_data["has_record"] = int(bool(attd))
            m_data["records"] = [{
                "name":
                self.make_id(member.user_id),
                "checked":
                bool(attd) and (attd[0].attendance_type == at_type.value),
                "value":
                at_type.value
            } for at_type in self.attendance_types]
            list_data.append(m_data)
        sorted_list = sorted(list_data,
                             key=itemgetter("has_record", "attendee"))
        return sorted_list

    def has_listing(self, action):
        return bool(len(self.listing))

    @property
    def action_url(self):
        return ""

    @property
    def action_method(self):
        return "post"

    @formlib.form.action(label=_("Save"), name="save", condition=has_listing)
    def handle_save(self, action, data):
        self.process_attendance()

    @formlib.form.action(label=_("Save and view"),
                         name="save_and_view",
                         condition=has_listing)
    def handle_save_view(self, action, data):
        self.process_attendance()
        next_url = url.absoluteURL(self.__parent__, self.request)
        self.request.response.redirect(next_url + "/attendance")

    @formlib.form.action(label=_("Cancel"), name="cancel")
    def handle_cancel(self, action, data):
        next_url = url.absoluteURL(self.__parent__, self.request)
        self.request.response.redirect(next_url)

    def setUpWidgets(self, ignore_request=False):
        actions = self.actions
        self.actions = []
        for action in actions:
            if getattr(action, "condition", None):
                if action.condition(self, self.context):
                    self.actions.append(action)
            else:
                self.actions.append(action)
        super(AttendanceEditor, self).setUpWidgets(self)

    def get_selected(self):
        selected = [
            {
                "user_id": k[len(self.radio_prefix):].decode("base64"),
                "attendance_type": self.request.form.get(k)
            } for k in self.request.form.keys()
            if k.startswith(self.radio_prefix) and self.request.form.get(k)
        ]
        return selected

    def process_attendance(self):
        session = Session()
        trusted = removeSecurityProxy(self.context)
        gs_id = trusted.sitting_id
        for selection in self.get_selected():
            member_id = selection.get("user_id")
            if not member_id:
                continue
            at = selection.get("attendance_type")
            if not at:
                continue
            member_id = int(member_id)
            # check existing attendance record
            query = session.query(SittingAttendance).filter(
                sql.and_(SittingAttendance.member_id == member_id,
                         SittingAttendance.sitting_id == gs_id))
            result = query.first()
            if result is not None:
                result.attendance_type = at
                session.flush()
                zope.event.notify(
                    zope.lifecycleevent.ObjectModifiedEvent(
                        result,
                        zope.lifecycleevent.Attributes(ISittingAttendance,
                                                       "attendance_type")))
            else:
                m_attendance = SittingAttendance()
                m_attendance.sitting_id = gs_id
                m_attendance.attendance_type = at
                m_attendance.member_id = member_id
                session.add(m_attendance)
                session.flush()
                zope.event.notify(
                    zope.lifecycleevent.ObjectCreatedEvent(m_attendance))
        self.status = _("Updated attendance record")

    def __call__(self):
        self.update()
        return self.render()
Ejemplo n.º 20
0
class SchedulingContextAgendaReportView(ReportView):
    result_template = ViewPageTemplateFile(
        "templates/default-report_scheduling.pt")
    display_minutes = False
    include_text = False
    note = ""
Ejemplo n.º 21
0
class MyGroupsViewlet(ViewletBase):
    name = _("My Groups")
    list_id = "my_groups"
    render = ViewPageTemplateFile("templates/workspace_group_viewlet.pt")

    def _setData(self):
        """Return the data of the query
        """
        formatter = date.getLocaleFormatter(self.request, "date", "long")
        data_list = []
        results = self.query.all()

        # if no current parliament, no data
        try:
            parliament_id = model_utils.get_current_parliament().parliament_id
        except:
            return data_list
        #
        government_id = self.__parent__.government_id
        for result in results:
            data = {}
            data["qid"] = "g_%s" % (result.group_id)
            data["subject"] = result.short_name
            data["title"] = "%s (%s)" % (result.short_name, result.type)
            data["result_item_class"] = "workflow-state-%s" % (result.status)
            _url = "/archive/browse/parliaments/obj-%s" % (parliament_id)
            if type(result) == domain.Parliament:
                data["url"] = url.set_url_context(_url)
                continue
            elif type(result) == domain.Committee:
                #data["url"] = url + "/committees/obj-" + str(result.group_id)
                data["url"] = url.set_url_context(
                    "/groups/%s/%s" % (result.parent_group.group_principal_id,
                                       result.group_principal_id))
            elif type(result) == domain.PoliticalGroup:
                data["url"] = url.set_url_context("%s/politicalgroups/obj-%s" %
                                                  (_url, result.group_id))
            elif type(result) == domain.Ministry:
                data["url"] = url.set_url_context(
                    "%s/governments/obj-%s/ministries/obj-%s" %
                    (_url, government_id, result.group_id))
            else:
                data["url"] = "#"
            data["status"] = misc.get_wf_state(result)
            data["status_date"] = formatter.format(result.status_date)
            data["owner"] = ""
            data["type"] = _(result.type)
            data["to"] = ""
            data_list.append(data)
        self._data = data_list

    def update(self):
        """refresh the query
        """
        session = Session()
        #user_id = self.__parent__.user_id
        #parliament_id = self.__parent__.context.parliament_id
        group_ids = self.__parent__.user_group_ids
        gfilter = sql.and_(domain.Group.group_id.in_(group_ids),
                           domain.Group.status == "active")
        groups = session.query(domain.Group).filter(gfilter)
        self.query = groups
        self._setData()
Ejemplo n.º 22
0
class CalendarView(BungeniBrowserView):
    """Main calendar view."""

    interface.implements(IStructuralView)

    template = ViewPageTemplateFile("templates/dhtmlxcalendar.pt")

    short_name = u"Scheduling"

    def __init__(self, context, request):
        log.debug("CalendarView.__init__: %s" % (context))
        super(CalendarView, self).__init__(ISchedulingContext(context),
                                           request)

    def __call__(self, timestamp=None):
        log.debug("CalendarView.__call__: %s" % (self.context))
        trusted = removeSecurityProxy(self.context)
        trusted.__name__ = self.__name__
        interface.alsoProvides(trusted, ILocation)
        if (IBusinessSectionLayer.providedBy(self.request)
                and isinstance(trusted, SittingContainerSchedulingContext)):
            self.url = url.absoluteURL(trusted.__parent__.__parent__,
                                       self.request)
        else:
            self.url = url.absoluteURL(trusted.__parent__, self.request)
        self.title = ISchedulingContext(self.context).label
        log.debug(debug.interfaces(self))
        log.debug(debug.location_stack(self))
        return self.render()

    def publishTraverse(self, request, name):
        traverser = component.getMultiAdapter((self.context, request),
                                              IPublishTraverse)
        return traverser.publishTraverse(request, name)

    def render(self, template=None):
        need("dhtmlxscheduler")
        need("dhtmlxscheduler-recurring")
        if template is None:
            template = self.template
        if (not checkPermission(u"bungeni.sitting.Add", self.context)) or \
            (IBusinessSectionLayer.providedBy(self.request)):
            self.edit = False
        else:
            self.edit = True
        session = Session()
        venues = session.query(domain.Venue).all()
        languages = get_all_languages()
        # !+SESSION_CLOSE(taras.sterch, july-2011) there is no need to close the
        # session. Transaction manager will take care of this. Hope it does not
        # brake anything.
        #session.close()
        self.display_language = get_default_language()
        if self.request.get("I18N_LANGUAGE"):
            self.display_language = self.request.get("I18N_LANGUAGE")
        #html is hardcoded in here because doing it in the template
        #would have been a colossal pain
        #TODO: FIX THIS
        s = '<div class="dhx_cal_ltext" style="height:90px;">'
        s += '<table>'
        s += '<tr><td>Venue</td><td><select id="select_sitting_venue">'
        for venue in venues:
            s += '<option value="' + str(
                venue.venue_id) + '">' + venue.short_name + '</option>'
        s += '</select></td></tr>'
        s += '<tr><td>Language</td><td><select id="select_sitting_lang">'
        for lang in languages:
            if lang == 'en':
                s += '<option value="' + lang + '" selected>' + lang + '</option>'
            else:
                s += '<option value="' + lang + '">' + lang + '</option>'
        s += '</select></td></tr></table></div>'
        self.sitting_details_form = s
        return template()
Ejemplo n.º 23
0
class Search(forms.common.BaseForm, ResultListing, HighlightMixin):
    """  basic content search form and results
    """
    template = ViewPageTemplateFile('templates/search.pt')
    form_fields = form.Fields(ISearch, IHighLight)

    #selection_column = columns[0]

    def setUpWidgets(self, ignore_request=False):
        # setup widgets in data entry mode not bound to context
        self.adapters = {}
        self.widgets = form.setUpDataWidgets(self.form_fields,
                                             self.prefix,
                                             self.context,
                                             self.request,
                                             ignore_request=ignore_request)

    @property
    def doc_count(self):
        return len(self._searchresults)

    def authorized(self, result):
        obj = result.object()
        defaultview = getDefaultViewName(obj, self.request)
        view = queryMultiAdapter((ProxyFactory(obj), self.request),
                                 name=defaultview)
        return canAccess(view, "__call__")

    def get_description(self, item):
        return item.description

    def get_title(self, item):
        return "%s %s" % (translate_obj(
            item.origin,
            self.request.locale.id.language).short_name, _(u"changes from"))

    def get_url(self, item):
        site = getSite()
        base_url = absoluteURL(site, self.request)
        return base_url + "/business/%ss/obj-%s" % (
            item.origin.type, item.origin.parliamentary_item_id)

    def get_user_subscriptions(self):
        """ Getting user subscribed items
        """
        session = Session()
        user = session.query(domain.User).filter(
            domain.User.login == self.request.principal.id).first()
        return user.subscriptions

    @CachedProperty
    def _searchresults(self):
        section = get_section_name()
        subqueries = []

        # Filter items allowed in current section
        for tq in ALLOWED_TYPES[section]:
            subqueries.append(self.searcher.query_field('object_type', tq))

        type_query = self.searcher.query_composite(self.searcher.OP_OR,
                                                   subqueries)

        self.query = self.searcher.query_composite(self.searcher.OP_AND, \
                                                       (self.query, type_query,))

        try:
            results = self.searcher.search(self.query, 0,
                                           self.searcher.get_doccount())
        except:
            results = []

        results = filter(self.authorized, results)

        return results

    @property
    def _results(self):
        return map(lambda x: x.object(), self._searchresults)

    @form.action(label=_(u"Search"))
    def handle_search(self, action, data):
        self.searcher = component.getUtility(interfaces.IIndexSearch)()
        search_term = data['full_text']

        if not search_term:
            self.status = _(u"Invalid Query")
            return

        # compose query
        t = time.time()
        lang = self.request.locale.getLocaleID()
        if lang == "en_US": lang = "en"
        if lang == "en_KE": lang = "en-ke"
        text_query = self.searcher.query_parse(search_term)
        lang_query = self.searcher.query_field('language', lang)
        self.query = self.searcher.query_composite(self.searcher.OP_AND, (
            text_query,
            lang_query,
        ))
        self.results = self._results
        self.search_time = time.time() - t

        # spelling suggestions
        suggestion = self.searcher.spell_correct(search_term)
        self.spelling_suggestion = (search_term != suggestion and suggestion
                                    or None)
Ejemplo n.º 24
0
class GroupSittingScheduleView(BrowserView):
    """Group-sitting scheduling view.

    This view presents a sitting and provides a user interface to
    manage the agenda.
    """

    template = ViewPageTemplateFile("templates/main.pt")
    ajax = ViewPageTemplateFile("templates/ajax.pt")

    _macros = ViewPageTemplateFile("templates/macros.pt")

    def __init__(self, context, request):
        super(GroupSittingScheduleView, self).__init__(context, request)
        self.__parent__ = context

    def __call__(self, timestamp=None):
        session = Session()
        if timestamp is None:
            # start the week on the first weekday (e.g. Monday)
            date = utils.datetimedict.fromdate(datetime.date.today())
        else:
            try:
                timestamp = float(timestamp)
            except:
                raise TypeError("Timestamp must be floating-point (got %s)" %
                                timestamp)
            date = utils.datetimedict.fromtimestamp(timestamp)
        #if misc.is_ajax_request(self.request):
        if self.request.get('headless') == 'true':
            rendered = self.render(date, template=self.ajax)
        else:
            rendered = self.render(date)
        # !+SESSION_CLOSE(taras.sterch, july-2011) there is no need to close the
        # session. Transaction manager will take care of this. Hope it does not
        # brake anything.
        #session.close()
        return rendered

    def reorder_field(self):
        if self.context.status == "draft_agenda":
            return 'planned_order'
        elif self.context.status == "draft_minutes":
            return 'real_order'
        else:
            return None

    def render(self, date, template=None):
        #need('yui-editor')
        need('yui-rte')
        need('yui-resize')
        need('yui-button')

        if template is None:
            template = self.template

        container = self.context.__parent__
        #schedule_url = self.request.getURL()
        container_url = url.absoluteURL(container, self.request)

        # determine position in container
        key = stringKey(self.context)
        keys = list(container.keys())
        pos = keys.index(key)

        links = {}
        if pos > 0:
            links['previous'] = "%s/%s/%s" % (container_url, keys[pos - 1],
                                              self.__name__)
        if pos < len(keys) - 1:
            links['next'] = "%s/%s/%s" % (container_url, keys[pos + 1],
                                          self.__name__)

        #start_date = utils.datetimedict.fromdatetime(self.context.start_date)
        #end_date = utils.datetimedict.fromdatetime(self.context.end_date)

        site_url = url.absoluteURL(getSite(), self.request)
        reorder = "reorder" if self.context.status in \
                                ["draft_agenda", "draft_minutes"] \
                            else "dont-reorder"
        return template(
            display="sitting",
            #title=_(u"$A $e, $B $Y", mapping=start_date),
            title="%s: %s - %s" %
            (self.context.group.short_name,
             self.context.start_date.strftime('%Y-%m-%d %H:%M'),
             self.context.end_date.strftime('%H:%M')),
            description=_(u"Sitting Info"),
            #            title = u"",
            #            description = u"",
            #
            links=links,
            actions=get_sitting_actions(self.context, self.request),
            items=get_sitting_items(self.context,
                                    self.request,
                                    include_actions=True),
            #categories=vocabulary.ItemScheduleCategories(self.context),
            new_category_url="%s/admin/content/categories/add?next_url=..." %
            site_url,
            status=self.context.status,
            reorder=reorder,
        )

    @property
    def macros(self):
        return self._macros.macros
Ejemplo n.º 25
0
class Many2ManyEdit(RelationTableBaseViewlet):

    selection_column = column.SelectionColumn(lambda item: str(item.id),
                                              name="selection")
    state = 'listing'
    template = ViewPageTemplateFile('templates/relation-edit.pt')

    def setUpColumns(self):
        columns = super(Many2ManyEdit, self).setUpColumns()
        columns.insert(0, self.selection_column)
        return columns

    def update(self):
        # we capture state from the last processed action, so our next action
        # becomes available.
        self.state = self.request.get("%s.state" % self.property_name,
                                      self.state)
        # our previous state when we process searches is the add state, in order
        # to process the form values for the search action, we need to have search
        # widgets setup prior to the handler invocation, so do that here..
        if self.state == 'add':
            self.form_fields = core.setUpFields(self.domain_model,
                                                mode='search')

        # if we're doing a listing prepopulate state before rendering so we
        # display empty results status, and for a delete do it eagerly so
        # we can check our condition
        if self.state in ('listing', 'delete'):
            self.results = getattr(self.context, self.property_name)

        super(Many2ManyEdit, self).update()

        # if our state changes to listing
        if not self.results and self.state == 'listing':
            self.results = getattr(self.context, self.property_name)

    def condition_search(self, action):
        return self.state == 'add'

    @form.action(u"Search", condition='condition_search')
    def handle_search(self, action, data):
        """
        search the other end point of m2m relationship for rows to
        associate.
        """
        self.state = 'search'
        d = core.constructQuery(self.form_fields, self.domain_model, data)

        context = proxy.removeSecurityProxy(self.context)

        mapper = orm.class_mapper(self.domain_model)
        instance_pkey = mapper.primary_key_from_instance
        pkey = mapper.primary_key[0]

        query = Session().query(self.domain_model)
        query = query.filter(
            rdb.not_(
                pkey.in_(
                    [ob.id for ob in getattr(context, self.property_name)])))

        if not d:
            self.results = query.all()
            return

        self.results = query.filter(*(d.values())).all()

    def condition_add(self, action):
        return self.state == 'listing'

    @form.action(u"Add", condition='condition_add')
    def handle_add(self, action, data):
        """
        sends user to search form.
        """
        self.state = 'add'
        session = Session()
        related_count = session.query(self.domain_model).count()
        if related_count > 20:
            self.form_fields = core.setUpFields(self.domain_model,
                                                mode='search')
        else:
            self.state = 'search'
            query = session.query(self.domain_model)
            context = proxy.removeSecurityProxy(self.context)

            collection = getattr(context, self.property_name)
            if collection:
                mapper = orm.class_mapper(self.domain_model)
                instance_pkey = mapper.primary_key_from_instance
                pkey = mapper.primary_key[0]
                query = query.filter(
                    rdb.not_(
                        pkey.in_([
                            instance_pkey(ob)[0]
                            for ob in getattr(context, self.property_name)
                        ])))
            self.results = query.all()

    def condition_delete(self, action):
        return self.state == 'listing' and self.results

    @form.action(u"Delete", condition='condition_delete')
    def handle_delete(self, action, data):
        """
        delete the selected items from the m2m relationship.
        """
        # reset form state
        self.state = 'listing'

        # first we need to dereference the selection column values into
        # objects to disassociate.
        values = core.getSelectedObjects(self.selection_column, self.request,
                                         self.domain_model)

        if not values:
            self.status = "No %s Selected" % (
                self.domain_model.__name__.title() + 's')
            return
        # remove objects from association
        association = getattr(self.context, self.property_name)
        for v in values:
            if v in association:
                association.remove(v)

        # pluralize properly
        if len(values) > 1:
            self.status = "%s Removed" % (self.domain_model.__name__.title() +
                                          's')
        else:
            self.status = "%s Removed" % self.domain_model.__name__.title()

    def condition_associate(self, action):
        return self.state == 'search'

    @form.action(u"Associate", condition='condition_associate')
    def handle_associate(self, action, data):
        """
        associate a search result with the context.
        """
        # reset viewlet state to listing of associated objects
        self.state = 'listing'

        # first we need to dereference the selection column values into
        # objects to associate.
        values = core.getSelectedObjects(self.selection_column, self.request,
                                         self.domain_model)

        # add objects to the association
        association = proxy.removeSecurityProxy(
            getattr(self.context, self.property_name))

        for v in values:
            if v not in association:
                association.append(v)

        # pluralize properly
        if len(values) > 1:
            self.status = "%s Associated" % (
                self.domain_model.__name__.title() + 's')
        else:
            self.status = "%s Associated" % self.domain_model.__name__.title()

        # reset selection column
        self.form_reset = True

    def condition_cancel(self, action):
        return self.state != 'listing'

    @form.action(u"Cancel", condition='condition_cancel')
    def handle_cancel(self, action, data):
        """
        cancel the current operation and go back to the view
        """
        self.state = 'listing'
Ejemplo n.º 26
0
class DhtmlxCalendarSittingsEdit(form.PageForm):
    """Form to add, edit or delete a sitting that works with
    DHTMLX scheduler"""

    #!+ CALENDAR(miano, dec-2010) Add recurrence to the model so that
    # sittings added as part of a recurrence can be modified as a part of that
    # recurrence a la google calendar.

    prefix = ""
    xml_template = ViewPageTemplateFile(
        "templates/dhtmlxcalendar_edit_form.pt")
    template_data = []

    def __init__(self, context, request):
        #dhtmlxscheduler posts the field names prefixed with the id
        #of the sitting, the code below removes the prefix and set the action to
        #be performed
        data = request.form
        for key in request.form.keys():
            t = key.partition("_")
            request.form[t[2]] = data[key]
        if "!nativeeditor_status" in request.form.keys():
            if request.form["!nativeeditor_status"] == "inserted":
                request.form["actions.insert"] = "insert"
            elif request.form["!nativeeditor_status"] == "updated":
                request.form["actions.update"] = "update"
            elif request.form["!nativeeditor_status"] == "deleted":
                request.form["actions.delete"] = "delete"
        super(DhtmlxCalendarSittingsEdit, self).__init__(context, request)

    class DhtmlxCalendarSittingsEditForm(interface.Interface):
        ids = schema.TextLine(title=u'ID',
                              description=u'Sitting ID',
                              required=False)
        start_date = schema.Datetime(
            title=_(u"Start Date and Time"),
            description=_(u"Choose a start date and time"),
            required=True)
        end_date = schema.Datetime(
            title=_(u"End Date and Time"),
            description=_(u"Choose an end date and time"),
            required=True)
        venue = schema.Choice(title=_(u"Venue"),
                              source="bungeni.vocabulary.Venues",
                              description=_(u"Venues"),
                              required=True)
        language = schema.Choice(title=_(u"Language"),
                                 default=get_default_language(),
                                 vocabulary="language_vocabulary",
                                 description=_(u'Language'),
                                 required=True)
        rec_type = schema.TextLine(title=u'Recurrence Type',
                                   required=False,
                                   description=u"A string that contains the \
                                            rules for reccurent sittings if any"
                                   )
        event_length = schema.TextLine(title=u'Event Length',
                                       required=False,
                                       description=u'Length of event')
        nativeeditor_status = schema.TextLine(title=u'editor status',
                                              required=False,
                                              description=u'Editor Status')

    form_fields = form.Fields(DhtmlxCalendarSittingsEditForm)

    def setUpWidgets(self, ignore_request=False):
        class context:
            ids = None
            start_date = None
            end_date = None
            location = None
            language = None
            venue = None
            rec_type = None
            event_length = None
            nativeeditor_status = None

        self.adapters = {self.DhtmlxCalendarSittingsEditForm: context}
        self.widgets = form.setUpEditWidgets(self.form_fields,
                                             "",
                                             self.context,
                                             self.request,
                                             adapters=self.adapters,
                                             ignore_request=ignore_request)

    def insert_sitting_failure_handler(self, action, data, errors):
        error_message = _(
            u"The following errors occured while adding a sitting")
        error_string = u""
        for error in errors:
            if error.message not in ('', None):
                error_string += error.message + "\n"
            else:
                error_string += error.__str__() + "\n"
        return "%s \n%s" % (error_message, error_string)

    # The form action strings below do not need to be translated because they are
    # not visible in the UI.
    @form.action(u"insert", failure='insert_sitting_failure_handler')
    def handle_insert(self, action, data):
        session = Session()
        self.template_data = []
        trusted = removeSecurityProxy(ISchedulingContext(self.context))
        if ("rec_type" in data.keys()) and (data["rec_type"] is not None):
            # !+ DATETIME(miano, dec-2010) the datetime widget above returns
            # aware datetime objects while the current database setup only
            # supports naive objects. The lines below(and in subsequent actions)
            # convert them to naive datetimes
            recurrence_start_date = data["start_date"].replace(tzinfo=None)
            recurrence_end_date = data["end_date"].replace(tzinfo=None)
            length = data["event_length"]
            sitting_length = timedelta(seconds=int(length))
            #
            # Check the end date of the recurrence
            # The end date is set to be the end date of the current group
            # or one year from the present date whichever is sooner.

            group = trusted.get_group()
            # If group is none then there is a big problem
            assert group is not None
            year = timedelta(days=365)
            now = datetime.datetime.now()
            if ((group.end_date is not None) and
                ((now + year) < group.end_date)) or (group.end_date is None):
                end = now + year
            else:
                end = group.end_date
            if recurrence_end_date > end:
                recurrence_end_date = end
            dates = utils.generate_recurrence_dates(recurrence_start_date,
                                                    recurrence_end_date,
                                                    data["rec_type"])
            recurrent_sittings = []
            for date in dates:
                sitting = domain.GroupSitting()
                sitting.group_id = trusted.group_id
                sitting.start_date = date
                sitting.end_date = date + sitting_length
                sitting.language = data["language"]
                sitting.venue_id = data["venue"]
                session.add(sitting)
                recurrent_sittings.append(sitting)
            session.commit()
            for s in recurrent_sittings:
                notify(ObjectCreatedEvent(s))
                self.template_data.append({
                    "group_sitting_id": s.group_sitting_id,
                    "action": "inserted",
                    "ids": data["ids"]
                })
            self.request.response.setHeader('Content-type', 'text/xml')
            return self.xml_template()
        else:
            sitting = domain.GroupSitting()
            sitting.start_date = data["start_date"].replace(tzinfo=None)
            sitting.end_date = data["end_date"].replace(tzinfo=None)
            sitting.group_id = trusted.group_id
            sitting.language = data["language"]
            sitting.venue_id = data["venue"]
            session.add(sitting)
            session.commit()
            notify(ObjectCreatedEvent(sitting))
            self.template_data.append({
                "group_sitting_id": sitting.group_sitting_id,
                "action": "inserted",
                "ids": data["ids"]
            })
            self.request.response.setHeader('Content-type', 'text/xml')
            return self.xml_template()

    def update_sitting_failure_handler(self, action, data, errors):
        error_string = u""
        for error in errors:
            if error.message not in ('', None):
                error_string += error.message + "\n"
            else:
                error_string += error.__str__() + "\n"
        return "%s \n%s" % (error_message, error_string)

    @form.action(u"update", failure='update_sitting_failure_handler')
    def handle_update(self, action, data):
        session = Session()
        self.template_data = []
        sitting = domain.GroupSitting()
        sitting = session.query(domain.GroupSitting).get(data["ids"])
        sitting.start_date = data["start_date"].replace(tzinfo=None)
        sitting.end_date = data["end_date"].replace(tzinfo=None)
        if "language" in data.keys():
            sitting.language = data["language"]
        if "venue" in data.keys():
            sitting.venue_id = data["venue"]
        # set extra data needed by template
        session.update(sitting)
        notify(ObjectModifiedEvent(sitting))
        self.template_data.append({
            "group_sitting_id": sitting.group_sitting_id,
            "action": "inserted",
            "ids": data["ids"]
        })
        session.commit()
        self.request.response.setHeader('Content-type', 'text/xml')
        return self.xml_template()

    def delete_sitting_failure_handler(self, action, data, errors):
        error_string = u""
        for error in errors:
            if error.message not in ('', None):
                error_string += error.message + "\n"
            else:
                error_string += error.__str__() + "\n"
        return "%s \n%s" % (error_message, error_string)

    @form.action(u"delete", failure='delete_sitting_failure_handler')
    def handle_delete(self, action, data):
        session = Session()
        self.template_data = []
        sitting = session.query(domain.GroupSitting).get(data["ids"])
        # set extra data needed by template
        self.template_data = []
        if sitting is not None:
            self.request.response.setHeader('Content-type', 'text/xml')
            self.template_data.append({
                "group_sitting_id": sitting.group_sitting_id,
                "action": "deleted",
                "ids": data["ids"]
            })
            session.delete(sitting)
            session.commit()
            return self.xml_template()
Ejemplo n.º 27
0
from zope import interface
from zope.viewlet import viewlet, manager
from zope.formlib import form
from zope.formlib.namedtemplate import NamedTemplate
from zope.formlib.namedtemplate import NamedTemplateImplementation
from zope.app.pagetemplate import ViewPageTemplateFile
from i18n import _
import core
import content

ContentViewletManagerTemplate = NamedTemplateImplementation(
    ViewPageTemplateFile('templates/content-manager.pt'))


class FormViewlet(form.SubPageForm, viewlet.ViewletBase):

    __init__ = viewlet.ViewletBase.__init__


class AddFormViewlet(content.AddFormBase, FormViewlet):
    """
    add form viewlet
    """
    __init__ = FormViewlet.__init__


class EditFormViewlet(form.SubPageEditForm, viewlet.ViewletBase):

    __init__ = viewlet.ViewletBase.__init__

    adapters = None
Ejemplo n.º 28
0
class DhtmlxCalendarSittings(BrowserView):
    """This view returns xml of the sittings for the week and group 
    requested in a format acceptable by DHTMLX scheduler"""
    interface.implements(IStructuralView)

    template = ViewPageTemplateFile('templates/dhtmlxcalendarxml.pt')

    def __init__(self, context, request):
        super(DhtmlxCalendarSittings,
              self).__init__(ISchedulingContext(context), request)
        self.context.__name__ = self.__name__
        interface.alsoProvides(self.context, ILocation)
        interface.alsoProvides(self.context, IDCDescriptiveProperties)
        self.__parent__ = context

    def __call__(self):
        try:
            date = self.request.get('from')
            dateobj = datetime.datetime(*time.strptime(date, "%Y-%m-%d")[0:5])
            start_date = utils.datetimedict.fromdate(dateobj)
        except:
            start_date = None

        try:
            date = self.request.get('to')
            dateobj = datetime.datetime(*time.strptime(date, "%Y-%m-%d")[0:5])
            end_date = utils.datetimedict.fromdate(dateobj)
        except:
            end_date = None

        if start_date is None:
            start_date = utils.datetimedict.fromdate(datetime.date.today())
            days = tuple(start_date + timedelta(days=d) for d in range(7))
            end_date = days[-1]
        elif end_date is None:
            start_date = utils.datetimedict.fromdate(datetime.date.today())
            days = tuple(start_date + timedelta(days=d) for d in range(7))
            end_date = days[-1]
        sittings = self.context.get_sittings(
            start_date,
            end_date,
        )
        self.sittings = []
        for sitting in sittings.values():
            if checkPermission("zope.View", sitting):
                trusted = removeSecurityProxy(sitting)
                if trusted.venue:
                    trusted.text = "<![CDATA[" \
                        "<b>Venue:</b></br>%s</br><b>Status:</b></br>%s" \
                        "]]>" % (trusted.venue.short_name, trusted.status)
                else:
                    trusted.text = "<![CDATA[<b>Status:</b></br>%s]]>" % (
                        trusted.status)
                # !+PRESENTATION_CODE(mr, mar-2011) should be in templates.
                self.sittings.append(trusted)
        self.request.response.setHeader('Content-type', 'text/xml')
        return self.render()
        #return super(DhtmlxCalendarSittings, self).__call__()

    def render(self, template=None):
        return self.template()
Ejemplo n.º 29
0
class WorkflowChangeStateView(WorkflowView):
    """This gets called on selection of a transition from the menu i.e. NOT:
    a) when clicking on one of the transition buttons in the workflow form.
    b) when clicking Add of an object (automatic transitions).
    """

    ajax_template = ViewPageTemplateFile("templates/workflow-ajax.pt")

    def __init__(self, context, request):
        self.context = context
        self.request = request
        zope.interface.alsoProvides(self.request, IConfirmWorkflowChangeLayer)
        super(WorkflowChangeStateView, self).__init__(context, request)

    def __call__(self, transition_id=None, headless=False):
        # parameters coming in via URL querystring or post vars !
        method = self.request["REQUEST_METHOD"]
        # !+ALWAYS_POST(mr, sep-2011) requests coming from link clicks (GETs)
        # from the bungeni Web UI seem to always be intercepted and switched
        # into POSTs.
        workflow = interfaces.IWorkflow(self.context)

        require_confirmation = True
        if transition_id is not None:
            self.update(transition_id)
            require_confirmation = workflow.get_transition(
                transition_id).require_confirmation
        else:
            self.update()

        if (IBungeniParliamentaryContent.providedBy(self.context)
                and get_mask(self.context) == "manual"
                and not self.context.registry_number):
            require_confirmation = True

        if (not require_confirmation and method == "POST"):
            actions = bindTransitions(self.action_viewlet, (transition_id, ),
                                      workflow)
            assert len(actions) == 1
            # execute action
            # !+ should pass self.request.form as data? e.g. value is:
            # {u"next_url": u"...", u"transition": u"submit_response"}
            result = actions[0].success({})
            # !+UNUSED(mr, jun-2011) this result is never used!

        if headless:
            actions = get_actions("context_workflow", self.context,
                                  self.request)
            state_title = workflow.get_state(self.context.status).title
            result = self.ajax_template(actions=actions,
                                        state_title=state_title)
            if require_confirmation:
                self.request.response.setStatus(403)
            else:
                self.request.response.setStatus(200)
                self.request.response.setResult(result)
                self.request.response.setHeader("Content-Type", "text/xml")
            return result

        template = self.template()
        return template
Ejemplo n.º 30
0
class ReportView(form.PageForm):
    main_result_template = ViewPageTemplateFile("templates/main_reports.pt")
    result_template = ViewPageTemplateFile("templates/reports.pt")
    display_minutes = None

    def __init__(self, context, request):
        super(ReportView, self).__init__(context, request)

    class IReportForm(interface.Interface):
        short_name = schema.Choice(
            title=_(u"Document Type"),
            description=_(u"Type of report to be produced"),
            values=[
                "Order of the day", "Weekly Business", "Questions of the week"
            ],
            required=True)
        date = schema.Date(
            title=_(u"Date"),
            description=_(u"Choose a starting date for this report"),
            required=True)
        item_types = schema.List(
            title=u"Items to include",
            required=False,
            value_type=schema.Choice(
                vocabulary="bungeni.vocabulary.AvailableItems"))
        bills_options = schema.List(
            title=u"Bill options",
            required=False,
            value_type=schema.Choice(
                vocabulary="bungeni.vocabulary.BillOptions"))
        agenda_items_options = schema.List(
            title=u"Agenda options",
            required=False,
            value_type=schema.Choice(
                vocabulary="bungeni.vocabulary.AgendaOptions"))
        motions_options = schema.List(
            title=u"Motion options",
            required=False,
            value_type=schema.Choice(
                vocabulary="bungeni.vocabulary.MotionOptions"))
        questions_options = schema.List(
            title=u"Question options",
            required=False,
            value_type=schema.Choice(
                vocabulary="bungeni.vocabulary.QuestionOptions"))
        tabled_documents_options = schema.List(
            title=u"Tabled Document options",
            required=False,
            value_type=schema.Choice(
                vocabulary="bungeni.vocabulary.TabledDocumentOptions"))
        note = schema.TextLine(
            title=u"Note",
            required=False,
            description=u"Optional note regarding this report")

    template = namedtemplate.NamedTemplate("alchemist.form")
    form_fields = form.Fields(IReportForm)
    form_fields["item_types"].custom_widget = horizontalMultiCheckBoxWidget
    form_fields["bills_options"].custom_widget = verticalMultiCheckBoxWidget
    form_fields[
        "agenda_items_options"].custom_widget = verticalMultiCheckBoxWidget
    form_fields["motions_options"].custom_widget = verticalMultiCheckBoxWidget
    form_fields[
        "questions_options"].custom_widget = verticalMultiCheckBoxWidget
    form_fields[
        "tabled_documents_options"].custom_widget = verticalMultiCheckBoxWidget
    form_fields["date"].custom_widget = SelectDateWidget

    def setUpWidgets(self, ignore_request=False):
        class context:
            item_types = "Bills"
            bills_options = "Title"
            agenda_items_options = "Title"
            questions_options = "Title"
            motions_options = "Title"
            tabled_documents_options = "Title"
            note = None
            date = None
            short_name = "Order of the day"

        self.adapters = {self.IReportForm: context}
        self.widgets = form.setUpEditWidgets(self.form_fields,
                                             self.prefix,
                                             self.context,
                                             self.request,
                                             adapters=self.adapters,
                                             ignore_request=ignore_request)

    def update(self):
        super(ReportView, self).update()
        forms.common.set_widget_errors(self.widgets, self.errors)

    def get_end_date(self, start_date, time_span):
        if time_span is TIME_SPAN.daily:
            return start_date + timedelta(days=1)
        elif time_span is TIME_SPAN.weekly:
            return start_date + timedelta(weeks=1)
        raise RuntimeError("Unknown time span: %s" % time_span)

    def time_span(self, data):
        if "short_name" in data:
            if data["short_name"] == "Order of the day":
                return TIME_SPAN.daily
            elif data["short_name"] == "Proceedings of the day":
                return TIME_SPAN.daily
            elif data["short_name"] == "Weekly Business":
                return TIME_SPAN.weekly
            elif data["short_name"] == "Questions of the week":
                return TIME_SPAN.weekly
        else:
            return TIME_SPAN.daily

    def validate(self, action, data):
        errors = super(ReportView, self).validate(action, data)
        time_span = self.time_span(data)
        if IGroupSitting.providedBy(self.context):
            if not self.context.items:
                errors.append(
                    interface.Invalid(
                        _(u"The sitting has no scheduled items")))
        else:
            start_date = data["date"] if "date" in data else \
                                                datetime.datetime.today().date()
            end_date = self.get_end_date(start_date, time_span)
            try:
                ctx = ISchedulingContext(self.context)
            except:
                errors.append(
                    interface.Invalid(
                        _(u"You are trying to generate a report "
                          "outside scheduling")))
            sittings = ctx.get_sittings(start_date, end_date).values()
            if not sittings:
                errors.append(
                    interface.Invalid(
                        _(u"The period selected has no sittings"), "date"))

            parliament = queries.get_parliament_by_date_range(
                start_date, end_date)
            if parliament is None:
                errors.append(
                    interface.Invalid(
                        _(u"A parliament must be active in the period"),
                        "date"))
        return errors

    @form.action(_(u"Preview"))
    def handle_preview(self, action, data):
        self.process_form(data)
        self.save_link = url.absoluteURL(self.context,
                                         self.request) + "/save-report"
        self.body_text = self.result_template()
        return self.main_result_template()

    def process_form(self, data):
        class optionsobj(object):
            """Object that holds all the options."""

        self.options = optionsobj()
        if not hasattr(self, "short_name"):
            if "short_name" in data:
                self.short_name = data["short_name"]
        self.sittings = []
        if IGroupSitting.providedBy(self.context):
            trusted = removeSecurityProxy(self.context)
            order = "real_order" if self.display_minutes else "planned_order"
            trusted.item_schedule.sort(key=operator.attrgetter(order))
            self.sittings.append(trusted)
            self.start_date = self.context.start_date
            self.end_date = self.get_end_date(self.start_date,
                                              self.time_span(data))
        else:
            self.start_date = data["date"] if "date" in data else \
                                                datetime.datetime.today().date()
            self.end_date = self.get_end_date(self.start_date,
                                              self.time_span(data))
            sittings = ISchedulingContext(self.context).get_sittings(
                self.start_date, self.end_date).values()
            self.sittings = map(removeSecurityProxy, sittings)
        self.ids = ""
        for s in self.sittings:
            self.ids += str(s.group_sitting_id) + ","

        def cleanup(string):
            return string.lower().replace(" ", "_")

        for item_type in data["item_types"]:
            itemtype = cleanup(item_type)
            setattr(self.options, itemtype, True)
            for option in data[itemtype + "_options"]:
                setattr(self.options, cleanup(itemtype + "_" + option), True)
        if self.display_minutes:
            self.link = url.absoluteURL(self.context, self.request) \
                                                + "/votes-and-proceedings"
        else:
            self.link = url.absoluteURL(self.context, self.request) + "/agenda"
        try:
            self.group = self.context.group
        except:
            self.group = ISchedulingContext(self.context).get_group()
Ejemplo n.º 31
0
class BungeniAttributeDisplay(DynamicFields, form.SubPageDisplayForm,
                              browser.BungeniViewlet):
    """bungeni.subform.manager
    """
    # the instance of the ViewProvideViewletManager
    #provide = z3evoque.ViewProvideViewletManager(
    #    default_provider_name="bungeni.subform.manager")
    #render = z3evoque.ViewTemplateFile("form.html#display")
    render = ViewPageTemplateFile("templates/display-form.pt")

    mode = "view"
    form_name = _(u"General")
    view_id = "display-item"
    has_data = True
    adapters = None

    def get_note(self):
        """Return Notes if supplied by context.
        """
        context = removeSecurityProxy(self.context)
        if getattr(context, "note", False):
            return context.note

    def setupActions(self):
        return  # !+ ??
        wfc = interfaces.IWorkflowController(self.context, None)
        if wfc is not None:
            transitions = wfc.getManualTransitionIds()
            self.actions = tuple(
                bindTransitions(self, transitions, wfc.workflow))

    def setUpWidgets(self, ignore_request=False):
        languages = get_all_languages()
        self.form_fields = filterFields(self.context, self.form_fields)

        #do not display empty form fields
        omit_names = []
        for f in self.form_fields:
            val = getattr(self.context, f.__name__)
            if val is None:
                omit_names.append(f.__name__)
        self.form_fields = self.form_fields.omit(*omit_names)
        context = self.context
        if ITranslatable.providedBy(self.context):
            lang = self.request.locale.getLocaleID()
            try:
                translation = get_translation_for(self.context, lang)
            except:
                translation = []
            if (not translation and getattr(self.context, "language", None)
                    and getattr(self.context, "language", None) != lang):
                supported_lang = languages.get(lang)
                if supported_lang:
                    langname = supported_lang.get("native", None)
                    if langname == None:
                        langname = supported_lang.get("name")
                    self.status = translate(
                        _(u"This content is not yet translated into" +\
                            " $language",
                            mapping={"language": langname}),
                        domain="bungeni",
                        context=self.request
                    )
            context = copy(removeSecurityProxy(self.context))
            for field_translation in translation:
                setattr(context, field_translation.field_name,
                        field_translation.field_text)
        self.widgets = form.setUpEditWidgets(self.form_fields,
                                             "",
                                             context,
                                             self.request,
                                             adapters=self.adapters,
                                             for_display=True,
                                             ignore_request=ignore_request)

    def update(self):
        self.setupActions()
        #super(BungeniAttributeDisplay, self).update()
        #super(DynamicFields, self).update()
        DynamicFields.update(self)
        self.setupActions()  # after we transition we have different actions
        try:
            self.wf_status = interfaces.IStateController(
                removeSecurityProxy(self.context)).get_status()
        except:
            pass

    @property
    def form_name(self):
        parent = self.context.__parent__
        #DESCRIPTOR(miano, June 2011) This originally first checked the parent's
        #descriptor then the item's descriptor. Why???
        #This was causing an error in the display pages of items in the
        #workspace since the workspace containers have no descriptor
        #defined for them.
        if IAlchemistContent.providedBy(self.context):
            descriptor = utils.get_descriptor(self.context.__class__)
        elif IAlchemistContainer.providedBy(parent):
            descriptor = utils.get_descriptor(parent.domain_model)
        else:
            raise RuntimeError("Unsupported object: %s." % repr(self.context))

        if descriptor:
            name = getattr(descriptor, "display_name", None)

        if name is None:
            name = self.context.__class__.__name__

        return name

    # !+RENAME get_object_class_name
    def getObjectClass(self):
        """Get the context object's class name. Called from the view template.
        """
        return self.context.__class__.__name__

    # !+ from ui.forms.common.BaseForm -- merge these 2 base classes?
    @property
    def invariantErrors(self):
        """ () -> [error:zope.interface.Invalid]
        """
        errors = []
        for error in self.errors:
            if isinstance(error, interface.Invalid):
                errors.append(error)
        return errors

    @property
    def invariantMessages(self):
        """ () -> [message:str]
        Called from the form.html#display template.
        """
        return filter(None, [error.message for error in self.invariantErrors])
Ejemplo n.º 32
0
 def _write_body(self):
     response = self.request.response
     body = ViewPageTemplateFile('templates/event_vcal.pt')(self)
     response.setHeader('Content-Type', 'text/vCal')
     response.setHeader('Content-Disposition', 'filename=cmf.vcs')
     response.write(body.encode("UTF-8"))