コード例 #1
0
ファイル: data.py プロジェクト: BenoitTalbot/bungeni-portal
 def group_items(self):
     """Prepare and remember item aggregations, for convenient access from 
     within templates. Grouping aggregations are keyed on the *pluralized* 
     name of:
     a) the item's type key
     b) (if different to type key) its custom archetype key 
     c) (if different to custom archetype key) its system archetype key.
     Example, an item of type "assembly_question" (that has custom 
     archetype "question", and system archetype "doc") will be included in
     the following aggregation list attributes on this instance:
     a) es.assembly_questions
     b) es.questions
     c) es.docs
     """
     for scheduled in self.sitting.item_schedule:
         type_key = scheduled.item.type
         ti = capi.get_type_info(type_key)
         grouping_type_keys = [type_key]
         for tk in (ti.custom_archetype_key, ti.sys_archetype_key):
             if tk is not None and tk not in grouping_type_keys:
                 grouping_type_keys.append(tk)
         for tk in grouping_type_keys:
             grouping_name = naming.plural(tk)
             log.debug(
                 "[Reports] Adding %s to grouping %r in expanded sitting %s", 
                     scheduled, grouping_name, self)
             self.grouped.setdefault(grouping_name, []).append(scheduled.item)
コード例 #2
0
 def __str__(self):
     doc = removeSecurityProxy(self.context)
     base_url = ui_utils.url.absoluteURL(getSite(), self.request)
     return "%s/admin/content/chambers/obj-%s/%s/%s" % (
         base_url, doc.chamber_id,
         naming.plural(naming.polymorphic_identity(
             type(doc))), stringKey(doc))
コード例 #3
0
ファイル: data.py プロジェクト: bungeni-org/bungeni.main
 def group_items(self):
     """Prepare and remember item aggregations, for convenient access from 
     within templates. Grouping aggregations are keyed on the *pluralized* 
     name of:
     a) the item's type key
     b) (if different to type key) its custom archetype key 
     c) (if different to custom archetype key) its system archetype key.
     Example, an item of type "assembly_question" (that has custom 
     archetype "question", and system archetype "doc") will be included in
     the following aggregation list attributes on this instance:
     a) es.assembly_questions
     b) es.questions
     c) es.docs
     """
     for scheduled in self.sitting.item_schedule:
         type_key = scheduled.item.type
         ti = capi.get_type_info(type_key)
         grouping_type_keys = [type_key]
         for tk in (ti.custom_archetype_key, ti.sys_archetype_key):
             if tk is not None and tk not in grouping_type_keys:
                 grouping_type_keys.append(tk)
         for tk in grouping_type_keys:
             grouping_name = naming.plural(tk)
             log.debug(
                 "[Reports] Adding %s to grouping %r in expanded sitting %s",
                 scheduled, grouping_name, self)
             self.grouped.setdefault(grouping_name,
                                     []).append(scheduled.item)
コード例 #4
0
ファイル: menu.py プロジェクト: mohalfaki/bungeni-portal
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     try:
         items = unproxied.items()
     except AttributeError:
         items = []
         for key, info in capi.iter_type_info():
             if IScheduleContent.implementedBy(info.domain_model):
                 name = naming.plural(key)
                 if hasattr(unproxied, name):
                     items.append((name, getattr(unproxied, name)))
     for key, item in items:
         if not IAlchemistContainer.providedBy(item): continue
         if not IScheduleContent.implementedBy(item.domain_model): continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key
             or naming.type_key("model_name", item.domain_model.__name__))
         if not checkPermission(permission, context): continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(
             dict(title=_title,
                  description=_title,
                  action=url.absoluteURL(item, request),
                  selected=False,
                  icon=None,
                  extra={},
                  submenu=None))
     return results
コード例 #5
0
ファイル: reports.py プロジェクト: gelie/bungeni_src
 def buildContext(self):
     if IWorkspaceScheduling.providedBy(self.request):
         self.buildSittings()
     elif IWorkspaceUnderConsideration.providedBy(self.context):
         default_filters = {
             'sort_dir':
             u'asc',
             'filter_status_date':
             u'%s->%s' %
             (self.start_date.isoformat(), self.end_date.isoformat()),
             'sort_on':
             u'status_date',
             'filter_type':
             u'',
         }
         doc_container = self.context.publishTraverse(
             self.request, "documents")
         for type_key, ti in capi.iter_type_info():
             workflow = ti.workflow
             if workflow and workflow.has_feature("workspace"):
                 #add generators of various doctypes
                 container_name = naming.plural(type_key)
                 filters = dict(default_filters)
                 filters['filter_type'] = type_key
                 setattr(self, container_name,
                         doc_container.query(**filters)[0])
コード例 #6
0
 def __str__(self):
     doc = removeSecurityProxy(self.context)
     base_url = ui_utils.url.absoluteURL(getSite(), self.request)        
     return "%s/admin/content/chambers/obj-%s/%s/%s" % (
                 base_url, 
                 doc.chamber_id, 
                 naming.plural(naming.polymorphic_identity(type(doc))), 
                 stringKey(doc))
コード例 #7
0
def parse_container(container_elem):
    target_type_key, rel_attr_name = xas(container_elem, "match").split(".", 1)
    return (
        xas(container_elem, "name") or naming.plural(target_type_key), 
        target_type_key, 
        rel_attr_name, 
        xas(container_elem, "indirect_key")
    )
コード例 #8
0
 def __str__(self):
     member = removeSecurityProxy(self.context)
     base_url = ui_utils.url.absoluteURL(getSite(), self.request)        
     return "%s/%s/%s/%s" % (
         base_url,
         super(GroupMemberAdminAbsoluteURLView, self)._group_url_path(member.group),
         naming.plural(naming.polymorphic_identity(type(member))),
         stringKey(member))
コード例 #9
0
 def __str__(self):
     member = removeSecurityProxy(self.context)
     base_url = ui_utils.url.absoluteURL(getSite(), self.request)
     return "%s/%s/%s/%s" % (
         base_url, super(GroupMemberAdminAbsoluteURLView,
                         self)._group_url_path(member.group),
         naming.plural(naming.polymorphic_identity(
             type(member))), stringKey(member))
コード例 #10
0
ファイル: localization.py プロジェクト: gelie/bungeni_src
def parse_container(container_elem):
    target_type_key, rel_attr_name = xas(container_elem, "match").split(".", 1)
    return (
        xas(container_elem, "name") or naming.plural(target_type_key), 
        target_type_key, 
        rel_attr_name, 
        xas(container_elem, "indirect_key")
    )
コード例 #11
0
 def decorate_ui(self, model):
     # container property per enabled event type
     for event_type_key in self.get_param("types"):
         if capi.has_type_info(event_type_key):
             container_property_name = naming.plural(event_type_key)
             add_info_container_to_descriptor(model, container_property_name, event_type_key, "head_id")
         else:
             log.warn("IGNORING feature %r ref to disabled type %r", self.name, event_type_key)
コード例 #12
0
 def decorate_ui(self, model):
     # container property per enabled event type
     for event_type_key in self.get_param("types"):
         if capi.has_type_info(event_type_key):
             container_property_name = naming.plural(event_type_key)
             add_info_container_to_descriptor(model, container_property_name, event_type_key, "head_id")
         else:
             log.warn("IGNORING feature %r ref to disabled type %r", 
                 self.name, event_type_key)
コード例 #13
0
 def _group_url_path(self, group):
     url_comps = []
     group = removeSecurityProxy(group)
     while group:
         url_comps.insert(0, "%s/%s" % (
                 naming.plural(naming.polymorphic_identity(type(group))),
                 stringKey(group)))
         group = removeSecurityProxy(group.parent_group)
     return "/".join(url_comps)
コード例 #14
0
 def _group_url_path(self, group):
     url_comps = []
     group = removeSecurityProxy(group)
     while group:
         url_comps.insert(
             0, "%s/%s" %
             (naming.plural(naming.polymorphic_identity(
                 type(group))), stringKey(group)))
         group = removeSecurityProxy(group.parent_group)
     return "/".join(url_comps)
