# HG changeset patch # User Sylvain Thénault # Date 1245415324 -7200 # Node ID a25859917ccc65e60240a86de5fc3813fbe76f10 # Parent 3e1d2ab5f8c0a436f36996f9516a25937417075d stop using meta attribute from yams schema. Use instead sets defining meta relations and another defining schema types. Refactor various schema view based on this diff -r 3e1d2ab5f8c0 -r a25859917ccc devtools/testlib.py --- a/devtools/testlib.py Thu Jun 18 21:01:55 2009 +0200 +++ b/devtools/testlib.py Fri Jun 19 14:42:04 2009 +0200 @@ -44,7 +44,7 @@ # compute how many entities by type we need to be able to satisfy relation constraint relmap = {} for rschema in schema.relations(): - if rschema.meta or rschema.is_final(): # skip meta relations + if rschema.is_final(): continue for subj, obj in rschema.iter_rdefs(): card = rschema.rproperty(subj, obj, 'cardinality') diff -r 3e1d2ab5f8c0 -r a25859917ccc entities/schemaobjs.py --- a/entities/schemaobjs.py Thu Jun 18 21:01:55 2009 +0200 +++ b/entities/schemaobjs.py Fri Jun 19 14:42:04 2009 +0200 @@ -25,8 +25,6 @@ def dc_long_title(self): stereotypes = [] _ = self.req._ - if self.meta: - stereotypes.append(_('meta')) if self.final: stereotypes.append(_('final')) if stereotypes: diff -r 3e1d2ab5f8c0 -r a25859917ccc entity.py --- a/entity.py Thu Jun 18 21:01:55 2009 +0200 +++ b/entity.py Fri Jun 19 14:42:04 2009 +0200 @@ -485,7 +485,7 @@ assert self.has_eid() execute = self.req.execute for rschema in self.e_schema.subject_relations(): - if rschema.meta or rschema.is_final(): + if rschema.is_final() or rschema.meta: continue # skip already defined relations if getattr(self, rschema.type): diff -r 3e1d2ab5f8c0 -r a25859917ccc goa/dbinit.py --- a/goa/dbinit.py Thu Jun 18 21:01:55 2009 +0200 +++ b/goa/dbinit.py Fri Jun 19 14:42:04 2009 +0200 @@ -86,14 +86,13 @@ def init_persistent_schema(ssession, schema): execute = ssession.unsafe_execute rql = ('INSERT CWEType X: X name %(name)s, X description %(descr)s,' - 'X final FALSE, X meta %(meta)s') + 'X final FALSE') eschema = schema.eschema('CWEType') - execute(rql, {'name': u'CWEType', 'descr': unicode(eschema.description), - 'meta': eschema.meta}) + execute(rql, {'name': u'CWEType', 'descr': unicode(eschema.description)}) for eschema in schema.entities(): if eschema.is_final() or eschema == 'CWEType': continue - execute(rql, {'name': unicode(eschema), 'meta': eschema.meta, + execute(rql, {'name': unicode(eschema), 'descr': unicode(eschema.description)}) def insert_versions(ssession, config): diff -r 3e1d2ab5f8c0 -r a25859917ccc goa/tools/generate_schema_img.py --- a/goa/tools/generate_schema_img.py Thu Jun 18 21:01:55 2009 +0200 +++ b/goa/tools/generate_schema_img.py Fri Jun 19 14:42:04 2009 +0200 @@ -8,6 +8,7 @@ import sys from os.path import dirname, abspath, join from yams import schema2dot +from cubicweb.web.views.schema import SKIP_TYPES APPLROOT = abspath(join(dirname(abspath(__file__)), '..')) @@ -22,9 +23,8 @@ skip_rels = ('owned_by', 'created_by', 'identity', 'is', 'is_instance_of') path = join(APPLROOT, 'data', 'schema.png') schema2dot.schema2dot(schema, path, #size=size, - skiprels=skip_rels, skipmeta=True) + skiptypes=SKIP_TYPES) print 'generated', path path = join(APPLROOT, 'data', 'metaschema.png') -schema2dot.schema2dot(schema, path, #size=size, - skiprels=skip_rels, skipmeta=False) +schema2dot.schema2dot(schema, path) print 'generated', path diff -r 3e1d2ab5f8c0 -r a25859917ccc goa/tools/laxctl.py --- a/goa/tools/laxctl.py Thu Jun 18 21:01:55 2009 +0200 +++ b/goa/tools/laxctl.py Fri Jun 19 14:42:04 2009 +0200 @@ -19,6 +19,8 @@ from logilab.common.clcommands import Command, register_commands, main_run from cubicweb.common.uilib import remove_html_tags +from cubicweb.web.views.schema import SKIP_TYPES + APPLROOT = osp.abspath(osp.join(osp.dirname(osp.abspath(__file__)), '..')) @@ -57,14 +59,12 @@ assert not args, 'no argument expected' from yams import schema2dot schema = self.vreg.schema - skip_rels = ('owned_by', 'created_by', 'identity', 'is', 'is_instance_of') path = osp.join(APPLROOT, 'data', 'schema.png') schema2dot.schema2dot(schema, path, #size=size, - skiprels=skip_rels, skipmeta=True) + skiptypes=SKIP_TYPES) print 'generated', path path = osp.join(APPLROOT, 'data', 'metaschema.png') - schema2dot.schema2dot(schema, path, #size=size, - skiprels=skip_rels, skipmeta=False) + schema2dot.schema2dot(schema, path) print 'generated', path diff -r 3e1d2ab5f8c0 -r a25859917ccc schema.py --- a/schema.py Thu Jun 18 21:01:55 2009 +0200 +++ b/schema.py Fri Jun 19 14:42:04 2009 +0200 @@ -6,6 +6,7 @@ :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ __docformat__ = "restructuredtext en" +_ = unicode import re from logging import getLogger @@ -30,11 +31,24 @@ schema.use_py_datetime() nodes.use_py_datetime() -_ = unicode +# set of meta-relations available for every entity types +META_RELATIONS_TYPES = set(( + 'owned_by', 'created_by', 'is', 'is_instance_of', 'identity', + 'eid', 'creation_date', 'modification_date', 'has_text', + ))) -BASEGROUPS = ('managers', 'users', 'guests', 'owners') +# set of entity and relation types used to build the schema +SCHEMA_TYPES = set(( + 'CWEType', 'CWRType', 'CWAttribute', 'CWRelation', + 'CWConstraint', 'CWConstraintType', 'RQLExpression', + 'relation_type', 'from_entity', 'to_entity', + 'constrained_by', 'cstrtype', + # XXX those are not really "schema" entity types + # but we usually don't want them as @* targets + 'CWProperty', 'CWPermission', 'State', 'Transition', + )) -LOGGER = getLogger('cubicweb.schemaloader') +_LOGGER = getLogger('cubicweb.schemaloader') # schema entities created from serialized schema have an eid rproperty ybo.ETYPE_PROPERTIES += ('eid',) @@ -68,6 +82,7 @@ etypes = () if '*' in etype: etypes += tuple(self._wildcard_etypes(schema)) + # XXX deprecate, too clumsy if '@' in etype: etypes += tuple(system_etypes(schema)) return etypes @@ -242,7 +257,7 @@ """return system entity types only: skip final, schema and application entities """ for eschema in schema.entities(): - if eschema.is_final() or eschema.schema_entity() or not eschema.meta: + if eschema.is_final() or eschema.schema_entity(): continue yield eschema.type @@ -321,7 +336,7 @@ def schema_entity(self): """return True if this entity type is used to build the schema""" - return self.type in self.schema.schema_entity_types() + return self.type in SCHEMA_TYPES def check_perm(self, session, action, eid=None): # NB: session may be a server session or a request object @@ -358,6 +373,9 @@ eid = getattr(rdef, 'eid', None) self.eid = eid + @property + def meta(self): + return self.type in META_RELATIONS_TYPES def update(self, subjschema, objschema, rdef): super(CubicWebRelationSchema, self).update(subjschema, objschema, rdef) @@ -396,8 +414,8 @@ (target == 'object' and card[1]) def schema_relation(self): - return self.type in ('relation_type', 'from_entity', 'to_entity', - 'constrained_by', 'cstrtype') + """return True if this relation type is used to build the schema""" + return self.type in SCHEMA_TYPES def physical_mode(self): """return an appropriate mode for physical storage of this relation type: @@ -457,14 +475,6 @@ rschema.final = False rschema.set_default_groups() - def schema_entity_types(self): - """return the list of entity types used to build the schema""" - return frozenset(('CWEType', 'CWRType', 'CWAttribute', 'CWRelation', - 'CWConstraint', 'CWConstraintType', 'RQLExpression', - # XXX those are not really "schema" entity types - # but we usually don't want them as @* targets - 'CWProperty', 'CWPermission', 'State', 'Transition')) - def add_entity_type(self, edef): edef.name = edef.name.encode() edef.name = bw_normalize_etype(edef.name) @@ -636,8 +646,8 @@ raise RQLSyntaxError(expression) for mainvar in mainvars.split(','): if len(self.rqlst.defined_vars[mainvar].references()) <= 2: - LOGGER.warn('You did not use the %s variable in your RQL expression %s', - mainvar, self) + _LOGGER.warn('You did not use the %s variable in your RQL ' + 'expression %s', mainvar, self) def __str__(self): return self.full_rql diff -r 3e1d2ab5f8c0 -r a25859917ccc schemaviewer.py --- a/schemaviewer.py Thu Jun 18 21:01:55 2009 +0200 +++ b/schemaviewer.py Fri Jun 19 14:42:04 2009 +0200 @@ -6,11 +6,11 @@ :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ __docformat__ = "restructuredtext en" +_ = unicode from logilab.common.ureports import Section, Title, Table, Link, Span, Text from yams.schema2dot import CARD_MAP -_ = unicode I18NSTRINGS = [_('read'), _('add'), _('delete'), _('update'), _('order')] class SchemaViewer(object): @@ -38,8 +38,7 @@ klass='acl') - def visit_schema(self, schema, display_relations=0, - skiprels=(), skipmeta=True): + def visit_schema(self, schema, display_relations=0, skiptypes=()): """get a layout for a whole schema""" title = Title(self.req._('Schema %s') % schema.name, klass='titleUnderline') @@ -48,21 +47,15 @@ klass='titleUnderline'),)) layout.append(esection) eschemas = [eschema for eschema in schema.entities() - if not eschema.is_final()] - if skipmeta: - eschemas = [eschema for eschema in eschemas - if not eschema.meta] + if not (eschema.is_final() or eschema in skiptypes)] for eschema in sorted(eschemas): - esection.append(self.visit_entityschema(eschema, skiprels)) + esection.append(self.visit_entityschema(eschema, skiptypes)) if display_relations: title = Title(self.req._('Relations'), klass='titleUnderline') rsection = Section(children=(title,)) layout.append(rsection) relations = [rschema for rschema in schema.relations() - if not (rschema.is_final() or rschema.type in skiprels)] - if skipmeta: - relations = [rschema for rschema in relations - if not rschema.meta] + if not (rschema.is_final() or rschema.type in skiptypes)] keys = [(rschema.type, rschema) for rschema in relations] for key, rschema in sorted(keys): relstr = self.visit_relationschema(rschema) @@ -107,17 +100,13 @@ def stereotype(self, name): return Span((' <<%s>>' % name,), klass='stereotype') - def visit_entityschema(self, eschema, skiprels=()): + def visit_entityschema(self, eschema, skiptypes=()): """get a layout for an entity schema""" etype = eschema.type layout = Section(children=' ', klass='clear') layout.append(Link(etype,' ' , id=etype)) # anchor title = Link(self.eschema_link_url(eschema), etype) - if eschema.meta: - stereotype = self.stereotype('meta') - boxchild = [Section(children=(title, ' (%s)'%eschema.display_name(self.req), stereotype), klass='title')] - else: - boxchild = [Section(children=(title, ' (%s)'%eschema.display_name(self.req)), klass='title')] + boxchild = [Section(children=(title, ' (%s)'% eschema.display_name(self.req)), klass='title')] table = Table(cols=4, rheaders=1, children=self._entity_attributes_data(eschema)) boxchild.append(Section(children=(table,), klass='body')) @@ -129,7 +118,7 @@ rels = [] first = True for rschema, targetschemas, x in eschema.relation_definitions(): - if rschema.type in skiprels: + if rschema.type in skiptypes: continue if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')): continue diff -r 3e1d2ab5f8c0 -r a25859917ccc server/__init__.py --- a/server/__init__.py Thu Jun 18 21:01:55 2009 +0200 +++ b/server/__init__.py Fri Jun 19 14:42:04 2009 +0200 @@ -24,7 +24,7 @@ a initial user) """ from glob import glob - from cubicweb.schema import BASEGROUPS + from yams import BASE_GROUPS from cubicweb.dbapi import in_memory_cnx from cubicweb.server.repository import Repository from cubicweb.server.utils import manager_userpasswd @@ -93,7 +93,7 @@ login, pwd = unicode(source['db-user']), source['db-password'] print 'inserting default user and groups' needisfix = [] - for group in BASEGROUPS: + for group in BASE_GROUPS: rset = session.execute('INSERT CWGroup X: X name %(name)s', {'name': unicode(group)}) needisfix.append( (rset.rows[0][0], rset.description[0][0]) ) diff -r 3e1d2ab5f8c0 -r a25859917ccc server/schemaserial.py --- a/server/schemaserial.py Thu Jun 18 21:01:55 2009 +0200 +++ b/server/schemaserial.py Fri Jun 19 14:42:04 2009 +0200 @@ -114,10 +114,10 @@ index = {} permsdict = deserialize_ertype_permissions(session) schema.reading_from_database = True - for eid, etype, desc, meta in session.execute('Any X, N, D, M WHERE ' - 'X is CWEType, X name N, ' - 'X description D, X meta M', - build_descr=False): + for eid, etype, desc in session.execute('Any X, N, D WHERE ' + 'X is CWEType, X name N, ' + 'X description D', + build_descr=False): # base types are already in the schema, skip them if etype in schemamod.BASE_TYPES: # just set the eid @@ -152,7 +152,7 @@ repo.clear_caches(tocleanup) session.commit(False) etype = netype - etype = ybo.EntityType(name=etype, description=desc, meta=meta, eid=eid) + etype = ybo.EntityType(name=etype, description=desc, eid=eid) eschema = schema.add_entity_type(etype) index[eid] = eschema set_perms(eschema, permsdict.get(eid, {})) @@ -167,9 +167,9 @@ seschema = schema.eschema(stype) eschema._specialized_type = stype seschema._specialized_by.append(etype) - for eid, rtype, desc, meta, sym, il in session.execute( - 'Any X,N,D,M,S,I WHERE X is CWRType, X name N, X description D, ' - 'X meta M, X symetric S, X inlined I', build_descr=False): + for eid, rtype, desc, sym, il in session.execute( + 'Any X,N,D,S,I WHERE X is CWRType, X name N, X description D, ' + 'X symetric S, X inlined I', build_descr=False): try: # bw compat: fulltext_container added in 2.47 ft_container = session.execute('Any FTC WHERE X eid %(x)s, X fulltext_container FTC', @@ -177,7 +177,7 @@ except: ft_container = None session.rollback(False) - rtype = ybo.RelationType(name=rtype, description=desc, meta=bool(meta), + rtype = ybo.RelationType(name=rtype, description=desc, symetric=bool(sym), inlined=bool(il), fulltext_container=ft_container, eid=eid) rschema = schema.add_relation_type(rtype) @@ -326,7 +326,6 @@ raise Exception("can't decode %s [was %s]" % (erschema.description, e)) return { 'name': type_, - 'meta': erschema.meta, 'final': erschema.is_final(), 'description': desc, } diff -r 3e1d2ab5f8c0 -r a25859917ccc web/uicfg.py --- a/web/uicfg.py Thu Jun 18 21:01:55 2009 +0200 +++ b/web/uicfg.py Fri Jun 19 14:42:04 2009 +0200 @@ -154,7 +154,11 @@ # * 'schema' # * 'subobject' (not displayed by default) -indexview_etype_section = {'EmailAddress': 'subobject'} +indexview_etype_section = {'EmailAddress': 'subobject', + 'CWUser': 'system', + 'CWGroup': 'system', + 'CWPermission': 'system', + } # autoform.AutomaticEntityForm configuration ################################## diff -r 3e1d2ab5f8c0 -r a25859917ccc web/views/owl.py --- a/web/views/owl.py Thu Jun 18 21:01:55 2009 +0200 +++ b/web/views/owl.py Fri Jun 19 14:42:04 2009 +0200 @@ -6,14 +6,14 @@ :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses """ __docformat__ = "restructuredtext en" +_ = unicode from logilab.mtconverter import TransformError, xml_escape from cubicweb.view import StartupView, EntityView +from cubicweb.selectors import none_rset, match_view from cubicweb.web.action import Action -from cubicweb.selectors import none_rset, match_view - -_ = unicode +from cubicweb.web.views import schema OWL_CARD_MAP = {'1': '', '?': '1', @@ -55,8 +55,6 @@ OWL_CLOSING_ROOT = u'' -DEFAULT_SKIP_RELS = frozenset(('is', 'is_instance_of', 'identity', - 'owned_by', 'created_by')) class OWLView(StartupView): """This view export in owl format schema database. It is the TBOX""" @@ -69,36 +67,36 @@ skipmeta = int(self.req.form.get('skipmeta', True)) if writeprefix: self.w(OWL_OPENING_ROOT % {'appid': self.schema.name}) - self.visit_schema(skipmeta=skipmeta) + self.visit_schema(skiptypes=skipmeta and schema.SKIP_TYPES or ()) if writeprefix: self.w(OWL_CLOSING_ROOT) - def visit_schema(self, skiprels=DEFAULT_SKIP_RELS, skipmeta=True): + def should_display_rschema(self, rschema): + return not rschema in self.skiptypes and ( + rschema.has_local_role('read') or + rschema.has_perm(self.req, 'read')): + + def visit_schema(self, skiptypes): """get a layout for a whole schema""" - entities = sorted([eschema for eschema in self.schema.entities() - if not eschema.is_final()]) - if skipmeta: - entities = [eschema for eschema in entities - if not eschema.meta] + self.skiptypes = skiptypes + entities = sorted(eschema for eschema in self.schema.entities() + if not eschema.is_final() or eschema in skiptypes) self.w(u'') for eschema in entities: - self.visit_entityschema(eschema, skiprels) + self.visit_entityschema(eschema) self.w(u'') - self.visit_property_schema(eschema, skiprels) + self.visit_property_schema(eschema) self.w(u'') self.visit_property_object_schema(eschema) - def visit_entityschema(self, eschema, skiprels=()): + def visit_entityschema(self, eschema): """get a layout for an entity OWL schema""" self.w(u''% eschema) self.w(u'') for rschema, targetschemas, role in eschema.relation_definitions(): - if rschema.type in skiprels: - continue - if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')): + if not self.should_display_rschema(rschema): continue for oeschema in targetschemas: - label = rschema.type if role == 'subject': card = rschema.rproperty(eschema, oeschema, 'cardinality')[0] else: @@ -110,58 +108,44 @@ %s - -''' % (label, cardtag)) +''' % (rschema, cardtag)) self.w(u'') - for rschema, aschema in eschema.attribute_definitions(): - if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')): - continue - aname = rschema.type - if aname == 'eid': + if not self.should_display_rschema(rschema): continue self.w(u''' -''' - % aname) +''' % rschema) self.w(u'') - def visit_property_schema(self, eschema, skiprels=()): + def visit_property_schema(self, eschema): """get a layout for property entity OWL schema""" for rschema, targetschemas, role in eschema.relation_definitions(): - if rschema.type in skiprels: - continue - if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')): + if not self.should_display_rschema(rschema): continue for oeschema in targetschemas: label = rschema.type self.w(u''' - -''' % (label, eschema, oeschema.type)) +''' % (label, eschema, oeschema.type)) def visit_property_object_schema(self, eschema): for rschema, aschema in eschema.attribute_definitions(): - if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')): - continue - aname = rschema.type - if aname == 'eid': + if not self.should_display_rschema(rschema): continue self.w(u''' -''' - % (aname, eschema, OWL_TYPE_MAP[aschema.type])) +''' % (aname, eschema, OWL_TYPE_MAP[aschema.type])) class OWLABOXView(EntityView): '''This view represents a part of the ABOX for a given entity.''' - id = 'owlabox' title = _('owlabox') templatable = False @@ -173,8 +157,8 @@ self.cell_call(i, 0) self.w(OWL_CLOSING_ROOT) - def cell_call(self, row, col, skiprels=DEFAULT_SKIP_RELS): - self.wview('owlaboxitem', self.rset, row=row, col=col, skiprels=skiprels) + def cell_call(self, row, col): + self.wview('owlaboxitem', self.rset, row=row, col=col) class OWLABOXItemView(EntityView): @@ -183,13 +167,13 @@ templatable = False content_type = 'application/xml' # 'text/xml' - def cell_call(self, row, col, skiprels=DEFAULT_SKIP_RELS): + def cell_call(self, row, col): entity = self.complete_entity(row, col) eschema = entity.e_schema self.w(u'<%s rdf:ID="%s">' % (eschema, entity.eid)) self.w(u'') for rschema, aschema in eschema.attribute_definitions(): - if rschema.type in skiprels: + if rschema.meta: continue if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')): continue @@ -204,7 +188,7 @@ pass self.w(u'') for rschema, targetschemas, role in eschema.relation_definitions(): - if rschema.type in skiprels: + if rschema.meta: continue if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')): continue diff -r 3e1d2ab5f8c0 -r a25859917ccc web/views/schema.py --- a/web/views/schema.py Thu Jun 18 21:01:55 2009 +0200 +++ b/web/views/schema.py Fri Jun 19 14:42:04 2009 +0200 @@ -7,12 +7,11 @@ """ __docformat__ = "restructuredtext en" -from itertools import cycle - from logilab.mtconverter import html_escape from yams import schema2dot as s2d from cubicweb.selectors import implements, yes +from cubicweb.schema import META_RELATIONS_TYPES, SCHEMA_TYPES from cubicweb.schemaviewer import SchemaViewer from cubicweb.view import EntityView, StartupView from cubicweb.common import tags, uilib @@ -20,6 +19,9 @@ from cubicweb.web.views import TmpFileViewMixin, primary, baseviews, tabs from cubicweb.web.facet import AttributeFacet +SKIP_TYPES = set() +SKIP_TYPES.update(META_RELATIONS_TYPES) +SKIP_TYPES.update(SCHEMA_TYPES) class ViewSchemaAction(action.Action): id = 'schema' @@ -56,14 +58,11 @@ if final: self.w(u'') -SKIPPED_RELS = ('is', 'is_instance_of', 'identity', 'created_by', 'owned_by', - 'has_text',) class CWETypePrimaryView(tabs.TabsMixin, primary.PrimaryView): __select__ = implements('CWEType') title = _('in memory entity schema') main_related_section = False - skip_rels = SKIPPED_RELS tabs = [_('cwetype-schema-text'), _('cwetype-schema-image'), _('cwetype-schema-permissions'), _('cwetype-workflow')] default_tab = 'cwetype-schema-text' @@ -186,94 +185,56 @@ # schema images ############################################################### -class RestrictedSchemaDotPropsHandler(s2d.SchemaDotPropsHandler): - def __init__(self, req): - # FIXME: colors are arbitrary - self.nextcolor = cycle( ('#aa0000', '#00aa00', '#0000aa', - '#000000', '#888888') ).next +class RestrictedSchemaVisitorMixIn(object): + def __init__(self, req, *args, **kwargs): + super(RestrictedSchemaVisitorMixIn, self).__init__(*args, **kwargs) self.req = req - def display_attr(self, rschema): - return not rschema.meta and (rschema.has_local_role('read') - or rschema.has_perm(self.req, 'read')) + def should_display_schema(self, schema): + return (super(RestrictedSchemaVisitorMixIn, self).should_display_schema(schema) + and rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')) - # XXX remove this method once yams > 0.20 is out - def node_properties(self, eschema): - """return default DOT drawing options for an entity schema""" - label = ['{', eschema.type, '|'] - label.append(r'\l'.join(rel.type for rel in eschema.subject_relations() - if rel.final and self.display_attr(rel))) - label.append(r'\l}') # trailing \l ensure alignement of the last one - return {'label' : ''.join(label), 'shape' : "record", - 'fontname' : "Courier", 'style' : "filled"} - - def edge_properties(self, rschema, subjnode, objnode): - kwargs = super(RestrictedSchemaDotPropsHandler, self).edge_properties(rschema, subjnode, objnode) - # symetric rels are handled differently, let yams decide what's best - if not rschema.symetric: - kwargs['color'] = self.nextcolor() - kwargs['fontcolor'] = kwargs['color'] - # dot label decoration is just awful (1 line underlining the label - # + 1 line going to the closest edge spline point) - kwargs['decorate'] = 'false' - return kwargs + def should_display_attr(self, schema): + return (super(RestrictedSchemaVisitorMixIn, self).should_display_attr(schema) + and rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')) -class RestrictedSchemaVisitorMiIn: - def __init__(self, req, *args, **kwargs): - # hack hack hack - assert len(self.__class__.__bases__) == 2 - self.__parent = self.__class__.__bases__[1] - self.__parent.__init__(self, *args, **kwargs) - self.req = req - - def nodes(self): - for etype, eschema in self.__parent.nodes(self): - if eschema.has_local_role('read') or eschema.has_perm(self.req, 'read'): - yield eschema.type, eschema - - def edges(self): - for setype, oetype, rschema in self.__parent.edges(self): - if rschema.has_local_role('read') or rschema.has_perm(self.req, 'read'): - yield setype, oetype, rschema - - -class FullSchemaVisitor(RestrictedSchemaVisitorMiIn, s2d.FullSchemaVisitor): +class FullSchemaVisitor(RestrictedSchemaVisitorMixIn, s2d.FullSchemaVisitor): pass -class OneHopESchemaVisitor(RestrictedSchemaVisitorMiIn, s2d.OneHopESchemaVisitor): +class OneHopESchemaVisitor(RestrictedSchemaVisitorMixIn, + s2d.OneHopESchemaVisitor): pass -class OneHopRSchemaVisitor(RestrictedSchemaVisitorMiIn, s2d.OneHopRSchemaVisitor): +class OneHopRSchemaVisitor(RestrictedSchemaVisitorMixIn, + s2d.OneHopRSchemaVisitor): pass class SchemaImageView(TmpFileViewMixin, StartupView): id = 'schemagraph' + content_type = 'image/png' - content_type = 'image/png' - skip_rels = SKIPPED_RELS def _generate(self, tmpfile): """display global schema information""" skipmeta = not int(self.req.form.get('withmeta', 0)) - visitor = FullSchemaVisitor(self.req, self.schema, skiprels=self.skip_rels, skipmeta=skipmeta) - s2d.schema2dot(outputfile=tmpfile, visitor=visitor, - prophdlr=RestrictedSchemaDotPropsHandler(self.req)) + visitor = FullSchemaVisitor(self.req, self.schema, + skiptypes=skipmeta and SKIP_TYPES or ()) + s2d.schema2dot(outputfile=tmpfile, visitor=visitor) class CWETypeSchemaImageView(TmpFileViewMixin, EntityView): id = 'schemagraph' __select__ = implements('CWEType') - content_type = 'image/png' - skip_rels = SKIPPED_RELS def _generate(self, tmpfile): """display schema information for an entity""" entity = self.entity(self.row, self.col) eschema = self.vreg.schema.eschema(entity.name) - visitor = OneHopESchemaVisitor(self.req, eschema, skiprels=self.skip_rels) - s2d.schema2dot(outputfile=tmpfile, visitor=visitor, - prophdlr=RestrictedSchemaDotPropsHandler(self.req)) + skipmeta = not int(self.req.form.get('withmeta', 0)) + visitor = OneHopESchemaVisitor(self.req, eschema, + skiptypes=skipmeta and SKIP_TYPES or ()) + s2d.schema2dot(outputfile=tmpfile, visitor=visitor) class CWRTypeSchemaImageView(CWETypeSchemaImageView): __select__ = implements('CWRType') @@ -283,8 +244,7 @@ entity = self.entity(self.row, self.col) rschema = self.vreg.schema.rschema(entity.name) visitor = OneHopRSchemaVisitor(self.req, rschema) - s2d.schema2dot(outputfile=tmpfile, visitor=visitor, - prophdlr=RestrictedSchemaDotPropsHandler(self.req)) + s2d.schema2dot(outputfile=tmpfile, visitor=visitor) ### facets diff -r 3e1d2ab5f8c0 -r a25859917ccc web/views/startup.py --- a/web/views/startup.py Thu Jun 18 21:01:55 2009 +0200 +++ b/web/views/startup.py Fri Jun 19 14:42:04 2009 +0200 @@ -16,8 +16,7 @@ from cubicweb.selectors import match_user_groups, implements from cubicweb.common.uilib import ureport_as_html from cubicweb.web import ajax_replace_url, uicfg, httpcache -from cubicweb.web.views import tabs -from cubicweb.web.views.management import SecurityViewMixIn +from cubicweb.web.views import tabs, management, schema class ManageView(StartupView): id = 'manage' @@ -31,8 +30,6 @@ uicfg.indexview_etype_section.setdefault(eschema, 'schema') elif eschema.is_subobject(strict=True): uicfg.indexview_etype_section.setdefault(eschema, 'subobject') - elif eschema.meta: - uicfg.indexview_etype_section.setdefault(eschema, 'system') else: uicfg.indexview_etype_section.setdefault(eschema, 'application') @@ -205,7 +202,7 @@ self.wview('editable-table', rset, displayfilter=True) -class ManagerSchemaPermissionsView(StartupView, SecurityViewMixIn): +class ManagerSchemaPermissionsView(StartupView, management.SecurityViewMixIn): id = 'schema_security' __select__ = StartupView.__select__ & match_user_groups('managers') @@ -221,7 +218,7 @@ if not eschema.is_final()] if not formparams['withmeta']: entities = [eschema for eschema in entities - if not eschema.meta] + if not eschema.schema_entity()] # compute relations relations = [] if display_relations: @@ -229,7 +226,7 @@ if not (rschema.is_final() or rschema.type in skiprels)] if not formparams['withmeta']: relations = [rschema for rschema in relations - if not rschema.meta] + if not rschema.schema_relation()] # index self.w(u'
') self.w(u'

