15 |
15 |
16 from logilab.common.decorators import cached, clear_cache, monkeypatch |
16 from logilab.common.decorators import cached, clear_cache, monkeypatch |
17 from logilab.common.deprecation import obsolete |
17 from logilab.common.deprecation import obsolete |
18 from logilab.common.compat import any |
18 from logilab.common.compat import any |
19 |
19 |
20 from yams import BadSchemaDefinition, buildobjs as ybo |
20 from yams import BadSchemaDefinition, buildobjs as ybo, constraints |
21 from yams.schema import Schema, ERSchema, EntitySchema, RelationSchema |
21 from yams.schema import Schema, ERSchema, EntitySchema, RelationSchema |
22 from yams.constraints import BaseConstraint, StaticVocabularyConstraint |
22 from yams.constraints import BaseConstraint, StaticVocabularyConstraint |
23 from yams.reader import CONSTRAINTS, PyFileReader, SchemaLoader, \ |
23 from yams.reader import CONSTRAINTS, PyFileReader, SchemaLoader, \ |
24 obsolete as yobsolete |
24 obsolete as yobsolete |
25 |
25 |
59 msg = '%s has been renamed to %s, please update your code' % ( |
59 msg = '%s has been renamed to %s, please update your code' % ( |
60 etype, ETYPE_NAME_MAP[etype]) |
60 etype, ETYPE_NAME_MAP[etype]) |
61 warn(msg, DeprecationWarning, stacklevel=4) |
61 warn(msg, DeprecationWarning, stacklevel=4) |
62 etype = ETYPE_NAME_MAP[etype] |
62 etype = ETYPE_NAME_MAP[etype] |
63 return etype |
63 return etype |
64 |
|
65 |
|
66 ## cubicweb provides a RichString class for convenience |
|
67 class RichString(ybo.String): |
|
68 """Convenience RichString attribute type |
|
69 The following declaration:: |
|
70 |
|
71 class Card(EntityType): |
|
72 content = RichString(fulltextindexed=True, default_format='text/rest') |
|
73 |
|
74 is equivalent to:: |
|
75 |
|
76 class Card(EntityType): |
|
77 content_format = String(internationalizable=True, |
|
78 default='text/rest', constraints=[format_constraint]) |
|
79 content = String(fulltextindexed=True) |
|
80 """ |
|
81 def __init__(self, default_format='text/plain', format_constraints=None, **kwargs): |
|
82 self.default_format = default_format |
|
83 self.format_constraints = format_constraints or [format_constraint] |
|
84 super(RichString, self).__init__(**kwargs) |
|
85 |
|
86 PyFileReader.context['RichString'] = yobsolete(RichString) |
|
87 |
|
88 ## need to monkeypatch yams' _add_relation function to handle RichString |
|
89 yams_add_relation = ybo._add_relation |
|
90 @monkeypatch(ybo) |
|
91 def _add_relation(relations, rdef, name=None, insertidx=None): |
|
92 if isinstance(rdef, RichString): |
|
93 format_attrdef = ybo.String(internationalizable=True, |
|
94 default=rdef.default_format, maxsize=50, |
|
95 constraints=rdef.format_constraints) |
|
96 yams_add_relation(relations, format_attrdef, name+'_format', insertidx) |
|
97 yams_add_relation(relations, rdef, name, insertidx) |
|
98 |
|
99 |
|
100 @monkeypatch(ybo.EntityType, methodname='add_relation') |
|
101 @classmethod |
|
102 def add_relation(cls, rdef, name=None): |
|
103 ybo.add_relation_function(cls, rdef, name) |
|
104 if isinstance(rdef, RichString) and not rdef in cls._defined: |
|
105 format_attr_name = (name or rdef.name) + '_format' |
|
106 rdef = cls.get_relations(format_attr_name).next() |
|
107 cls._ensure_relation_type(rdef) |
|
108 |
64 |
109 def display_name(req, key, form=''): |
65 def display_name(req, key, form=''): |
110 """return a internationalized string for the key (schema entity or relation |
66 """return a internationalized string for the key (schema entity or relation |
111 name) in a given form |
67 name) in a given form |
112 """ |
68 """ |
924 for filepath in self.get_schema_files(cube): |
880 for filepath in self.get_schema_files(cube): |
925 self.info('loading %s', filepath) |
881 self.info('loading %s', filepath) |
926 self.handle_file(filepath) |
882 self.handle_file(filepath) |
927 |
883 |
928 |
884 |
|
885 set_log_methods(CubicWebSchemaLoader, getLogger('cubicweb.schemaloader')) |
|
886 set_log_methods(BootstrapSchemaLoader, getLogger('cubicweb.bootstrapschemaloader')) |
|
887 set_log_methods(RQLExpression, getLogger('cubicweb.schema')) |
|
888 |
929 # _() is just there to add messages to the catalog, don't care about actual |
889 # _() is just there to add messages to the catalog, don't care about actual |
930 # translation |
890 # translation |
931 PERM_USE_TEMPLATE_FORMAT = _('use_template_format') |
891 PERM_USE_TEMPLATE_FORMAT = _('use_template_format') |
932 |
892 NEED_PERM_FORMATS = [_('text/cubicweb-page-template')] |
933 class FormatConstraint(StaticVocabularyConstraint): |
893 |
934 need_perm_formats = [_('text/cubicweb-page-template')] |
894 @monkeypatch(constraints.FormatConstraint) |
935 |
895 def vocabulary(self, entity=None, req=None): |
936 regular_formats = (_('text/rest'), |
896 if req is None and entity is not None: |
937 _('text/html'), |
897 req = entity.req |
938 _('text/plain'), |
898 if req is not None and req.user.has_permission(PERM_USE_TEMPLATE_FORMAT): |
939 ) |
899 return self.regular_formats + tuple(NEED_PERM_FORMATS) |
940 def __init__(self): |
900 return self.regular_formats |
941 pass |
|
942 |
|
943 def serialize(self): |
|
944 """called to make persistent valuable data of a constraint""" |
|
945 return None |
|
946 |
|
947 @classmethod |
|
948 def deserialize(cls, value): |
|
949 """called to restore serialized data of a constraint. Should return |
|
950 a `cls` instance |
|
951 """ |
|
952 return cls() |
|
953 |
|
954 def vocabulary(self, entity=None, req=None): |
|
955 if req is None and entity is not None: |
|
956 req = entity.req |
|
957 if req is not None and req.user.has_permission(PERM_USE_TEMPLATE_FORMAT): |
|
958 return self.regular_formats + tuple(self.need_perm_formats) |
|
959 return self.regular_formats |
|
960 |
|
961 def __str__(self): |
|
962 return 'value in (%s)' % u', '.join(repr(unicode(word)) for word in self.vocabulary()) |
|
963 |
|
964 |
|
965 format_constraint = FormatConstraint() |
|
966 CONSTRAINTS['FormatConstraint'] = FormatConstraint |
|
967 PyFileReader.context['format_constraint'] = format_constraint |
|
968 |
|
969 set_log_methods(CubicWebSchemaLoader, getLogger('cubicweb.schemaloader')) |
|
970 set_log_methods(BootstrapSchemaLoader, getLogger('cubicweb.bootstrapschemaloader')) |
|
971 set_log_methods(RQLExpression, getLogger('cubicweb.schema')) |
|
972 |
901 |
973 # XXX monkey patch PyFileReader.import_erschema until bw_normalize_etype is |
902 # XXX monkey patch PyFileReader.import_erschema until bw_normalize_etype is |
974 # necessary |
903 # necessary |
975 orig_import_erschema = PyFileReader.import_erschema |
904 orig_import_erschema = PyFileReader.import_erschema |
976 def bw_import_erschema(self, ertype, schemamod=None, instantiate=True): |
905 def bw_import_erschema(self, ertype, schemamod=None, instantiate=True): |