コード例 #15
0
 def decorate_ui(self, model):
     add_info_container_to_descriptor(model, "sittings", "sitting", "group_id")
     add_info_container_to_descriptor(model, "headings", "heading", "group_id")
     add_info_container_to_descriptor(model, "editorial_notes", "editorial_note", "group_id")
     # add_info_container_to_descriptor(model, "agenda_items", "agenda_item", "group_id")
     # container property per enabled calendar_doc_type
     for calendar_doc_type_key in self.get_param("calendar_doc_types"):
         if capi.has_type_info(calendar_doc_type_key):
             container_property_name = naming.plural(calendar_doc_type_key)
             add_info_container_to_descriptor(model, container_property_name, calendar_doc_type_key, "group_id")
         else:
             log.warn("IGNORING feature %r ref to disabled type %r", self.name, calendar_doc_type_key)
コード例 #16
0
def child(context, type_key):
    """Get the child document of the specified type. 
    
    !+ assumes only one; if more than one, glazes over the issue and just takes 
    the "latest", approximately; if None returns None.
    """
    container_property_name = naming.plural(type_key)
    container = getattr(context, container_property_name)
    try:
        return sorted(container.values())[-1]
    except IndexError:
        return None
コード例 #17
0
 def decorate_ui(self, model):
     add_info_container_to_descriptor(model, "sittings", "sitting", "group_id")
     add_info_container_to_descriptor(model, "headings", "heading", "group_id")
     add_info_container_to_descriptor(model, "editorial_notes", "editorial_note", "group_id")
     #add_info_container_to_descriptor(model, "agenda_items", "agenda_item", "group_id")
     # container property per enabled calendar_doc_type
     for calendar_doc_type_key in self.get_param("calendar_doc_types"):
         if capi.has_type_info(calendar_doc_type_key):
             container_property_name = naming.plural(calendar_doc_type_key)
             add_info_container_to_descriptor(model, 
                 container_property_name, calendar_doc_type_key, "group_id")
         else:
             log.warn("IGNORING feature %r ref to disabled type %r", 
                 self.name, calendar_doc_type_key)
コード例 #18
0
 def build_context(self):
     default_filters = {
         "sort_dir": u"asc", 
         "filter_status_date": u"%s->%s" % (
             self.start_date.isoformat(), self.end_date.isoformat()
         ), 
         "sort_on": u"status_date", 
         "filter_type": u"",
     }
     doc_container = self.context.publishTraverse(self.request, "documents")
     for type_key, ti in capi.iter_type_info():
         workflow = ti.workflow
         if workflow and workflow.has_feature("workspace"):
             # add generators of various doctypes
             container_name = naming.plural(type_key)
             filters = dict(default_filters)
             filters["filter_type"] = type_key
             setattr(self, container_name, doc_container.query(**filters)[0])
コード例 #19
0
ファイル: menu.py プロジェクト: BenoitTalbot/bungeni-portal
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     items = []
     for key, info in capi.iter_type_info():
         if IScheduleContent.implementedBy(info.domain_model):
             name = naming.plural(key)
             traverser = component.getMultiAdapter((unproxied, request),
                 IPublishTraverse)
             try:
                 item = traverser.publishTraverse(request, name)
                 items.append((name, item))
             except NotFound:
                 continue
     for key, item in items:
         if not IAlchemistContainer.providedBy(item):
             continue
         if not IScheduleContent.implementedBy(item.domain_model):
             continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key or 
             naming.type_key("model_name", item.domain_model.__name__)
         )
         if not checkPermission(permission, context):
             continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(dict(
             title=_title,
             description=_title,
             action = url.absoluteURL(item, request),
             selected=False,
             icon=None,
             extra={"id": "nav_calendar_content_%s" % key},
             submenu=None,
         ))
     return results
コード例 #20
0
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     items = []
     for key, info in capi.iter_type_info():
         if IScheduleContent.implementedBy(info.domain_model):
             name = naming.plural(key)
             traverser = component.getMultiAdapter((unproxied, request),
                                                   IPublishTraverse)
             try:
                 item = traverser.publishTraverse(request, name)
                 items.append((name, item))
             except NotFound:
                 continue
     for key, item in items:
         if not IAlchemistContainer.providedBy(item):
             continue
         if not IScheduleContent.implementedBy(item.domain_model):
             continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key
             or naming.type_key("model_name", item.domain_model.__name__))
         if not checkPermission(permission, context):
             continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(
             dict(
                 title=_title,
                 description=_title,
                 action=url.absoluteURL(item, request),
                 selected=False,
                 icon=None,
                 extra={"id": "nav_calendar_content_%s" % key},
                 submenu=None,
             ))
     return results
コード例 #21
0
ファイル: reports.py プロジェクト: bungeni-org/bungeni.main
 def build_context(self):
     default_filters = {
         "sort_dir":
         u"asc",
         "filter_status_date":
         u"%s->%s" %
         (self.start_date.isoformat(), self.end_date.isoformat()),
         "sort_on":
         u"status_date",
         "filter_type":
         u"",
     }
     doc_container = self.context.publishTraverse(self.request, "documents")
     for type_key, ti in capi.iter_type_info():
         workflow = ti.workflow
         if workflow and workflow.has_feature("workspace"):
             # add generators of various doctypes
             container_name = naming.plural(type_key)
             filters = dict(default_filters)
             filters["filter_type"] = type_key
             setattr(self, container_name,
                     doc_container.query(**filters)[0])
コード例 #22
0
def feature_event(kls, feature):
    """Decorator for domain types to support "event" feature.
    For Doc types (other than Event itself).
    """
    # !+ feature "descriptor/processing/validation", move elsewhere?
    # parameter "types":
    # - may "allow" multiple event types
    # - if none specified, "event" is assumed as the default.
    feature.params["types"] = feature.params.get("types", "event").split()
    
    # domain.Event itself may NOT support events
    assert not interfaces.IEvent.implementedBy(kls)
    interface.classImplements(kls, interfaces.IFeatureEvent)
    
    # container property per enabled event type
    for event_type_key in feature.params["types"]:
        if capi.has_type_info(event_type_key):
            container_property_name = naming.plural(event_type_key)
            container_class_name = naming.container_class_name(event_type_key)
            add_container_property_to_model(kls, container_property_name,
                "bungeni.models.domain.%s" % (container_class_name), "head_id")
        else:
            log.warn('IGNORING feature "event" ref to disabled type %r', event_type_key)
コード例 #23
0
ファイル: menu.py プロジェクト: BenoitTalbot/bungeni-portal
 def getMenuItems(self, context, request):
     results = []
     unproxied = proxy.removeSecurityProxy(context.__parent__)
     try:
         items = unproxied.items()
     except AttributeError:
         items = []
         for key, info in capi.iter_type_info():
             if IScheduleContent.implementedBy(info.domain_model):
                 name = naming.plural(key)
                 if hasattr(unproxied, name):
                     items.append((name, getattr(unproxied, name)))
     for key, item in items:
         if not IAlchemistContainer.providedBy(item): continue
         if not IScheduleContent.implementedBy(item.domain_model): continue
         type_info = capi.get_type_info(item.domain_model)
         permission = "bungeni.%s.Add" % (
             type_info.workflow_key or 
             naming.type_key("model_name", item.domain_model.__name__)
         )
         if not checkPermission(permission, context): continue
         dc_adapter = IDCDescriptiveProperties(item, None)
         if dc_adapter:
             _title = dc_adapter.title
         else:
             _title = getattr(item, "title", "Unknown")
         results.append(dict(
             title=_title,
             description=_title,
             action = url.absoluteURL(item, request),
             selected=False,
             icon=None,
             extra={},
             submenu=None
             
         ))
     return results
コード例 #24
0
ファイル: reports.py プロジェクト: gelie/bungeni_src
 def buildContext(self):
     if IWorkspaceScheduling.providedBy(self.request):
         self.buildSittings()
     elif IWorkspaceUnderConsideration.providedBy(self.context):
         default_filters = {
             'sort_dir': u'asc', 
             'filter_status_date': u'%s->%s' %(
                 self.start_date.isoformat(), self.end_date.isoformat()
             ), 
             'sort_on': u'status_date', 
             'filter_type': u'',
         }
         doc_container = self.context.publishTraverse(self.request,
             "documents")
         for type_key, ti in capi.iter_type_info():
             workflow = ti.workflow
             if workflow and workflow.has_feature("workspace"):
                 #add generators of various doctypes
                 container_name = naming.plural(type_key)
                 filters = dict(default_filters)
                 filters['filter_type'] = type_key
                 setattr(self, container_name,
                     doc_container.query(**filters)[0]
                 )