%s

' % _('index').capitalize()) @@ -260,11 +257,11 @@ self.w(u'
' % (eschema.type, eschema.type)) self.w(u'

%s (%s) ' % (eschema.type, _(eschema.type))) url = html_escape(self.build_url('schema', **formparams) + '#index') - self.w(u'%s' % (url, self.req.external_resource('UP_ICON'), _('up'))) + self.w(u'%s' % ( + url, self.req.external_resource('UP_ICON'), _('up'))) self.w(u'

') self.w(u'
') self.schema_definition(eschema, link=False) - # display entity attributes only if they have some permissions modified modified_attrs = [] for attr, etype in eschema.attribute_definitions(): @@ -277,10 +274,7 @@ for attr in modified_attrs: self.w(u'

%s (%s)

' % (attr.type, _(attr.type))) self.schema_definition(attr, link=False) - self.w(u'
') - else: - self.w(u'
') - + self.w(u'') def display_relations(self, relations, formparams): _ = self.req._ @@ -290,16 +284,19 @@ self.w(u'' % (rschema.type, rschema.type)) self.w(u'

%s (%s) ' % (rschema.type, _(rschema.type))) url = html_escape(self.build_url('schema', **formparams) + '#index') - self.w(u'%s' % (url, self.req.external_resource('UP_ICON'), _('up'))) + self.w(u'%s' % ( + url, self.req.external_resource('UP_ICON'), _('up'))) self.w(u'

