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
--- 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')
--- 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:
--- 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):
--- 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):
--- 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
--- 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
--- 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
--- 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
--- 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]) )
--- 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,
}
--- 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 ##################################
--- 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': '<rdf:type rdf:resource="&owl;FunctionalProperty"/>',
'?': '<owl:maxCardinality rdf:datatype="&xsd;int">1</owl:maxCardinality>',
@@ -55,8 +55,6 @@
OWL_CLOSING_ROOT = u'</rdf:RDF>'
-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'<!-- classes definition -->')
for eschema in entities:
- self.visit_entityschema(eschema, skiprels)
+ self.visit_entityschema(eschema)
self.w(u'<!-- property definition -->')
- self.visit_property_schema(eschema, skiprels)
+ self.visit_property_schema(eschema)
self.w(u'<!-- datatype property -->')
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'<owl:Class rdf:ID="%s">'% eschema)
self.w(u'<!-- relations -->')
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 @@
<owl:onProperty rdf:resource="#%s"/>
%s
</owl:Restriction>
-</rdfs:subClassOf>
-''' % (label, cardtag))
+</rdfs:subClassOf>''' % (rschema, cardtag))
self.w(u'<!-- attributes -->')
-
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'''<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#%s"/>
<rdf:type rdf:resource="&owl;FunctionalProperty"/>
</owl:Restriction>
-</rdfs:subClassOf>'''
- % aname)
+</rdfs:subClassOf>''' % rschema)
self.w(u'</owl:Class>')
- 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'''<owl:ObjectProperty rdf:ID="%s">
<rdfs:domain rdf:resource="#%s"/>
<rdfs:range rdf:resource="#%s"/>
-</owl:ObjectProperty>
-''' % (label, eschema, oeschema.type))
+</owl:ObjectProperty>''' % (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'''<owl:DatatypeProperty rdf:ID="%s">
<rdfs:domain rdf:resource="#%s"/>
<rdfs:range rdf:resource="%s"/>
-</owl:DatatypeProperty>'''
- % (aname, eschema, OWL_TYPE_MAP[aschema.type]))
+</owl:DatatypeProperty>''' % (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'<!--attributes-->')
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'<!--relations -->')
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
--- 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'</em>')
-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
--- 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'<div id="schema_security"><a id="index" href="index"/>')
self.w(u'<h2 class="schema">%s</h2>' % _('index').capitalize())
@@ -260,11 +257,11 @@
self.w(u'<a id="%s" href="%s"/>' % (eschema.type, eschema.type))
self.w(u'<h3 class="schema">%s (%s) ' % (eschema.type, _(eschema.type)))
url = html_escape(self.build_url('schema', **formparams) + '#index')
- self.w(u'<a href="%s"><img src="%s" alt="%s"/></a>' % (url, self.req.external_resource('UP_ICON'), _('up')))
+ self.w(u'<a href="%s"><img src="%s" alt="%s"/></a>' % (
+ url, self.req.external_resource('UP_ICON'), _('up')))
self.w(u'</h3>')
self.w(u'<div style="margin: 0px 1.5em">')
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'<h4 class="schema">%s (%s)</h4> ' % (attr.type, _(attr.type)))
self.schema_definition(attr, link=False)
- self.w(u'</div>')
- else:
- self.w(u'</div>')
-
+ self.w(u'</div>')
def display_relations(self, relations, formparams):
_ = self.req._
@@ -290,16 +284,19 @@
self.w(u'<a id="%s" href="%s"/>' % (rschema.type, rschema.type))
self.w(u'<h3 class="schema">%s (%s) ' % (rschema.type, _(rschema.type)))
url = html_escape(self.build_url('schema', **formparams) + '#index')
- self.w(u'<a href="%s"><img src="%s" alt="%s"/></a>' % (url, self.req.external_resource('UP_ICON'), _('up')))
+ self.w(u'<a href="%s"><img src="%s" alt="%s"/></a>' % (
+ url, self.req.external_resource('UP_ICON'), _('up')))
self.w(u'</h3>')
self.w(u'<div style="margin: 0px 1.5em">')
subjects = [str(subj) for subj in rschema.subjects()]
- self.w(u'<div><strong>%s</strong> %s (%s)</div>' % (_('subject_plural:'),
- ', '.join( [str(subj) for subj in rschema.subjects()]),
- ', '.join( [_(str(subj)) for subj in rschema.subjects()])))
- self.w(u'<div><strong>%s</strong> %s (%s)</div>' % (_('object_plural:'),
- ', '.join( [str(obj) for obj in rschema.objects()]),
- ', '.join( [_(str(obj)) for obj in rschema.objects()])))
+ self.w(u'<div><strong>%s</strong> %s (%s)</div>' % (
+ _('subject_plural:'),
+ ', '.join(str(subj) for subj in rschema.subjects()),
+ ', '.join(_(str(subj)) for subj in rschema.subjects())))
+ self.w(u'<div><strong>%s</strong> %s (%s)</div>' % (
+ _('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'</div>')
@@ -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))