コード例 #25
0
 def container_name(cls):
     return naming.plural(cls.display_name) # !+unicode
コード例 #26
0
def setup_customization_ui():
    """Called from ui.app.on_wsgi_application_created_event -- must be called
    late, at least as long as there other ui zcml directives (always executed 
    very late) that need to have been executed prior to this e.g. 
    creation of specific menus such as "context_actions".
    """
    def register_menu_item(type_key,
                           privilege,
                           title,
                           for_,
                           action,
                           menu="context_actions",
                           order=10,
                           layer="bungeni.ui.interfaces.IBungeniSkin"):
        naming.MSGIDS.add(title)  # for i18n extraction
        UI_ZC_DECLS.append(register_menu_item.TMPL.format(**locals()))

    register_menu_item.TMPL = """
            <browser:menuItem menu="{menu}"
                for="{for_}"
                action="{action}"
                title="{title}"
                order="{order}"
                permission="bungeni.{type_key}.{privilege}"
                layer="{layer}"
            />"""

    def register_form_view(type_key,
                           privilege,
                           name,
                           for_,
                           class_,
                           layer="bungeni.ui.interfaces.IBungeniSkin"):
        UI_ZC_DECLS.append(register_form_view.TMPL.format(**locals()))

    register_form_view.TMPL = """
            <browser:page name="{name}"
                for="{for_}"
                class="{class_}"
                permission="bungeni.{type_key}.{privilege}"
                layer="{layer}"
            />"""

    def register_api_view(type_key, for_):
        UI_ZC_DECLS.append(register_api_view.TMPL.format(**locals()))

    register_api_view.TMPL = """
            <browser:page name="index"
                for="{for_}"
                class="bungeni.ui.api.APIObjectView"
                permission="bungeni.{type_key}.View"
                layer="bungeni.ui.interfaces.IBungeniAPILayer"
            />"""

    def model_title(type_key):
        return naming.split_camel(naming.model_name(type_key))

    UI_ZC_DECLS[:] = []
    # we assume that non-custom types have already been set up as needed
    for type_key, ti in capi.iter_type_info(scope="custom"):
        UI_ZC_DECLS.append("""
            
            <!-- {type_key} -->""".format(type_key=type_key))

        type_title = model_title(type_key)
        # model interface is defined, but container interface is not yet
        model_interface_qualname = naming.qualname(ti.interface)
        container_interface_qualname = "bungeni.models.interfaces.%s" % (
            naming.container_interface_name(type_key))

        # generic forms (independent of any feature)
        # add
        register_form_view(type_key, "Add", "add",
                           container_interface_qualname,
                           "bungeni.ui.forms.common.AddForm")
        # view
        register_form_view(type_key, "View", "index", model_interface_qualname,
                           "bungeni.ui.forms.common.DisplayForm")

        register_api_view(type_key, model_interface_qualname)
        # edit !+DiffEditForm prior to r10032, doc-archetyped types were being
        # *declared* to use bungeni.ui.forms.forms.DiffEditForm, but this
        # is not the edit view tht was actually being used!
        #register_form_view(type_key, "Edit", "edit", model_interface_qualname,
        #    "bungeni.ui.forms.common.EditForm")
        if issubclass(ti.interface, IBungeniGroup):
            register_form_view(type_key, "Edit", "edit",
                               model_interface_qualname,
                               "bungeni.ui.forms.common.GroupEditForm")
        else:
            register_form_view(type_key, "Edit", "edit",
                               model_interface_qualname,
                               "bungeni.ui.forms.common.EditForm")
        # delete
        register_form_view(type_key, "Delete", "delete",
                           model_interface_qualname,
                           "bungeni.ui.forms.common.DeleteForm")

        # plone content menu (for custom types)
        # !+ doc-types were previously being layered on IWorkspaceOrAdminSectionLayer
        # !+ there was previously no reg for IReportConatiner and one of the member
        # containers, plus there was inconsistency in permission for
        # IOfficeMemberContainer (was bungeni.office.Add).
        register_menu_item(type_key,
                           "Add",
                           "Add %s..." % (type_title),
                           container_interface_qualname,
                           "./add",
                           menu="plone_contentmenu",
                           layer="bungeni.ui.interfaces.IAdminSectionLayer")

        # workspace
        if ti.workflow.has_feature("workspace"):
            log.debug("Setting up UI for feature %r for type %r", "workspace",
                      type_key)

            # add menu item
            # !+workspace_feature_add(mr, oct-2012) note that an enabled
            # workspace feature also implies "add" functionality for the type
            first_tab = capi.workspace_tabs[0]
            action = "../../{first_tab}/add_{k}".format(first_tab=first_tab,
                                                        k=type_key)
            register_menu_item(type_key,
                               "Add",
                               type_title,
                               "*",
                               action,
                               menu="workspace_add_parliamentary_content",
                               order=7)

            # add menu item -> for admin ?!
            # !+ why a duplicated (almost identical) menu item for admin?
            # !+ criteria here is having workspace enabled... but, cirterion
            # should be simply that of being "parliamentary"? Do we need to
            # formalize this distinction?
            # !+ need a formal "container attribute" naming convention!
            action = "{k}/add".format(k=naming.plural(type_key))
            register_menu_item(type_key,
                               "Add",
                               type_title,
                               "*",
                               action,
                               menu="context_add_parliamentary_content",
                               order=7)

            # edit menu item
            # !+ edit/delete used to be on layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer"
            title = "Edit {t}".format(t=type_title)
            register_menu_item(type_key,
                               "Edit",
                               title,
                               model_interface_qualname,
                               "edit",
                               menu="context_actions",
                               order=10)

            # delete menu item
            title = "Delete {t}".format(t=type_title)
            register_menu_item(type_key,
                               "Delete",
                               title,
                               model_interface_qualname,
                               "delete",
                               menu="context_actions",
                               order=99)

            # add view
            name = "add_{type_key}".format(type_key=type_key)
            register_form_view(type_key, "Add", name,
                               "bungeni.core.interfaces.IWorkspaceTab",
                               "bungeni.ui.workspace.WorkspaceAddForm")

        # events
        if ti.workflow.has_feature("event"):
            log.debug("Setting up UI for feature %r for type %r", "event",
                      type_key)
            for event_type_key in ti.workflow.get_feature(
                    "event").params["types"]:
                if capi.has_type_info(event_type_key):
                    container_property_name = naming.plural(event_type_key)
                    # add menu item
                    title = "{t} {e}".format(t=type_title,
                                             e=model_title(event_type_key))
                    register_menu_item(
                        event_type_key,
                        "Add",
                        "Add %s" % (title),
                        model_interface_qualname,
                        "./%s/add" % (container_property_name),
                        menu="additems",
                        order=21,
                        layer=
                        "bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
                else:
                    log.warn(
                        'IGNORING feature "event" ref to disabled type %r',
                        event_type_key)

        # register other non-workspace menu items for custom types (only once)
        # custom events !+GET_ARCHETYPE
        if issubclass(ti.domain_model, domain.Event):
            # edit menu item
            register_menu_item(
                type_key,
                "Edit",
                "Edit {t}".format(t=type_title),
                model_interface_qualname,
                "edit",
                menu="context_actions",
                order=10,
                layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
            # delete menu item
            register_menu_item(
                type_key,
                "Delete",
                "Delete {t}".format(t=type_title),
                model_interface_qualname,
                "delete",
                menu="context_actions",
                order=99,
                layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")

        # address
        if ti.workflow.has_feature("address"):
            log.debug("Setting up UI for feature %r for type %r", "address",
                      type_key)
            if issubclass(ti.domain_model, domain.Group):
                title = "Add {t} Address".format(t=type_title)
                #layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer"
                # add address in the "add items..." menu
                register_menu_item("address",
                                   "Add",
                                   title,
                                   model_interface_qualname,
                                   "./addresses/add",
                                   menu="additems",
                                   order=80)
            elif issubclass(ti.domain_model, domain.User):
                # !+ User not a custom type (so should never pass here)
                assert False, "Type %s may not be a custom type" % (
                    ti.domain_model)
コード例 #27
0
ファイル: app.py プロジェクト: mohalfaki/bungeni-portal
    def setUp(self):

        # register translations
        #import zope.i18n.zcml
        #zope.i18n.zcml.registerTranslations(getConfigContext(),
        #    capi.get_path_for("translations", "bungeni"))
        # !+ZCML_PYTHON(mr, apr-2011) above registerTranslations() in python
        # does not work, as subsequent utility lookup fails. We workaround it
        # by executing the following parametrized bit of ZCML:
        from zope.configuration import xmlconfig
        xmlconfig.string("""
            <configure xmlns="http://namespaces.zope.org/zope"
                xmlns:i18n="http://namespaces.zope.org/i18n">
                <include package="zope.i18n" file="meta.zcml" />
                <i18n:registerTranslations directory="%s" />
            </configure>
            """ % (capi.get_path_for("translations", "bungeni")))

        sm = site.LocalSiteManager(self.context)
        self.context.setSiteManager(sm)

        from bungeni.core import language
        from bungeni.ui import z3evoque
        z3evoque.set_get_gettext()
        z3evoque.setup_evoque()
        z3evoque.domain.set_on_globals("devmode",
                                       common.has_feature("devmode"))
        z3evoque.domain.set_on_globals("absoluteURL", url.absoluteURL)
        z3evoque.domain.set_on_globals("get_section_name",
                                       url.get_section_name)
        z3evoque.domain.set_on_globals("get_base_direction",
                                       language.get_base_direction)
        z3evoque.domain.set_on_globals("is_rtl", language.is_rtl)

        # !+ where is the view name for the app root (slash) set?

        # CONVENTION: the action of each site top-section is made to point
        # directly the primary sub-section (the INDEX) that it contains.
        # EXCEPTION: the "/", when logged in, is redirected to "/workspace/pi"

        self.context["bungeni"] = AkomaNtosoSection(
            title=_(u"Bungeni"),
            description=_(u"Current parliamentary activity"),
            default_name="bung",  # !+NAMING(mr, jul-2011) bung?!?
        )

        # top-level sections
        workspace = self.context["workspace"] = WorkspaceSection(
            title=_("section_workspace", default=u"Workspace"),
            description=_(u"Current parliamentary activity"),
            default_name="my-documents",
        )
        alsoProvides(workspace, interfaces.ISearchableSection)

        workspace["my-documents"] = WorkspaceSection(
            title=_("section_workspace_documents", default=u"my documents"),
            description=_(u"my documents workspace section"),
            default_name="inbox",
            marker=interfaces.IWorkspaceDocuments,
        )

        for tab in capi.workspace_tabs:
            workspace["my-documents"][tab] = WorkspaceContainer(
                tab_type=tab,
                title=_("section_workspace_%s" % tab, default=tab),
                marker=interfaces.IWorkspaceTab)

        ws_uc = workspace["under-consideration"] = WorkspaceSection(
            title=_(u"under consideration"),
            description=_(u"documents under consideration"),
            default_name="documents",
            marker=interfaces.IWorkspaceUnderConsideration)
        ws_uc["documents"] = WorkspaceUnderConsiderationContainer(
            name="documents",
            title=_(u"under consideration"),
            description=_(u"documents under consideration"),
            marker=interfaces.IWorkspaceTrackedDocuments)
        ws_uc["tracked-documents"] = WorkspaceTrackedDocumentsContainer(
            name="tracked documents",
            title=_(u"tracked documents"),
            description=_(u"tracked documents"))

        ws_sched = workspace["scheduling"] = Section(
            title=_("section_scheduling", default=u"Scheduling"),
            description=_(u"Workspace Scheduling"),
            default_name="index",
            marker=interfaces.IWorkspaceScheduling)
        ws_sched["committees"] = QueryContent(
            container_getter(get_chamber_for_context, "committees"),
            title=_("section_scheduling_committees", default=u"Committees"),
            #!+marker=interfaces.ICommitteeAddContext,
            description=_(u"Committee schedules"))
        ws_sched["documents"] = WorkspaceSchedulableContainer(
            name=_(u"schedulable items"),
            title=_(u"schedulable items"),
            description=_(u"documents available for scheduling"))
        ws_sched["sittings"] = QueryContent(
            container_getter(get_chamber_for_context, "sittings"),
            title=_("section_scheduling_sittings", default=u"Sittings"),
            description=_(u"Plenary Sittings"))
        ws_sched["sessions"] = QueryContent(
            container_getter(get_chamber_for_context, "sessions"),
            title=_("section_scheduling_sessions", default=u"Sessions"),
            description=_(u"Plenary Sessions"))
        ws_sched["venues"] = QueryContent(container_getter(
            get_chamber_for_context, "venues"),
                                          title=_("section_scheduling_venues",
                                                  default=u"Venues"),
                                          description=_(u"Venues"))
        ws_sched["agendaitems"] = QueryContent(
            container_getter(get_chamber_for_context, "agendaitems"),
            title=_("section_scheduling_agenda_items",
                    default=u"Agenda items"),
            #marker=interfaces.IAgendaItemAddContext,
            description=_(u"Manage agenda items"))
        ws_sched["publications"] = QueryContent(
            container_getter(get_chamber_for_context, "publications"),
            title=_("section_scheduling_publications",
                    default=u"Publications"),
            description=_(u"Publications"))

        workspace["groups"] = WorkspaceSection(
            title=_("section_groups", default=u"Groups"),
            description=_(u"Bungeni Groups"),
            default_name="my-groups",
            marker=interfaces.IWorkspaceGroups)
        workspace["groups"]["my-groups"] = WorkspaceGroupsContainer(
            name="my-groups",
            title=_(u"My Groups"),
            description=_(u"Groups that the user is a member of"))

        #!+TIMING
        #!+AUTO CONTAINERS SCHEDULING(mb, April-2012)
        # type_info missing container name
        for type_key, ti in capi.iter_type_info():
            if model_interfaces.IScheduleContent.implementedBy(
                    ti.domain_model):
                container_property_name = naming.plural(type_key)
                container_class_name = naming.container_class_name(type_key)
                if not ws_sched.has_key(container_property_name):
                    ws_sched[container_property_name] = \
                        getattr(domain, container_class_name)()
                    to_locatable_container(ti.domain_model,
                                           ws_sched[container_property_name])

        ##########
        # Admin User Interface
        # Administration section

        #!+SECURITY(miano. nov-2010) Admin section now uses AdminSection
        # container that is identical to Section, only difference is that
        # traversing though it requires zope.ManageSite permission as defined
        # in core/configure.zcml

        admin = self.context["admin"] = AdminSection(
            title=_(u"Administration"),
            description=_(u"Manage bungeni settings"),
            default_name="admin-index",
            marker=model_interfaces.IBungeniAdmin)

        content = admin["content"] = Section(
            title=_(u"Content"),
            description=_(u"browse bungeni content"),
            marker=model_interfaces.IBungeniAdmin,
            default_name="browse-admin")
        alsoProvides(content, interfaces.ISearchableSection)

        admin["email-settings"] = Section(
            title=_(u"email settings"),
            description=_(u"manage email settings"),
            marker=model_interfaces.IBungeniAdmin,
            default_name="email-settings")

        admin["search-settings"] = Section(
            title=_(u"search settings"),
            description=_(u"manage bungeni email settings"),
            marker=model_interfaces.IBungeniAdmin,
            default_name="search-settings")

        admin["registry-settings"] = Section(
            title=_(u"registry settings"),
            description=_(u"manage registry settings"),
            marker=model_interfaces.IBungeniAdmin,
            default_name="registry-settings")

        admin["serialization-manager"] = Section(
            title=_(u"serialization manager"),
            description=_(u"batch serialization of content"),
            marker=model_interfaces.IBungeniAdmin,
            default_name="serialization-manager")

        content[u"parliaments"] = domain.ParliamentContainer()
        to_locatable_container(domain.Parliament, content[u"parliaments"])
        content[u"governments"] = domain.GovernmentContainer()
        to_locatable_container(domain.Government, content[u"governments"])
        content[u"joint-committees"] = domain.JointCommitteeContainer()
        to_locatable_container(domain.JointCommittee,
                               content["joint-committees"])
        content[u"users"] = domain.UserContainer()
        to_locatable_container(domain.User, content[u"users"])

        api = self.context[u"api"] = APISection(
            title=_(u"Bungeni API"),
            description=_(u"Bungeni REST API"),
            default_name="index",
        )

        api[u"workspace"] = copy.deepcopy(workspace)

        api[u"users"] = copy.deepcopy(content[u"users"])

        self.context["oauth"] = OAuthSection(
            title=_(u"Bungeni OAuth API"),
            description=_(u"Bungeni OAuth API"),
            default_name="index",
        )
        admin[u"applications"] = domain.OAuthApplicationContainer()
        to_locatable_container(domain.OAuthApplication, admin[u"applications"])
コード例 #28
0
def setup_customization_ui():
    """Called from ui.app.on_wsgi_application_created_event -- must be called
    late, at least as long as there other ui zcml directives (always executed 
    very late) that need to have been executed prior to this e.g. 
    creation of specific menus such as "context_actions".
    """
    #def model_title(type_key):
    #    return naming.split_camel(naming.model_name(type_key))
    
    # clear accumulation of generated zcml code -- but retain the same GLOBAL 
    # list variable instance
    UI_ZC_DECLS[:] = []
    
    # setup bungeni_custom resource
    UI_ZC_DECLS.append("""
    <browser:resourceDirectory name="reporting-static" 
        directory="%s/reporting/static" />""" % (capi.get_root_path()))
    
    # we assume that non-custom types have already been set up as needed
    for type_key, ti in capi.iter_type_info(scope="custom"):
        UI_ZC_DECLS.append("""
    
    <!-- {type_key} -->""".format(type_key=type_key))
        
        type_title = ti.label or ti.type_key
        
        # model interface is defined, but container interface is not yet
        model_interface_qualname = naming.qualname(ti.interface)
        container_interface_qualname = "bungeni.models.interfaces.%s" % (
                naming.container_interface_name(type_key))
        
        # generic forms (independent of any feature)
        # add
        register_form_view(type_key, "Add", "add", container_interface_qualname,
            "bungeni.ui.forms.common.AddForm")
        # api add
        register_form_view(type_key, "Add", "add", container_interface_qualname,
            "bungeni.ui.api.APIAddForm", "bungeni.ui.interfaces.IBungeniAPILayer")
        # view
        register_form_view(type_key, "View", "index", model_interface_qualname,
            "bungeni.ui.forms.common.DisplayForm")
        # api view
        register_form_view(type_key, "View", "index",
                model_interface_qualname,
                "bungeni.ui.api.APIObjectView",
                "bungeni.ui.interfaces.IBungeniAPILayer")
        # edit 
        # !+DiffEditForm prior to r10032, doc-archetyped types were being
        # *declared* to use bungeni.ui.forms.forms.DiffEditForm, but this
        # is not the edit view tht was actually being used!
        #register_form_view(type_key, "Edit", "edit", model_interface_qualname,
        #    "bungeni.ui.forms.common.EditForm")
        if issubclass(ti.domain_model, domain.Group):
            # groups
            register_form_view(type_key, "Edit", "edit",
                model_interface_qualname,
                "bungeni.ui.forms.common.GroupEditForm")
        else:
            register_form_view(type_key, "Edit", "edit",
                model_interface_qualname,
                "bungeni.ui.forms.common.EditForm")
            register_form_view(type_key, "Edit", "edit",
                model_interface_qualname,
                "bungeni.ui.api.APIEditForm",
                "bungeni.ui.interfaces.IBungeniAPILayer")
        # delete
        register_form_view(type_key, "Delete", "delete", model_interface_qualname,
            "bungeni.ui.forms.common.DeleteForm")
        
        # plone content menu (for custom types)
        # !+ doc-types were previously being layered on IWorkspaceOrAdminSectionLayer
        register_menu_item(type_key, "Add", "Add %s..." % (type_title), 
            container_interface_qualname,
            "./add",
            menu="plone_contentmenu",
            layer="bungeni.ui.interfaces.IAdminSectionLayer")
        
        # group        
        if issubclass(ti.domain_model, domain.Group):
            if ti.workflow.has_feature("sitting"):
                # !+CHAMBER_SITTING clarify/regularize for chamber (e.g. can
                # already add an agenda item via workspace menus, etc).
                # add sitting
                register_menu_item("sitting", "Add", "Add sitting...",
                    model_interface_qualname,
                    "./sittings/add",
                    menu="additems", 
                    order=40,
                    layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
                # add calendar "createable" add doc menu items
                sitting_feature = ti.workflow.get_feature("sitting")
                for calendar_doc_type_key in sitting_feature.get_param("calendar_doc_types"):
                    CALENDAR_DOC_TYPE_KEYS.add(calendar_doc_type_key)
                    calendar_doc_ti = capi.get_type_info(calendar_doc_type_key)
                    container_property_name = naming.plural(calendar_doc_type_key)
                    register_menu_item(calendar_doc_type_key, 
                        "Add",
                        "Add %s..." % (calendar_doc_ti.label), #!+MENUITEM_TITLE
                        model_interface_qualname,
                        "./%s/add" % (container_property_name),
                        menu="additems", 
                        order=41,
                        layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
                
                # group CalendarView
                register_form_view(type_key, "View", "schedule",
                    model_interface_qualname,
                    "bungeni.ui.calendar.browser.CalendarView")
        
        # member
        if issubclass(ti.domain_model, domain.GroupMember):
            group_ti = capi.get_type_info(ti.within_type_key)
            group_model_interface_qualname = naming.qualname(group_ti.interface)
            # add
            register_menu_item(type_key, "Add", "Add %s..." % (type_title), 
                group_model_interface_qualname,
                "./%s/add" % (naming.plural(type_key)),
                menu="additems", 
                order=61,
                layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
        
        # group, member
        if issubclass(ti.domain_model, (domain.Group, domain.GroupMember)):
            # edit
            register_menu_item(type_key, "Edit", "Edit %s..." % (type_title), 
                model_interface_qualname,
                "edit",
                menu="context_actions", 
                order=10,
                layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
            # delete
            register_menu_item(type_key, "Delete", "Delete %s..." % (type_title), 
                model_interface_qualname,
                "delete",
                menu="context_actions", 
                order=99,
                layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
        
        # create/register custom container viewlets
        # !+descriptor/restore.py ti.descriptor_model is None when running this utility
        if ti.descriptor_model:
            for i, ic in enumerate(ti.descriptor_model.info_containers):
                if ic.viewlet:
                    sfv_cls = new_container_sub_form_viewlet_cls(type_key, ic, i)
                    register_container_viewlet(
                        type_key, ic.viewlet_name, model_interface_qualname)
        
        # workspace
        if ti.workflow.has_feature("workspace"):
            log.debug("Setting up UI for feature %r for type %r", "workspace", type_key)
            
            # add menu item
            # !+AUTO_UI_ZCML_MENU_ITEMS: workspace_add_parliamentary_content
            # !+workspace_feature_add(mr, oct-2012) note that an enabled
            # workspace feature also implies "add" functionality for the type
            first_tab = capi.workspace_tabs[0]
            action_verb = "add_{k}".format(k=type_key)
            action = "../../{first_tab}/{action_verb}".format(
                first_tab=first_tab, action_verb=action_verb)
            # !+MENUITEM_TITLE_r11350(mr, jun-2014) am switching the title of these 
            # two menuItems to use the type_key instead of the ti label, as it seems 
            # ZCML does not allow to have a same @title value for multiple menuItem 
            # declarations for the same menu + target interface (even if @action,
            # @permission are different).
            # bungeni.models.interfaces.IGroup, bungeni.core.interfaces.IWorkspaceContainer
            register_menu_item(type_key, "Add", 
                type_title, # !+MENUITEM_TITLE
                "bungeni.models.interfaces.ISUBMENU_workspace_add_parliamentary_content",
                action,
                menu="workspace_add_parliamentary_content",
                filter_="python: context.is_type_workspaced(%r)" % (type_key),
                order=7)
            
            ''' !+MENUITEM_TITLE_r11350(mr, jun-2014) -- disabling to monitor 
                if needed; re-enable or delete...
            # add menu item -> for admin ?!
            # !+AUTO_UI_ZCML_MENU_ITEMS: context_add_parliamentary_content
            # !+ why a duplicated (almost identical) menu item for admin?
            # !+ criteria here is having workspace enabled... but, criterion 
            # should be simply that of being "parliamentary"? Do we need to 
            # formalize this distinction?
            # !+ need a formal "container attribute" naming convention!
            action = "{k}/add".format(k=naming.plural(type_key))
            register_menu_item(type_key, "Add", type_title, 
                "bungeni.models.interfaces.IGroup",
                action,
                menu="context_add_parliamentary_content",
                filter_="python: context.is_type_workspaced(%r)" % (type_key),
                order=7)
            '''
            
            # edit menu item
            # !+ edit/delete used to be on layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer"
            title = "Edit {t}".format(t=type_title)
            register_menu_item(type_key, "Edit", title, model_interface_qualname, "edit",
                menu="context_actions", order=10)
            
            # delete menu item
            title = "Delete {t}".format(t=type_title)
            register_menu_item(type_key, "Delete", title, model_interface_qualname, "delete",
                menu="context_actions", order=99)
            
            # add view
            name = "add_{type_key}".format(type_key=type_key)
            register_form_view(type_key, "Add", name,
                "bungeni.core.interfaces.IWorkspaceTab",
                "bungeni.ui.workspace.WorkspaceAddForm")
            # api add
            register_form_view(type_key, "Add", name,
                "bungeni.core.interfaces.IWorkspaceTab",
                "bungeni.ui.api.APIWorkspaceAddForm",
                "bungeni.ui.interfaces.IBungeniAPILayer")
        
        # workspace add titles to strings for i18n
        for ws_tab in capi.workspace_tabs:
            naming.MSGIDS.add(("section_workspace_%s" % ws_tab, ws_tab))
        
        # events
        if ti.workflow.has_feature("event"):
            log.debug("Setting up UI for feature %r for type %r", "event", type_key)
            event_feature = ti.workflow.get_feature("event")
            for event_type_key in event_feature.get_param("types"):
                if capi.has_type_info(event_type_key):
                    container_property_name = naming.plural(event_type_key)
                    event_type_ti = capi.get_type_info(event_type_key)
                    # add menu item
                    title = "{t} {e}".format(
                        t=type_title, 
                        e=(event_type_ti.label or event_type_ti.type_key))
                    register_menu_item(event_type_key, "Add", "Add %s" %(title),
                        model_interface_qualname, 
                        "./%s/add" % (container_property_name), 
                        menu="additems",
                        order=21,
                        layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
                else:
                    log.warn("IGNORING feature %r ref to disabled type %r", 
                        "event", event_type_key)
        
        # register other non-workspace menu items for custom types (only once)
        # custom events !+GET_ARCHETYPE !+ARCHETYPE_INSTANTIATABLE
        if issubclass(ti.domain_model, domain.Event):
            # edit menu item
            register_menu_item(type_key, "Edit", "Edit {t}".format(t=type_title),
                model_interface_qualname,
                "edit",
                menu="context_actions",
                order=10,
                layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
            # delete menu item
            register_menu_item(type_key, "Delete", "Delete {t}".format(t=type_title),
                model_interface_qualname,
                "delete",
                menu="context_actions",
                order=99,
                layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
        
        # address
        if ti.workflow.has_feature("address"):
            log.debug("Setting up UI for feature %r for type %r", "address", type_key)
            if issubclass(ti.domain_model, domain.Group):
                title = "Add {t} Address".format(t=type_title)
                #layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer"
                # add address in the "add items..." menu
                register_menu_item("address", "Add", title, model_interface_qualname, 
                    "./addresses/add", menu="additems", order=80)
            elif issubclass(ti.domain_model, domain.User):
                # !+ User not a custom type (so should never pass here)
                assert False, "Type %s may not be a custom type" % (ti.domain_model)
    
    # once-only processing
    for calendar_doc_type_key in CALENDAR_DOC_TYPE_KEYS:
        # !+CALENDAR_DOC_TYPES
        calendar_doc_ti = capi.get_type_info(calendar_doc_type_key)
        container_property_name = naming.plural(calendar_doc_type_key)
        # !+SchedulingContext why do they need to be different?
        # plenary scheduling
        register_menu_item(calendar_doc_type_key, 
            "Add", 
            "Add %s..." % (calendar_doc_ti.label), #!+MENUITEM_TITLE
            "bungeni.core.schedule.WorkspaceSchedulingContext",
            "./%s/add" % (container_property_name),
            menu="plone_contentmenu", 
            #order=41,
            layer="bungeni.ui.interfaces.IWorkspaceSectionLayer")
        # group (committee) scheduling 
        register_menu_item(calendar_doc_type_key, 
            "Add", 
            "Add %s..." % (calendar_doc_ti.label), #!+MENUITEM_TITLE
            "bungeni.core.schedule.GroupSchedulingContext",
            "./../%s/add" % (container_property_name),
            menu="plone_contentmenu", 
            #order=41,
            layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
コード例 #29
0
ファイル: app.py プロジェクト: kohsah/bungeni-portal
    def setUp(self):
        
        # register translations
        #import zope.i18n.zcml
        #zope.i18n.zcml.registerTranslations(getConfigContext(),
        #    capi.get_path_for("translations", "bungeni"))
        # !+ZCML_PYTHON(mr, apr-2011) above registerTranslations() in python 
        # does not work, as subsequent utility lookup fails. We workaround it 
        # by executing the following parametrized bit of ZCML:
        from zope.configuration import xmlconfig
        xmlconfig.string("""
            <configure xmlns="http://namespaces.zope.org/zope"
                xmlns:i18n="http://namespaces.zope.org/i18n">
                <include package="zope.i18n" file="meta.zcml" />
                <i18n:registerTranslations directory="%s" />
            </configure>
            """ % (capi.get_path_for("translations", "bungeni")))
        
        sm = site.LocalSiteManager(self.context)
        self.context.setSiteManager(sm)
        
        from bungeni.core import language
        from bungeni.ui import z3evoque
        z3evoque.set_get_gettext()
        z3evoque.setup_evoque()
        z3evoque.domain.set_on_globals("devmode", common.has_feature("devmode"))
        z3evoque.domain.set_on_globals("absoluteURL", url.absoluteURL)
        z3evoque.domain.set_on_globals("get_section_name", url.get_section_name)
        z3evoque.domain.set_on_globals("get_base_direction", 
            language.get_base_direction)
        z3evoque.domain.set_on_globals("is_rtl", language.is_rtl)          
        
        # !+ where is the view name for the app root (slash) set?
        
        # CONVENTION: the action of each site top-section is made to point 
        # directly the primary sub-section (the INDEX) that it contains.
        # EXCEPTION: the "/", when logged in, is redirected to "/workspace/pi"
        
        self.context["bungeni"] = AkomaNtosoSection(
            title=_(u"Bungeni"),
            description=_(u"Current parliamentary activity"),
            default_name="bung", # !+NAMING(mr, jul-2011) bung?!?
        )
        
        # top-level sections
        workspace = self.context["workspace"] = WorkspaceSection(
            title=_("section_workspace", default=u"Workspace"),
            description=_(u"Current parliamentary activity"),
            default_name="my-documents",
        )
        alsoProvides(workspace, interfaces.ISearchableSection)
        
        workspace["my-documents"] = WorkspaceSection(
            title=_("section_workspace_documents", default=u"my documents"),
            description=_(u"my documents workspace section"),
            default_name="inbox",
            marker=interfaces.IWorkspaceDocuments,
        )
        
        for tab in capi.workspace_tabs:
            workspace["my-documents"][tab] = WorkspaceContainer(
                tab_type=tab,
                title=_("section_workspace_%s" % tab, default=tab),
                marker=interfaces.IWorkspaceTab
            )

        ws_uc = workspace["under-consideration"] = WorkspaceSection(
            title=_(u"under consideration"),
            description=_(u"documents under consideration"),
            default_name="documents",
            marker=interfaces.IWorkspaceUnderConsideration)
        ws_uc["documents"] = WorkspaceUnderConsiderationContainer(
            name="documents",
            title=_(u"under consideration"),
            description=_(u"documents under consideration"),
            marker=interfaces.IWorkspaceTrackedDocuments)
        ws_uc["tracked-documents"] = WorkspaceTrackedDocumentsContainer(
            name="tracked documents",
            title=_(u"tracked documents"),
            description=_(u"tracked documents"))
        
        ws_sched = workspace["scheduling"] = Section(
            title=_("section_scheduling", default=u"Scheduling"),
            description=_(u"Workspace Scheduling"),
            default_name="index",
            marker=interfaces.IWorkspaceScheduling)
        ws_sched["committees"] = QueryContent(
            container_getter(get_chamber_for_context, "committees"),
            title=_("section_scheduling_committees", default=u"Committees"),
            #!+marker=interfaces.ICommitteeAddContext,
            description=_(u"Committee schedules"))
        ws_sched["documents"] = WorkspaceSchedulableContainer(
            name=_(u"schedulable items"),
            title=_(u"schedulable items"),
            description=_(u"documents available for scheduling"))
        ws_sched["sittings"] = QueryContent(
            container_getter(get_chamber_for_context, "sittings"),
            title=_("section_scheduling_sittings", default=u"Sittings"),
            description=_(u"Plenary Sittings"))
        ws_sched["sessions"] = QueryContent(
            container_getter(get_chamber_for_context, "sessions"),
            title=_("section_scheduling_sessions", default=u"Sessions"),
            description=_(u"Plenary Sessions"))
        ws_sched["venues"] = QueryContent(
            container_getter(get_chamber_for_context, "venues"),
            title=_("section_scheduling_venues", default=u"Venues"),
            description=_(u"Venues"))
        ws_sched["agendaitems"] = QueryContent(
            container_getter(get_chamber_for_context, "agendaitems"),
            title=_("section_scheduling_agenda_items", 
                default=u"Agenda items"),
            #marker=interfaces.IAgendaItemAddContext,
            description=_(u"Manage agenda items"))
        ws_sched["publications"] = QueryContent(
            container_getter(get_chamber_for_context, "publications"),
            title=_("section_scheduling_publications", 
                default=u"Publications"),
            description=_(u"Publications"))
        
        workspace["groups"] = WorkspaceSection(
            title=_("section_groups", default=u"Groups"),
            description=_(u"Bungeni Groups"),
            default_name="my-groups",
            marker=interfaces.IWorkspaceGroups)
        workspace["groups"]["my-groups"] = WorkspaceGroupsContainer(
            name="my-groups",
            title=_(u"My Groups"),
            description=_(u"Groups that the user is a member of"))
        
        #!+TIMING
        #!+AUTO CONTAINERS SCHEDULING(mb, April-2012)
        # type_info missing container name
        for type_key, ti in capi.iter_type_info():
            if model_interfaces.IScheduleContent.implementedBy(ti.domain_model):
                container_property_name = naming.plural(type_key)
                container_class_name = naming.container_class_name(type_key)
                if not ws_sched.has_key(container_property_name):
                    ws_sched[container_property_name] = \
                        getattr(domain, container_class_name)()
                    to_locatable_container(
                        ti.domain_model, ws_sched[container_property_name])
        
        
        ##########
        # Admin User Interface
        # Administration section
        
        #!+SECURITY(miano. nov-2010) Admin section now uses AdminSection
        # container that is identical to Section, only difference is that
        # traversing though it requires zope.ManageSite permission as defined
        # in core/configure.zcml
        
        admin = self.context["admin"] = AdminSection(
            title=_(u"Administration"),
            description=_(u"Manage bungeni settings"),
            default_name="admin-index",
            marker=model_interfaces.IBungeniAdmin)
        
        content = admin["content"] = Section(
            title=_(u"Content"),
            description=_(u"browse bungeni content"),
            marker=model_interfaces.IBungeniAdmin,
            default_name="browse-admin")
        alsoProvides(content, interfaces.ISearchableSection)
        
        admin["email-settings"] = Section(
            title=_(u"email settings"),
            description=_(u"manage email settings"),
            marker=model_interfaces.IBungeniAdmin,
            default_name="email-settings")
        
        admin["search-settings"] = Section(
            title=_(u"search settings"),
            description=_(u"manage bungeni email settings"),
            marker=model_interfaces.IBungeniAdmin,
            default_name="search-settings")
        
        admin["registry-settings"] = Section(
            title=_(u"registry settings"),
            description=_(u"manage registry settings"),
            marker=model_interfaces.IBungeniAdmin,
            default_name="registry-settings")
        
        admin["serialization-manager"] = Section(
            title=_(u"serialization manager"),
            description=_(u"batch serialization of content"),
            marker=model_interfaces.IBungeniAdmin,
            default_name="serialization-manager")
        
        content[u"parliaments"] = domain.ParliamentContainer()
        to_locatable_container(domain.Parliament, content[u"parliaments"])
        content[u"governments"] = domain.GovernmentContainer()
        to_locatable_container(domain.Government, content[u"governments"])
        content[u"joint-committees"] = domain.JointCommitteeContainer()
        to_locatable_container(domain.JointCommittee,
            content["joint-committees"])
        content[u"users"] = domain.UserContainer()
        to_locatable_container(domain.User, content[u"users"])

        api = self.context[u"api"] = APISection(
            title=_(u"Bungeni API"),
            description=_(u"Bungeni REST API"),
            default_name="index",
        )

        api[u"workspace"] = copy.deepcopy(workspace)

        api[u"users"] = copy.deepcopy(content[u"users"])

        self.context["oauth"] = OAuthSection(
            title=_(u"Bungeni OAuth API"),
            description=_(u"Bungeni OAuth API"),
            default_name="index",
        )
        admin[u"applications"] = domain.OAuthApplicationContainer()
        to_locatable_container(domain.OAuthApplication, admin[u"applications"])
コード例 #30
0
def localize_descriptor(type_key, descriptor_elem, scope="system"):
    """Localize descriptor from descriptor XML element.
    Return the created/modified descriptor class.
    """
    ti = capi.get_type_info(type_key)
    # !+ ensure domain_model has already been set
    assert ti.domain_model, type_key
    
    order = xai(descriptor_elem, "order")
    fields = new_descriptor_fields(descriptor_elem)
    
    info_containers = []
    for c_elem in descriptor_elem.findall("container"):
        # !+ @view_title:i18n_key, @view_id:token, @weight:int ?
        target_type_key, rel_attr_name = xas(c_elem, "match").split(".", 1)
        container_attr_name = xas(c_elem, "name") or naming.plural(target_type_key)
        indirect_key = xas(c_elem, "indirect_key")
        viewlet = xab(c_elem, "viewlet", False)
        add_info_container(type_key, info_containers, 
            container_attr_name, target_type_key, rel_attr_name, indirect_key, 
            viewlet=viewlet, _origin="container")
    
    integrity = descriptor_elem.find("integrity")
    if integrity is not None:
        constraints = [ capi.get_form_constraint(c) for c in
            xas(integrity, "constraints", "").split() ]
        validations = [ capi.get_form_validator(v) for v in 
            xas(integrity, "validations", "").split() ]
    else:
        constraints, validations = (), ()
    
    if scope=="custom":
        try:
            cls = update_descriptor_cls(type_key, order, 
                fields, info_containers, constraints, validations)
        except AttributeError:
            # first time around, no such descriptor - so create a new custom descriptor
            archetype_key = naming.polymorphic_identity(ti.archetype)
            cls = new_descriptor_cls(type_key, archetype_key, order, 
                fields, info_containers, constraints, validations)
            if xas(descriptor_elem, "sort_on"):
                cls.sort_on = xas(descriptor_elem, "sort_on").split()
                # !+ assert each name is a field in the descriptor
            if xas(descriptor_elem, "sort_dir"): # default cls.sort_dir: "desc"
                cls.sort_dir = xas(descriptor_elem, "sort_dir")
            update_new_descriptor_cls_from_ti(ti)
    else:
        # non-custom
        cls = update_descriptor_cls(type_key, order, 
            fields, info_containers, constraints, validations)
    
    # finish model/descriptor setup from feature configuration
    if ti.workflow:
        for feature in ti.workflow.features:
            feature.setup_ui(ti.domain_model)
    
    # custom container order - re-sort info_containers such that "container" 
    # ones precede all "feature" ones, plus make the list immutable i.e. no 
    # further changes allowed.
    ics = ti.descriptor_model.info_containers
    ti.descriptor_model.info_containers = tuple(sorted(ics,
            # False sorts before True (as 0 sorts before 1)
            key=lambda ic: ic._origin == "feature"
    ))
    
    log.debug("Localized descriptor [%s] %s", type_key, ti)
    return cls
コード例 #31
0
def setup_customization_ui():
    """Called from ui.app.on_wsgi_application_created_event -- must be called
    late, at least as long as there other ui zcml directives (always executed 
    very late) that need to have been executed prior to this e.g. 
    creation of specific menus such as "context_actions".
    """
    
    def register_menu_item(type_key, privilege, title, for_, action,
            menu="context_actions", 
            order=10,
            layer="bungeni.ui.interfaces.IBungeniSkin"
        ):
        naming.MSGIDS.add(title) # for i18n extraction
        UI_ZC_DECLS.append(register_menu_item.TMPL.format(**locals()))
    register_menu_item.TMPL = """
            <browser:menuItem menu="{menu}"
                for="{for_}"
                action="{action}"
                title="{title}"
                order="{order}"
                permission="bungeni.{type_key}.{privilege}"
                layer="{layer}"
            />"""
    
    def register_form_view(type_key, privilege, name, for_, class_,
            layer="bungeni.ui.interfaces.IBungeniSkin"
        ):
        UI_ZC_DECLS.append(register_form_view.TMPL.format(**locals()))
    register_form_view.TMPL = """
            <browser:page name="{name}"
                for="{for_}"
                class="{class_}"
                permission="bungeni.{type_key}.{privilege}"
                layer="{layer}"
            />"""

    def register_api_view(type_key, for_):
        UI_ZC_DECLS.append(register_api_view.TMPL.format(**locals()))
    register_api_view.TMPL = """
            <browser:page name="index"
                for="{for_}"
                class="bungeni.ui.api.APIObjectView"
                permission="bungeni.{type_key}.View"
                layer="bungeni.ui.interfaces.IBungeniAPILayer"
            />"""

    def model_title(type_key):
        return naming.split_camel(naming.model_name(type_key))
    
    UI_ZC_DECLS[:] = []
    # we assume that non-custom types have already been set up as needed
    for type_key, ti in capi.iter_type_info(scope="custom"):
        UI_ZC_DECLS.append("""
            
            <!-- {type_key} -->""".format(type_key=type_key))
        
        type_title = model_title(type_key)
        # model interface is defined, but container interface is not yet
        model_interface_qualname = naming.qualname(ti.interface)
        container_interface_qualname = "bungeni.models.interfaces.%s" % (
                naming.container_interface_name(type_key))
        
        # generic forms (independent of any feature)
        # add
        register_form_view(type_key, "Add", "add", container_interface_qualname,
            "bungeni.ui.forms.common.AddForm")
        # view
        register_form_view(type_key, "View", "index", model_interface_qualname,
            "bungeni.ui.forms.common.DisplayForm")
        
        register_api_view(type_key, model_interface_qualname)
        # edit !+DiffEditForm prior to r10032, doc-archetyped types were being
        # *declared* to use bungeni.ui.forms.forms.DiffEditForm, but this
        # is not the edit view tht was actually being used!
        #register_form_view(type_key, "Edit", "edit", model_interface_qualname,
        #    "bungeni.ui.forms.common.EditForm")
        if issubclass(ti.interface, IBungeniGroup):
            register_form_view(type_key, "Edit", "edit",
                model_interface_qualname,
                "bungeni.ui.forms.common.GroupEditForm")
        else:
            register_form_view(type_key, "Edit", "edit",
            model_interface_qualname,
            "bungeni.ui.forms.common.EditForm")
        # delete
        register_form_view(type_key, "Delete", "delete", model_interface_qualname,
            "bungeni.ui.forms.common.DeleteForm")
        
        # plone content menu (for custom types)
        # !+ doc-types were previously being layered on IWorkspaceOrAdminSectionLayer
        # !+ there was previously no reg for IReportConatiner and one of the member
        # containers, plus there was inconsistency in permission for 
        # IOfficeMemberContainer (was bungeni.office.Add).
        register_menu_item(type_key, "Add", "Add %s..." % (type_title), 
            container_interface_qualname,
            "./add",
            menu="plone_contentmenu",
            layer="bungeni.ui.interfaces.IAdminSectionLayer")
        
        # workspace
        if ti.workflow.has_feature("workspace"):
            log.debug("Setting up UI for feature %r for type %r", "workspace", type_key)
            
            # add menu item
            # !+workspace_feature_add(mr, oct-2012) note that an enabled
            # workspace feature also implies "add" functionality for the type
            first_tab = capi.workspace_tabs[0]
            action = "../../{first_tab}/add_{k}".format(first_tab=first_tab,
                k=type_key)
            register_menu_item(type_key, "Add", type_title, "*", action,
                menu="workspace_add_parliamentary_content", order=7)
            
            # add menu item -> for admin ?!
            # !+ why a duplicated (almost identical) menu item for admin?
            # !+ criteria here is having workspace enabled... but, cirterion 
            # should be simply that of being "parliamentary"? Do we need to 
            # formalize this distinction?
            # !+ need a formal "container attribute" naming convention!
            action = "{k}/add".format(k=naming.plural(type_key)) 
            register_menu_item(type_key, "Add", type_title, "*", action,
                menu="context_add_parliamentary_content", order=7)
            
            # edit menu item
            # !+ edit/delete used to be on layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer"
            title = "Edit {t}".format(t=type_title)
            register_menu_item(type_key, "Edit", title, model_interface_qualname, "edit",
                menu="context_actions", order=10)
            
            # delete menu item
            title = "Delete {t}".format(t=type_title)
            register_menu_item(type_key, "Delete", title, model_interface_qualname, "delete",
                menu="context_actions", order=99)
            
            # add view
            name = "add_{type_key}".format(type_key=type_key)
            register_form_view(type_key, "Add", name,
                "bungeni.core.interfaces.IWorkspaceTab",
                "bungeni.ui.workspace.WorkspaceAddForm")
        
        # events
        if ti.workflow.has_feature("event"):
            log.debug("Setting up UI for feature %r for type %r", "event", type_key)
            for event_type_key in ti.workflow.get_feature("event").params["types"]:
                if capi.has_type_info(event_type_key):
                    container_property_name = naming.plural(event_type_key)
                    # add menu item
                    title = "{t} {e}".format(t=type_title, e=model_title(event_type_key))
                    register_menu_item(event_type_key, "Add", "Add %s" %(title),
                        model_interface_qualname, 
                        "./%s/add" % (container_property_name), 
                        menu="additems", 
                        order=21,
                        layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
                else:
                    log.warn('IGNORING feature "event" ref to disabled type %r', 
                        event_type_key)
        
        # register other non-workspace menu items for custom types (only once)
        # custom events !+GET_ARCHETYPE
        if issubclass(ti.domain_model, domain.Event):
            # edit menu item
            register_menu_item(type_key, "Edit", "Edit {t}".format(t=type_title),
                model_interface_qualname,
                "edit",
                menu="context_actions",
                order=10,
                layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
            # delete menu item
            register_menu_item(type_key, "Delete", "Delete {t}".format(t=type_title),
                model_interface_qualname,
                "delete",
                menu="context_actions",
                order=99,
                layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer")
        
        # address
        if ti.workflow.has_feature("address"):
            log.debug("Setting up UI for feature %r for type %r", "address", type_key)
            if issubclass(ti.domain_model, domain.Group):
                title = "Add {t} Address".format(t=type_title)
                #layer="bungeni.ui.interfaces.IWorkspaceOrAdminSectionLayer"
                # add address in the "add items..." menu
                register_menu_item("address", "Add", title, model_interface_qualname, 
                    "./addresses/add", menu="additems", order=80)
            elif issubclass(ti.domain_model, domain.User):
                # !+ User not a custom type (so should never pass here)
                assert False, "Type %s may not be a custom type" % (ti.domain_model)