1 """an helper class to display CubicWeb schema using ureports |
1 """an helper class to display CubicWeb schema using ureports |
2 |
2 |
3 :organization: Logilab |
3 :organization: Logilab |
4 :copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
4 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
6 """ |
6 """ |
7 __docformat__ = "restructuredtext en" |
7 __docformat__ = "restructuredtext en" |
8 |
8 |
9 from logilab.common.ureports import Section, Title, Table, Link, Span, Text |
9 from logilab.common.ureports import Section, Title, Table, Link, Span, Text |
10 from yams.schema2dot import CARD_MAP |
10 from yams.schema2dot import CARD_MAP |
11 |
11 |
12 _ = unicode |
12 _ = unicode |
13 I18NSTRINGS = [_('read'), _('add'), _('delete'), _('update'), _('order')] |
13 I18NSTRINGS = [_('read'), _('add'), _('delete'), _('update'), _('order')] |
14 |
14 |
15 class SchemaViewer(object): |
15 class SchemaViewer(object): |
22 if not encoding: |
22 if not encoding: |
23 encoding = req.encoding |
23 encoding = req.encoding |
24 else: |
24 else: |
25 self._possible_views = lambda x: () |
25 self._possible_views = lambda x: () |
26 self.encoding = encoding |
26 self.encoding = encoding |
27 |
27 |
28 def format_acls(self, schema, access_types): |
28 def format_acls(self, schema, access_types): |
29 """return a layout displaying access control lists""" |
29 """return a layout displaying access control lists""" |
30 data = [self.req._('access type'), self.req._('groups')] |
30 data = [self.req._('access type'), self.req._('groups')] |
31 for access_type in access_types: |
31 for access_type in access_types: |
32 data.append(self.req._(access_type)) |
32 data.append(self.req._(access_type)) |
34 acls += (rqlexp.expression for rqlexp in schema.get_rqlexprs(access_type)) |
34 acls += (rqlexp.expression for rqlexp in schema.get_rqlexprs(access_type)) |
35 data.append(', '.join(acls)) |
35 data.append(', '.join(acls)) |
36 return Section(children=(Table(cols=2, cheaders=1, rheaders=1, children=data),), |
36 return Section(children=(Table(cols=2, cheaders=1, rheaders=1, children=data),), |
37 klass='acl') |
37 klass='acl') |
38 |
38 |
39 |
39 |
40 def visit_schema(self, schema, display_relations=0, |
40 def visit_schema(self, schema, display_relations=0, |
41 skiprels=(), skipmeta=True): |
41 skiprels=(), skipmeta=True): |
42 """get a layout for a whole schema""" |
42 """get a layout for a whole schema""" |
43 title = Title(self.req._('Schema %s') % schema.name, |
43 title = Title(self.req._('Schema %s') % schema.name, |
44 klass='titleUnderline') |
44 klass='titleUnderline') |
45 layout = Section(children=(title,)) |
45 layout = Section(children=(title,)) |
46 esection = Section(children=(Title(self.req._('Entities'), |
46 esection = Section(children=(Title(self.req._('Entities'), |
47 klass='titleUnderline'),)) |
47 klass='titleUnderline'),)) |
48 layout.append(esection) |
48 layout.append(esection) |
49 entities = [eschema for eschema in schema.entities() |
49 eschemas = [eschema for eschema in schema.entities() |
50 if not eschema.is_final()] |
50 if not eschema.is_final()] |
51 if skipmeta: |
51 if skipmeta: |
52 entities = [eschema for eschema in entities |
52 eschemas = [eschema for eschema in eschemas |
53 if not eschema.meta] |
53 if not eschema.meta] |
54 keys = [(eschema.type, eschema) for eschema in entities] |
54 for eschema in sorted(eschemas): |
55 for key, eschema in sorted(keys): |
|
56 esection.append(self.visit_entityschema(eschema, skiprels)) |
55 esection.append(self.visit_entityschema(eschema, skiprels)) |
57 if display_relations: |
56 if display_relations: |
58 title = Title(self.req._('Relations'), klass='titleUnderline') |
57 title = Title(self.req._('Relations'), klass='titleUnderline') |
59 rsection = Section(children=(title,)) |
58 rsection = Section(children=(title,)) |
60 layout.append(rsection) |
59 layout.append(rsection) |
61 relations = [rschema for rschema in schema.relations() |
60 relations = [rschema for rschema in schema.relations() |
62 if not (rschema.is_final() or rschema.type in skiprels)] |
61 if not (rschema.is_final() or rschema.type in skiprels)] |
63 if skipmeta: |
62 if skipmeta: |
64 relations = [rschema for rschema in relations |
63 relations = [rschema for rschema in relations |
75 for rschema, aschema in eschema.attribute_definitions(): |
74 for rschema, aschema in eschema.attribute_definitions(): |
76 if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')): |
75 if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')): |
77 continue |
76 continue |
78 aname = rschema.type |
77 aname = rschema.type |
79 if aname == 'eid': |
78 if aname == 'eid': |
80 continue |
79 continue |
81 data.append('%s (%s)' % (aname, _(aname))) |
80 data.append('%s (%s)' % (aname, _(aname))) |
82 data.append(_(aschema.type)) |
81 data.append(_(aschema.type)) |
83 defaultval = eschema.default(aname) |
82 defaultval = eschema.default(aname) |
84 if defaultval is not None: |
83 if defaultval is not None: |
85 default = self.to_string(defaultval) |
84 default = self.to_string(defaultval) |
93 data.append(', '.join(str(constr) for constr in constraints)) |
92 data.append(', '.join(str(constr) for constr in constraints)) |
94 return data |
93 return data |
95 |
94 |
96 def eschema_link_url(self, eschema): |
95 def eschema_link_url(self, eschema): |
97 return self.req.build_url('eetype/%s?vid=eschema' % eschema) |
96 return self.req.build_url('eetype/%s?vid=eschema' % eschema) |
98 |
97 |
99 def rschema_link_url(self, rschema): |
98 def rschema_link_url(self, rschema): |
100 return self.req.build_url('ertype/%s?vid=eschema' % rschema) |
99 return self.req.build_url('ertype/%s?vid=eschema' % rschema) |
101 |
100 |
102 def possible_views(self, etype): |
101 def possible_views(self, etype): |
103 rset = self.req.etype_rset(etype) |
102 rset = self.req.etype_rset(etype) |
104 return [v for v in self._possible_views(self.req, rset) |
103 return [v for v in self._possible_views(self.req, rset) |
105 if v.category != 'startupview'] |
104 if v.category != 'startupview'] |
106 |
105 |
107 def stereotype(self, name): |
106 def stereotype(self, name): |
108 return Span((' <<%s>>' % name,), klass='stereotype') |
107 return Span((' <<%s>>' % name,), klass='stereotype') |
109 |
108 |
110 def visit_entityschema(self, eschema, skiprels=()): |
109 def visit_entityschema(self, eschema, skiprels=()): |
111 """get a layout for an entity schema""" |
110 """get a layout for an entity schema""" |
112 etype = eschema.type |
111 etype = eschema.type |
113 layout = Section(children=' ', klass='clear') |
112 layout = Section(children=' ', klass='clear') |
114 layout.append(Link(etype,' ' , id=etype)) # anchor |
113 layout.append(Link(etype,' ' , id=etype)) # anchor |
116 if eschema.meta: |
115 if eschema.meta: |
117 stereotype = self.stereotype('meta') |
116 stereotype = self.stereotype('meta') |
118 boxchild = [Section(children=(title, ' (%s)'%eschema.display_name(self.req), stereotype), klass='title')] |
117 boxchild = [Section(children=(title, ' (%s)'%eschema.display_name(self.req), stereotype), klass='title')] |
119 else: |
118 else: |
120 boxchild = [Section(children=(title, ' (%s)'%eschema.display_name(self.req)), klass='title')] |
119 boxchild = [Section(children=(title, ' (%s)'%eschema.display_name(self.req)), klass='title')] |
121 table = Table(cols=4, rheaders=1, |
120 table = Table(cols=4, rheaders=1, |
122 children=self._entity_attributes_data(eschema)) |
121 children=self._entity_attributes_data(eschema)) |
123 boxchild.append(Section(children=(table,), klass='body')) |
122 boxchild.append(Section(children=(table,), klass='body')) |
124 data = [] |
123 data = [] |
125 data.append(Section(children=boxchild, klass='box')) |
124 data.append(Section(children=boxchild, klass='box')) |
126 data.append(Section(children='', klass='vl')) |
125 data.append(Section(children='', klass='vl')) |
156 layout.append(Section(children=data, klass='entityAttributes')) |
155 layout.append(Section(children=data, klass='entityAttributes')) |
157 if eschema.is_final(): # stop here for final entities |
156 if eschema.is_final(): # stop here for final entities |
158 return layout |
157 return layout |
159 _ = self.req._ |
158 _ = self.req._ |
160 if self.req.user.matching_groups('managers'): |
159 if self.req.user.matching_groups('managers'): |
161 layout.append(self.format_acls(eschema, ('read', 'add', 'delete', 'update'))) |
160 # layout.append(self.format_acls(eschema, ('read', 'add', 'delete', 'update'))) |
162 # possible views for this entity type |
161 # possible views for this entity type |
163 views = [_(view.title) for view in self.possible_views(etype)] |
162 views = [_(view.title) for view in self.possible_views(etype)] |
164 layout.append(Section(children=(Table(cols=1, rheaders=1, |
163 layout.append(Section(children=(Table(cols=1, rheaders=1, |
165 children=[_('views')]+views),), |
164 children=[_('views')]+views),), |
166 klass='views')) |
165 klass='views')) |
167 return layout |
166 return layout |
168 |
167 |
169 def visit_relationschema(self, rschema, title=True): |
168 def visit_relationschema(self, rschema, title=True): |
170 """get a layout for a relation schema""" |
169 """get a layout for a relation schema""" |
171 _ = self.req._ |
170 _ = self.req._ |
172 title = Link(self.rschema_link_url(rschema), rschema.type) |
171 title = Link(self.rschema_link_url(rschema), rschema.type) |
173 stereotypes = [] |
172 stereotypes = [] |