') self.w(u'
') subjects = [str(subj) for subj in rschema.subjects()] - self.w(u'
%s %s (%s)
' % (_('subject_plural:'), - ', '.join( [str(subj) for subj in rschema.subjects()]), - ', '.join( [_(str(subj)) for subj in rschema.subjects()]))) - self.w(u'
%s %s (%s)
' % (_('object_plural:'), - ', '.join( [str(obj) for obj in rschema.objects()]), - ', '.join( [_(str(obj)) for obj in rschema.objects()]))) + self.w(u'
%s %s (%s)
' % ( + _('subject_plural:'), + ', '.join(str(subj) for subj in rschema.subjects()), + ', '.join(_(str(subj)) for subj in rschema.subjects()))) + self.w(u'
%s %s (%s)
' % ( + _('object_plural:'), + ', '.join(str(obj) for obj in rschema.objects()), + ', '.join(_(str(obj)) for obj in rschema.objects()))) self.schema_definition(rschema, link=False) self.w(u'
') @@ -309,13 +306,13 @@ def call(self): from cubicweb.schemaviewer import SchemaViewer - skipmeta = int(self.req.form.get('skipmeta', True)) - schema = self.schema + if int(self.req.form.get('skipmeta', True)): + skip = schema.SKIP_TYPES + else: + skip = () viewer = SchemaViewer(self.req) - layout = viewer.visit_schema(schema, display_relations=True, - skiprels=('is', 'is_instance_of', 'identity', - 'owned_by', 'created_by'), - skipmeta=skipmeta) + layout = viewer.visit_schema(self.schema, display_relations=True, + skiptypes=skip) self.w(ureport_as_html(layout))