def documentTemplates(self): templates = [] templates_path = capi.get_path_for("reporting", "templates", "templates.xml") if os.path.exists(templates_path): template_config = etree.fromstring(open(templates_path).read()) for template in template_config.iter(tag="template"): location = capi.get_path_for("reporting", "templates", template.get("file")) template_file_name = template.get("file") if os.path.exists(location): template_dict = dict( title=template.get("name"), language=template.get("language"), location=base64.encodestring(template_file_name), ) templates.append(template_dict) else: log.error("Template does noet exist. No file found at %s.", location) return templates
def documentTemplates(self): templates = [] templates_path = capi.get_path_for("reporting", "templates", "templates.xml") if os.path.exists(templates_path): template_config = etree.fromstring(open(templates_path).read()) for template in template_config.iter(tag="template"): location = capi.get_path_for("reporting", "templates", template.get("file")) template_file_name = template.get("file") if os.path.exists(location): template_dict = dict( title=template.get("name"), language=template.get("language"), location=base64.encodestring(template_file_name)) templates.append(template_dict) else: log.error("Template does noet exist. No file found at %s.", location) return templates
def setupTemplate(self): """Check if a template was provided in the request as url/form parameter. """ template_encoded = self.request.form.get("template", "") if template_encoded != "": template_file_name = base64.decodestring(template_encoded) template_path = capi.get_path_for("reporting", "templates", template_file_name ) if os.path.exists(template_path): self.oo_template_file = template_path
def get_mask(context): # assert IBungeniParliamentaryContent.providedBy(context) # !+IBungeniParliamentaryContent(mr, nov-2011) only context typed # interfaces.IBungeniParliamentaryContent should ever get here! # But for this case, all we need is that context defines a type: m = "PI context [%s] for get_mask must specify a type attr" % (context) assert hasattr(context, "type"), m path = capi.get_path_for("registry") config = ConfigParser() config.readfp(open(os.path.join(path, "config.ini"))) try: return config.get("types", context.type) except NoOptionError: return None
def set_get_gettext(): """Set this callable as the z3evoque.get_gettext global function to return a gettext bound onto an i18n domain and a language. This function is to be defined and called by the application - get_gettext itself should have the parameters (i18n_domain, language). """ from bungeni.utils.capi import capi _i18n_domain_localedirs = { "bungeni": capi.get_path_for("translations", "bungeni"), } _untranslated = [] def _get_gettext(i18n_domain, language): """Get a _() i18n gettext function bound to domain and language. !+ There is probably a better way to do this; the following "obvious" way does not work: zope.i18nmessageid.MessageFactory(i18n_domain) """ import gettext try: t = gettext.translation( i18n_domain, localedir=_i18n_domain_localedirs[i18n_domain], languages=[language]) except (IOError, ): cls, exc, tb = sys.exc_info() if language != "en": log.error(""" [%s] %s [lang=%s] -> trying with [lang=%s]""" % (cls.__name__, exc, language, "en")) return _get_gettext(i18n_domain, "en") else: log.error(""" [%s] %s [lang=%s]""" % (cls.__name__, exc, language)) raise exc # wrap t.gettext to intercept and log possibly untranslated msgids def _gt(msgid): try: msgstr = t.gettext(msgid) return msgstr finally: if msgid == msgstr and msgid not in _untranslated: _untranslated.append(msgid) log.warn('i18n NOT LOCALIZED [%s, %s] "%s"' % (i18n_domain, language, msgid)) return _gt global get_gettext get_gettext = _get_gettext
def buildTerms(self): vocabulary_terms = [] template_folder = capi.get_path_for("reporting", "templates", self.template_folder) if not os.path.exists(template_folder): log.error("Directory for XHTML templates does not exist: %s", template_folder) return file_list = filter(lambda fname: fname.endswith(".html"), os.listdir(template_folder)) for file_name in file_list: file_path = "/".join([template_folder, file_name]) vocabulary_terms.append( vocabulary.SimpleTerm(file_path, token=hashlib.md5(file_name).hexdigest(), title=self.getTitle(file_path))) return vocabulary_terms
def load_workspace(file_name, domain_class): """Loads the workspace configuration for each documemnt""" workspace_tabs = getUtility(IWorkspaceTabsUtility) path = capi.get_path_for("workspace") file_path = os.path.join(path, file_name) item_type = file_name.split(".")[0] workspace_tabs.registerItemType(domain_class, item_type) workspace = etree.fromstring(open(file_path).read()) for state in workspace.iterchildren("state"): for tab in state.iterchildren(): if tab.get("id") in TABS: if tab.get("roles"): roles = tab.get("roles").split() for role in roles: workspace_tabs.setContent(role, tab.get("id"), domain_class, state.get("id")) else: raise ValueError("Invalid tab - %s", tab.get("id"))
def set_get_gettext(): """Set this callable as the z3evoque.get_gettext global function to return a gettext bound onto an i18n domain and a language. This function is to be defined and called by the application - get_gettext itself should have the parameters (i18n_domain, language). """ from bungeni.utils.capi import capi _i18n_domain_localedirs = { "bungeni": capi.get_path_for("translations", "bungeni"), } _untranslated = [] def _get_gettext(i18n_domain, language): """Get a _() i18n gettext function bound to domain and language. !+ There is probably a better way to do this; the following "obvious" way does not work: zope.i18nmessageid.MessageFactory(i18n_domain) """ import gettext try: t = gettext.translation(i18n_domain, localedir=_i18n_domain_localedirs[i18n_domain], languages=[language]) except (IOError,): cls, exc, tb = sys.exc_info() if language != "en": log.error(""" [%s] %s [lang=%s] -> trying with [lang=%s]""" % ( cls.__name__, exc, language, "en")) return _get_gettext(i18n_domain, "en") else: log.error(""" [%s] %s [lang=%s]""" % ( cls.__name__, exc, language)) raise exc # wrap t.gettext to intercept and log possibly untranslated msgids def _gt(msgid): try: msgstr = t.gettext(msgid) return msgstr finally: if msgid == msgstr and msgid not in _untranslated: _untranslated.append(msgid) log.warn('i18n NOT LOCALIZED [%s, %s] "%s"' % ( i18n_domain, language, msgid)) return _gt global get_gettext get_gettext = _get_gettext
def load_workspace(file_name, domain_class): """Loads the workspace configuration for each documemnt""" workspace_tabs = getUtility(IWorkspaceTabsUtility) path = capi.get_path_for("workspace") file_path = os.path.join(path, file_name) item_type = file_name.split(".")[0] workspace_tabs.register_item_type(domain_class, item_type) workspace = etree.fromstring(open(file_path).read()) for state in workspace.iterchildren(tag="state"): for tab in state.iterchildren(tag="tab"): if tab.get("id") in TABS: if tab.get("roles"): roles = tab.get("roles").split() for role in roles: workspace_tabs.set_content(role, tab.get("id"), domain_class, state.get("id")) else: raise ValueError("Invalid tab - %s. state : %s", tab.get("id"), state.get("id"))
def get_mask(context): # !+IBungeniParliamentaryContent(mr, nov-2011) only context typed # interfaces.IBungeniParliamentaryContent should ever get here! # For some reason signatory instances are also being passed in here. # Remove try/except wrapper here, once that is fixed (leaving the assert). try: m = "PI context [%s] for get_mask must specify a type attr" % (context) assert hasattr(context, "type"), m except AssertionError: log.error(m) return None path = capi.get_path_for("registry") config = ConfigParser() config.readfp(open(os.path.join(path, "config.ini"))) try: return config.get("types", context.type) except NoOptionError: return None
def load_workflow(name, path_custom_workflows=capi.get_path_for("workflows")): """Setup the Workflow instance, from XML definition, for named workflow. """ # load / register as utility / retrieve # #if not component.queryUtility(IWorkflow, name): !+BREAKS_DOCTESTS if not get_workflow._WORKFLOWS.has_key(name): wf = xmlimport.load(path_custom_workflows, name) log.debug("Loading WORKFLOW: %s %s" % (name, wf)) # debug info for state_key, state in wf.states.items(): log.debug(" STATE: %s %s" % (state_key, state)) for p in state.permissions: log.debug(" %s" % (p, )) # Workflow instances as utilities provideUtilityWorkflow(wf, name) else: wf = get_workflow(name) log.warn("Already Loaded WORKFLOW : %s %s" % (name, wf))
def load_workflow(name, path_custom_workflows=capi.get_path_for("workflows")): """Setup the Workflow instance, from XML definition, for named workflow. """ # load / register as utility / retrieve # #if not component.queryUtility(IWorkflow, name): !+BREAKS_DOCTESTS if not get_workflow._WORKFLOWS.has_key(name): wf = xmlimport.load(path_custom_workflows, name) log.debug("Loading WORKFLOW: %s %s" % (name, wf)) # debug info for state_key, state in wf.states.items(): log.debug(" STATE: %s %s" % (state_key, state)) for p in state.permissions: log.debug(" %s" % (p,)) # Workflow instances as utilities provideUtilityWorkflow(wf, name) else: wf = get_workflow(name) log.warn("Already Loaded WORKFLOW : %s %s" % (name, wf))
def load_workflow(name, iface, path_custom_workflows=capi.get_path_for("workflows") ): """Setup the Workflow instance, from XML definition, for named workflow. """ # # load / register as utility / retrieve # #if not component.queryUtility(IWorkflow, name): !+BREAKS_DOCTESTS if not _WORKFLOWS.has_key(name): wf = xmlimport.load(path_custom_workflows, name) log.debug("Loading WORKFLOW: %s %s" % (name, wf)) # debug info for state_key, state in wf.states.items(): log.debug(" STATE: %s %s" % (state_key, state)) for p in state.permissions: log.debug(" %s" % (p,)) else: wf = get_workflow(name) log.debug("Already Loaded WORKFLOW : %s %s" % (name, wf)) # We "mark" the supplied iface with IWorkflowed, as a means to mark type # the iface is applied (that, at this point, may not be unambiguously # determined). This has the advantage of then being able to # register/lookup adapters on only this single interface. # # A simple way to "mark" the supplied iface with IWorkflowed is to # "add" IWorkflowed as an inheritance ancestor to iface: if (IWorkflowed not in iface.__bases__): iface.__bases__ = (IWorkflowed,) + iface.__bases__ # register related adapters # Workflow instances as utilities provideUtilityWorkflow(wf, name) # Workflows are also the factory of own AdaptedWorkflows provideAdapterWorkflow(wf, iface) # !+VERSION_WORKFLOW(mr, apr-2011) if name == "version": component.provideAdapter(bungeni.core.version.ContextVersioned, (interfaces.IVersionable,), bungeni.core.interfaces.IVersioned)
def load_workflow(name, iface, path_custom_workflows=capi.get_path_for("workflows")): """Setup the Workflow instance, from XML definition, for named workflow. """ # # load / register as utility / retrieve # #if not component.queryUtility(IWorkflow, name): !+BREAKS_DOCTESTS if not _WORKFLOWS.has_key(name): wf = xmlimport.load(path_custom_workflows, name) log.debug("Loading WORKFLOW: %s %s" % (name, wf)) # debug info for state_key, state in wf.states.items(): log.debug(" STATE: %s %s" % (state_key, state)) for p in state.permissions: log.debug(" %s" % (p, )) else: wf = get_workflow(name) log.debug("Already Loaded WORKFLOW : %s %s" % (name, wf)) # We "mark" the supplied iface with IWorkflowed, as a means to mark type # the iface is applied (that, at this point, may not be unambiguously # determined). This has the advantage of then being able to # register/lookup adapters on only this single interface. # # A simple way to "mark" the supplied iface with IWorkflowed is to # "add" IWorkflowed as an inheritance ancestor to iface: if (IWorkflowed not in iface.__bases__): iface.__bases__ = (IWorkflowed, ) + iface.__bases__ # register related adapters # Workflow instances as utilities provideUtilityWorkflow(wf, name) # Workflows are also the factory of own AdaptedWorkflows provideAdapterWorkflow(wf, iface) # !+VERSION_WORKFLOW(mr, apr-2011) if name == "version": component.provideAdapter(bungeni.core.version.ContextVersioned, (interfaces.IVersionable, ), bungeni.core.interfaces.IVersioned)
def buildTerms(self): vocabulary_terms = [] template_folder = capi.get_path_for("reporting", "templates", self.template_folder ) if not os.path.exists(template_folder): log.error("Directory for XHTML templates does not exist: %s", template_folder ) return file_list = filter(lambda fname: fname.endswith(".html"), os.listdir(template_folder) ) for file_name in file_list: file_path = "/".join([template_folder, file_name]) vocabulary_terms.append( vocabulary.SimpleTerm(file_path, token=hashlib.md5(file_name).hexdigest(), title=self.getTitle(file_path) ) ) return vocabulary_terms
def file_path(self): return capi.get_path_for("vocabularies", self.file_name)
def load_workflow(name, iface, path_custom_workflows=capi.get_path_for("workflows") ): """Setup the Workflow instance, from XML definition, for named workflow. """ # # load / register as utility / retrieve # #if not component.queryUtility(IWorkflow, name): !+BREAKS_DOCTESTS if not _WORKFLOWS.has_key(name): wf = xmlimport.load(path_custom_workflows, name) log.debug("Loading WORKFLOW: %s %s" % (name, wf)) # debug info for state_key, state in wf.states.items(): log.debug(" STATE: %s %s" % (state_key, state)) for p in state.permissions: log.debug(" %s" % (p,)) else: wf = get_workflow(name) log.debug("Already Loaded WORKFLOW : %s %s" % (name, wf)) # We "mark" the supplied iface with IWorkflowed, as a means to mark type # the iface is applied (that, at this point, may not be unambiguously # determined). This has the advantage of then being able to # register/lookup adapters on only this single interface. # # Normally this is done by applying the iface to the target type, but # at this point may may not be unambiguously determined--so, we instead # "mark" the interface itself... by simply adding IWorkflowed as an # inheritance ancestor to iface (if it is not already): if (IWorkflowed not in iface.__bases__): iface.__bases__ = (IWorkflowed,) + iface.__bases__ # apply customizations, features as per configuration of the document type def camel(name): """Convert an underscore-separated word to CamelCase.""" return "".join([ s.capitalize() for s in name.split("_") ]) from bungeni.models import domain, schema, orm def get_domain_kls(workflow_name): """Infer a workflow's target domain kls from the workflow file name, following underscore naming to camel case convention; names that do not follow the convention are custom handled, as per mapping below. """ # !+ should state it explicitly as a param? # !+ problem with multiple types sharing same workflow e.g. # UserAddress, GroupAddress kls_name = camel( get_domain_kls.non_conventional.get(workflow_name, workflow_name)) return getattr(domain, kls_name) get_domain_kls.non_conventional = { "address": "user_address", # "group_address"? "agendaitem": "agenda_item", "attachedfile": "attached_file", "event": "event_item", "groupsitting": "group_sitting", "tableddocument": "tabled_document", } if wf.auditable or wf.versionable: kls = get_domain_kls(name) if wf.versionable: kls = domain.versionable(kls) elif wf.auditable: kls = domain.auditable(kls) schema.configurable_schema(kls) orm.configurable_mappings(kls) bungeni.core.audit.set_auditor(kls) kn = kls.__name__ # register related adapters # Workflow instances as utilities provideUtilityWorkflow(wf, name) # Workflows are also the factory of own AdaptedWorkflows provideAdapterWorkflow(wf, iface) # !+VERSION_WORKFLOW(mr, apr-2011) if name == "version": component.provideAdapter(bungeni.core.version.ContextVersioned, (interfaces.IVersionable,), bungeni.core.interfaces.IVersioned)
def get_mask(context): path = capi.get_path_for("registry") config = ConfigParser() config.readfp(open(os.path.join(path,"config.ini"))) type = context.type return config.get("types",type)
from bungeni.alchemist.model import ( #ModelDescriptor, IModelDescriptor, #queryModelDescriptor, Field, show, hide, norm_sorted, ) from bungeni.utils.capi import capi, bungeni_custom_errors from bungeni.ui.utils import debug # constants from bungeni.ui.descriptor import descriptor as DESCRIPTOR_MODULE CUSTOM_PATH = capi.get_path_for("forms", "ui.xml") DESCRIPTOR_CLASSNAME_POSTFIX = "Descriptor" ROLES_DEFAULT = " ".join(Field._roles) INDENT = " " * 4 # utils def read_custom(): try: return open(CUSTOM_PATH, "r").read().decode("utf-8") except IOError: return '<NO-SUCH-FILE path="%s" />' % (CUSTOM_PATH) def write_custom(old_content, content): print "*** OVERWRITING localization file: %s" % (CUSTOM_PATH)
def setUp(self): # register translations from bungeni.utils.capi import capi #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"))) import index # ensure indexing facilities are setup(lazy) index.setupFieldDefinitions(index.indexer) sm = site.LocalSiteManager(self.context) self.context.setSiteManager(sm) 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=_(u"Workspace"), description=_(u"Current parliamentary activity"), default_name="documents", ) alsoProvides(workspace, interfaces.ISearchableSection) workspace["documents"] = Section( title=_(u"documents"), description=_(u"documents"), default_name="inbox", marker = interfaces.IWorkspaceDocuments, ) workspace["documents"]["draft"] = WorkspaceContainer( tab_type="draft", title=_("draft"), description=_("draft documents"), marker=interfaces.IWorkspaceDraft ) workspace["documents"]["inbox"] = WorkspaceContainer( tab_type="inbox", title=_("inbox"), description=_("incoming documents"), marker=interfaces.IWorkspaceInbox ) workspace["documents"]["sent"] = WorkspaceContainer( tab_type="sent", title=_("sent"), description=_("sent documents"), marker=interfaces.IWorkspaceSent ) workspace["documents"]["archive"] = WorkspaceContainer( tab_type="archive", title=_("archive"), description=_("archived documents"), marker=interfaces.IWorkspaceArchive ) workspace["scheduling"] = Section( title=_(u"Scheduling"), description=_(u"Scheduling"), default_name="index", marker=interfaces.IWorkspaceScheduling, ) workspace["scheduling"]["committees"] = QueryContent( container_getter(get_current_parliament, 'committees'), title=_(u"Committees"), marker=interfaces.ICommitteeAddContext, description=_(u"Committee schedules") ) workspace["scheduling"]["sittings"] = QueryContent( container_getter(get_current_parliament, 'sittings'), title=_(u"Sittings"), description=_(u"Plenary Sittings") ) # Proof-of-concept: support for selective inclusion in breadcrumb trail: # a view marked with an attribute __crumb__=False is NOT included in # the breadcrumb trail (see ui/viewlets/navigation.py) #self.context["workspace"].__crumb__ = False business = self.context["business"] = Section( title=_(u"Business"), description=_(u"Daily operations of the parliament"), default_name="business-index") members = self.context["members"] = Section( title=_(u"Members"), description=_(u"Records of members of parliament"), default_name="members-index") archive = self.context["archive"] = Section( title=_(u"Archive"), description=_(u"Parliament records and documents"), default_name="archive-index") alsoProvides(archive, interfaces.ISearchableSection) #!+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) alsoProvides(admin, interfaces.ISearchableSection) # business section business["whats-on"] = Section( title=_(u"What's on"), description=_(u"Current parliamentary activity"), default_name="whats-on") alsoProvides(business, interfaces.ISearchableSection) business[u"committees"] = QueryContent( container_getter(get_current_parliament, 'committees'), title=_(u"Committees"), marker=interfaces.ICommitteeAddContext, description=_(u"View committees created by the current parliament")) business[u"bills"] = QueryContent( container_getter(get_current_parliament, 'bills'), title=_(u"Bills"), marker=interfaces.IBillAddContext, description=_(u"View bills introduced in the current parliament")) business[u"questions"] = QueryContent( container_getter(get_current_parliament, 'questions'), title=_(u"Questions"), marker=interfaces.IQuestionAddContext, description=_(u"View questions tabled in the current parliament")) business[u"motions"] = QueryContent( container_getter(get_current_parliament, 'motions'), title=_(u"Motions"), marker=interfaces.IMotionAddContext, description=_(u"View motions moved in the current parliament")) business[u"tableddocuments"] = QueryContent( container_getter(get_current_parliament, 'tableddocuments'), title=_(u"Tabled documents"), marker=interfaces.ITabledDocumentAddContext, description=\ _(u"View the documents tabled in the current parliament") ) business[u"agendaitems"] = QueryContent( container_getter(get_current_parliament, 'agendaitems'), title=_(u"Agenda items"), marker=interfaces.IAgendaItemAddContext, description=_(u"View the agenda items of the current parliament")) # sessions = business[u"sessions"] = QueryContent( # container_getter(get_current_parliament, 'sessions'), # title=_(u"Sessions"), # marker=interfaces.ISessionAddContext, # description=_(u"View the sessions of the current parliament.")) business[u"sittings"] = QueryContent( container_getter(get_current_parliament, 'sittings'), title=_(u"Sittings"), description=_(u"View the sittings of the current parliament")) #Parliamentary reports business[u"preports"] = QueryContent( container_getter(get_current_parliament, 'preports'), title=_(u"Publications"), marker=interfaces.IReportAddContext, description=\ _(u"browse and download parliamentary publications") ) # members section members[u"current"] = QueryContent( container_getter(get_current_parliament, 'parliamentmembers'), title=_(u"Current"), description=_(u"View current parliament members (MPs)")) alsoProvides(members, interfaces.ISearchableSection) members[u"political-groups"] = QueryContent( container_getter(get_current_parliament, 'politicalgroups'), title=_(u"Political groups"), description=_(u"View current political groups")) # archive records = archive[u"browse"] = Section( title=_(u"Browse archives"), description=_(u"Browse records from the archive"), default_name="browse-archive") documents = archive["documents"] = Section( title=_(u"Documents"), description=_(u"Browse documents in the archive"), default_name="browse-archive") def to_locatable_container(domain_class, *domain_containers): provideAdapter(location.ContainerLocation(*domain_containers), (implementedBy(domain_class), ILocation)) # archive/records documents[u"bills"] = domain.BillContainer() to_locatable_container(domain.Bill, documents[u"bills"]) documents[u"motions"] = domain.MotionContainer() to_locatable_container(domain.Motion, documents[u"motions"]) documents[u"questions"] = domain.QuestionContainer() to_locatable_container(domain.Question, documents[u"questions"]) documents[u"agendaitems"] = domain.AgendaItemContainer() to_locatable_container(domain.AgendaItem, documents[u"agendaitems"]) documents[u"tableddocuments"] = domain.TabledDocumentContainer() to_locatable_container(domain.TabledDocument, documents[u"tableddocuments"] ) documents[u"reports"] = domain.ReportContainer() to_locatable_container(domain.Report, documents[u"reports"]) #provideAdapter(location.ContainerLocation(tableddocuments, documents[u"reports"]), # (implementedBy(domain.Report), ILocation)) records[u"parliaments"] = domain.ParliamentContainer() to_locatable_container(domain.Parliament, records[u"parliaments"]) records[u"politicalgroups"] = domain.PoliticalGroupContainer() to_locatable_container(domain.PoliticalGroup, records[u"politicalgroups"] ) records[u"constituencies"] = domain.ConstituencyContainer() to_locatable_container(domain.Constituency, records[u"constituencies"]) records[u"committees"] = domain.CommitteeContainer() to_locatable_container(domain.Committee, records[u"committees"]) #records[u"mps"] = domain.MemberOfParliamentContainer() #provideAdapter(location.ContainerLocation(records[u"mps"]), # (implementedBy(domain.MemberOfParliament), ILocation)) ########## # Admin User Interface # Administration section content = admin["content"] = Section( title=_(u"Content"), description=_(u"browse bungeni content"), marker=model_interfaces.IBungeniAdmin, default_name="browse-admin") admin["settings"] = Section( title=_(u"Settings"), description=_(u"settings"), marker=model_interfaces.IBungeniAdmin, default_name="settings") admin["email-settings"] = Section( title=_(u"email settings"), description=_(u"manage email settings"), marker=model_interfaces.IBungeniAdmin, default_name="email-settings") admin["xapian-settings"] = Section( title=_(u"search index settings"), description=_(u"manage search index settings"), marker=model_interfaces.IBungeniAdmin, default_name="xapian-settings") admin["registry-settings"] = Section( title=_(u"registry settings"), description=_(u"manage registry settings"), marker=model_interfaces.IBungeniAdmin, default_name="registry-settings") content[u"parliaments"] = domain.ParliamentContainer() to_locatable_container(domain.Parliament, content[u"parliaments"]) content[u"offices"] = domain.OfficeContainer() to_locatable_container(domain.Office, content[u"offices"]) content[u'users'] = domain.UserContainer() to_locatable_container(domain.User, content[u"users"]) content[u'headings'] = domain.HeadingContainer() to_locatable_container(domain.Heading, content[u"headings"]) content[u"constituencies"] = domain.ConstituencyContainer() to_locatable_container(domain.Constituency, content[u"constituencies"]) content[u"provinces"] = domain.ProvinceContainer() to_locatable_container(domain.Province, content[u"provinces"]) content[u"regions"] = domain.RegionContainer() to_locatable_container(domain.Region, content[u"regions"]) content[u"parties"] = domain.PoliticalPartyContainer() to_locatable_container(domain.PoliticalParty, content[u"parties"]) ''' !+TYPES_CUSTOM
#ModelDescriptor, IModelDescriptor, #queryModelDescriptor, Field, show, hide, norm_sorted, ) from bungeni.utils.capi import capi, bungeni_custom_errors from bungeni.ui.utils import debug # constants from bungeni.ui.descriptor import descriptor as DESCRIPTOR_MODULE CUSTOM_PATH = capi.get_path_for("forms", "ui.xml") DESCRIPTOR_CLASSNAME_POSTFIX = "Descriptor" ROLES_DEFAULT = " ".join(Field._roles) INDENT = " " * 4 # utils def read_custom(): try: return open(CUSTOM_PATH, "r").read().decode("utf-8") except IOError: return '<NO-SUCH-FILE path="%s" />' % (CUSTOM_PATH)
def setUp(self): # register translations from bungeni.utils.capi import capi #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"))) import index # ensure indexing facilities are setup(lazy) index.setupFieldDefinitions(index.indexer) sm = site.LocalSiteManager(self.context) self.context.setSiteManager(sm) 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=_(u"Workspace"), description=_(u"Current parliamentary activity"), default_name="documents", ) alsoProvides(workspace, interfaces.ISearchableSection) workspace["documents"] = Section( title=_(u"documents"), description=_(u"documents"), default_name="inbox", marker=interfaces.IWorkspaceDocuments, ) workspace["documents"]["draft"] = WorkspaceContainer( tab_type="draft", title=_("draft"), description=_("draft documents"), marker=interfaces.IWorkspaceDraft) workspace["documents"]["inbox"] = WorkspaceContainer( tab_type="inbox", title=_("inbox"), description=_("incoming documents"), marker=interfaces.IWorkspaceInbox) workspace["documents"]["sent"] = WorkspaceContainer( tab_type="sent", title=_("sent"), description=_("sent documents"), marker=interfaces.IWorkspaceSent) workspace["documents"]["archive"] = WorkspaceContainer( tab_type="archive", title=_("archive"), description=_("archived documents"), marker=interfaces.IWorkspaceArchive) workspace["scheduling"] = Section( title=_(u"Scheduling"), description=_(u"Scheduling"), default_name="index", marker=interfaces.IWorkspaceScheduling, ) workspace["scheduling"]["committees"] = QueryContent( container_getter(get_current_parliament, 'committees'), title=_(u"Committees"), marker=interfaces.ICommitteeAddContext, description=_(u"Committee schedules")) workspace["scheduling"]["sittings"] = QueryContent( container_getter(get_current_parliament, 'sittings'), title=_(u"Sittings"), description=_(u"Plenary Sittings")) # Proof-of-concept: support for selective inclusion in breadcrumb trail: # a view marked with an attribute __crumb__=False is NOT included in # the breadcrumb trail (see ui/viewlets/navigation.py) #self.context["workspace"].__crumb__ = False business = self.context["business"] = Section( title=_(u"Business"), description=_(u"Daily operations of the parliament"), default_name="business-index") members = self.context["members"] = Section( title=_(u"Members"), description=_(u"Records of members of parliament"), default_name="members-index") archive = self.context["archive"] = Section( title=_(u"Archive"), description=_(u"Parliament records and documents"), default_name="archive-index") alsoProvides(archive, interfaces.ISearchableSection) #!+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) alsoProvides(admin, interfaces.ISearchableSection) # business section business["whats-on"] = Section( title=_(u"What's on"), description=_(u"Current parliamentary activity"), default_name="whats-on") alsoProvides(business, interfaces.ISearchableSection) business[u"committees"] = QueryContent( container_getter(get_current_parliament, 'committees'), title=_(u"Committees"), marker=interfaces.ICommitteeAddContext, description=_( u"View committees created by the current parliament")) business[u"bills"] = QueryContent( container_getter(get_current_parliament, 'bills'), title=_(u"Bills"), marker=interfaces.IBillAddContext, description=_(u"View bills introduced in the current parliament")) business[u"questions"] = QueryContent( container_getter(get_current_parliament, 'questions'), title=_(u"Questions"), marker=interfaces.IQuestionAddContext, description=_(u"View questions tabled in the current parliament")) business[u"motions"] = QueryContent( container_getter(get_current_parliament, 'motions'), title=_(u"Motions"), marker=interfaces.IMotionAddContext, description=_(u"View motions moved in the current parliament")) business[u"tableddocuments"] = QueryContent( container_getter(get_current_parliament, 'tableddocuments'), title=_(u"Tabled documents"), marker=interfaces.ITabledDocumentAddContext, description=\ _(u"View the documents tabled in the current parliament") ) business[u"agendaitems"] = QueryContent( container_getter(get_current_parliament, 'agendaitems'), title=_(u"Agenda items"), marker=interfaces.IAgendaItemAddContext, description=_(u"View the agenda items of the current parliament")) # sessions = business[u"sessions"] = QueryContent( # container_getter(get_current_parliament, 'sessions'), # title=_(u"Sessions"), # marker=interfaces.ISessionAddContext, # description=_(u"View the sessions of the current parliament.")) business[u"sittings"] = QueryContent( container_getter(get_current_parliament, 'sittings'), title=_(u"Sittings"), description=_(u"View the sittings of the current parliament")) #Parliamentary reports business[u"preports"] = QueryContent( container_getter(get_current_parliament, 'preports'), title=_(u"Publications"), marker=interfaces.IReportAddContext, description=\ _(u"browse and download parliamentary publications") ) # members section members[u"current"] = QueryContent( container_getter(get_current_parliament, 'parliamentmembers'), title=_(u"Current"), description=_(u"View current parliament members (MPs)")) alsoProvides(members, interfaces.ISearchableSection) members[u"political-groups"] = QueryContent( container_getter(get_current_parliament, 'politicalgroups'), title=_(u"Political groups"), description=_(u"View current political groups")) # archive records = archive[u"browse"] = Section( title=_(u"Browse archives"), description=_(u"Browse records from the archive"), default_name="browse-archive") documents = archive["documents"] = Section( title=_(u"Documents"), description=_(u"Browse documents in the archive"), default_name="browse-archive") def to_locatable_container(domain_class, *domain_containers): provideAdapter(location.ContainerLocation(*domain_containers), (implementedBy(domain_class), ILocation)) # archive/records documents[u"bills"] = domain.BillContainer() to_locatable_container(domain.Bill, documents[u"bills"]) documents[u"motions"] = domain.MotionContainer() to_locatable_container(domain.Motion, documents[u"motions"]) documents[u"questions"] = domain.QuestionContainer() to_locatable_container(domain.Question, documents[u"questions"]) documents[u"agendaitems"] = domain.AgendaItemContainer() to_locatable_container(domain.AgendaItem, documents[u"agendaitems"]) documents[u"tableddocuments"] = domain.TabledDocumentContainer() to_locatable_container(domain.TabledDocument, documents[u"tableddocuments"]) documents[u"reports"] = domain.ReportContainer() to_locatable_container(domain.Report, documents[u"reports"]) #provideAdapter(location.ContainerLocation(tableddocuments, documents[u"reports"]), # (implementedBy(domain.Report), ILocation)) records[u"parliaments"] = domain.ParliamentContainer() to_locatable_container(domain.Parliament, records[u"parliaments"]) records[u"politicalgroups"] = domain.PoliticalGroupContainer() to_locatable_container(domain.PoliticalGroup, records[u"politicalgroups"]) records[u"constituencies"] = domain.ConstituencyContainer() to_locatable_container(domain.Constituency, records[u"constituencies"]) records[u"committees"] = domain.CommitteeContainer() to_locatable_container(domain.Committee, records[u"committees"]) #records[u"mps"] = domain.MemberOfParliamentContainer() #provideAdapter(location.ContainerLocation(records[u"mps"]), # (implementedBy(domain.MemberOfParliament), ILocation)) ########## # Admin User Interface # Administration section content = admin["content"] = Section( title=_(u"Content"), description=_(u"browse bungeni content"), marker=model_interfaces.IBungeniAdmin, default_name="browse-admin") admin["settings"] = Section(title=_(u"Settings"), description=_(u"settings"), marker=model_interfaces.IBungeniAdmin, default_name="settings") admin["email-settings"] = Section( title=_(u"email settings"), description=_(u"manage email settings"), marker=model_interfaces.IBungeniAdmin, default_name="email-settings") admin["xapian-settings"] = Section( title=_(u"search index settings"), description=_(u"manage search index settings"), marker=model_interfaces.IBungeniAdmin, default_name="xapian-settings") admin["registry-settings"] = Section( title=_(u"registry settings"), description=_(u"manage registry settings"), marker=model_interfaces.IBungeniAdmin, default_name="registry-settings") content[u"parliaments"] = domain.ParliamentContainer() to_locatable_container(domain.Parliament, content[u"parliaments"]) content[u"offices"] = domain.OfficeContainer() to_locatable_container(domain.Office, content[u"offices"]) content[u'users'] = domain.UserContainer() to_locatable_container(domain.User, content[u"users"]) content[u'headings'] = domain.HeadingContainer() to_locatable_container(domain.Heading, content[u"headings"]) content[u"constituencies"] = domain.ConstituencyContainer() to_locatable_container(domain.Constituency, content[u"constituencies"]) content[u"provinces"] = domain.ProvinceContainer() to_locatable_container(domain.Province, content[u"provinces"]) content[u"regions"] = domain.RegionContainer() to_locatable_container(domain.Region, content[u"regions"]) content[u"parties"] = domain.PoliticalPartyContainer() to_locatable_container(domain.PoliticalParty, content[u"parties"]) ''' !+TYPES_CUSTOM
def load_workflow(name, iface, path_custom_workflows=capi.get_path_for("workflows")): """Setup the Workflow instance, from XML definition, for named workflow. """ # # load / register as utility / retrieve # # if not component.queryUtility(IWorkflow, name): !+BREAKS_DOCTESTS if not _WORKFLOWS.has_key(name): wf = xmlimport.load(path_custom_workflows, name) log.debug("Loading WORKFLOW: %s %s" % (name, wf)) # debug info for state_key, state in wf.states.items(): log.debug(" STATE: %s %s" % (state_key, state)) for p in state.permissions: log.debug(" %s" % (p,)) else: wf = get_workflow(name) log.debug("Already Loaded WORKFLOW : %s %s" % (name, wf)) # We "mark" the supplied iface with IWorkflowed, as a means to mark type # the iface is applied (that, at this point, may not be unambiguously # determined). This has the advantage of then being able to # register/lookup adapters on only this single interface. # # Normally this is done by applying the iface to the target type, but # at this point may may not be unambiguously determined--so, we instead # "mark" the interface itself... by simply adding IWorkflowed as an # inheritance ancestor to iface (if it is not already): if IWorkflowed not in iface.__bases__: iface.__bases__ = (IWorkflowed,) + iface.__bases__ # apply customizations, features as per configuration of the document type def camel(name): """Convert an underscore-separated word to CamelCase.""" return "".join([s.capitalize() for s in name.split("_")]) from bungeni.models import domain, schema, orm def get_domain_kls(workflow_name): """Infer a workflow's target domain kls from the workflow file name, following underscore naming to camel case convention; names that do not follow the convention are custom handled, as per mapping below. """ # !+ should state it explicitly as a param? # !+ problem with multiple types sharing same workflow e.g. # UserAddress, GroupAddress kls_name = camel(get_domain_kls.non_conventional.get(workflow_name, workflow_name)) return getattr(domain, kls_name) # !+RENAME_TO_CONVENTION get_domain_kls.non_conventional = { "address": "user_address", # "group_address"? "agendaitem": "agenda_item", "attachedfile": "attached_file", "event": "event_item", "groupsitting": "group_sitting", "tableddocument": "tabled_document", } if wf.auditable or wf.versionable: kls = get_domain_kls(name) if wf.versionable: kls = domain.versionable(kls) elif wf.auditable: kls = domain.auditable(kls) schema.configurable_schema(kls) orm.configurable_mappings(kls) bungeni.core.audit.set_auditor(kls) kn = kls.__name__ # register related adapters # Workflow instances as utilities provideUtilityWorkflow(wf, name) # Workflows are also the factory of own AdaptedWorkflows provideAdapterWorkflow(wf, iface)
def get_mask(context): path = capi.get_path_for("registry") config = ConfigParser() config.readfp(open(os.path.join(path, "config.ini"))) type = context.type return config.get("types", type)