unification of meta-attributes handling: tls-sprint
authorsylvain.thenault@logilab.fr
Thu, 12 Mar 2009 19:39:34 +0100
branchtls-sprint
changeset 1101 0c067de38e46
parent 1100 7ca89f4468e4
child 1102 054dfee29bfc
unification of meta-attributes handling: * remove has_format, has_text_encoding, format, text_encoding methods on Entity * remove rich_text_fields method on EntitySchema * use instead has_metadata / meta_attribute on EntitySchema (from yams) and attribute_metadata on Entity
entities/__init__.py
entity.py
schema.py
sobjects/hooks.py
web/form.py
web/formfields.py
web/views/editcontroller.py
web/widgets.py
--- a/entities/__init__.py	Thu Mar 12 18:41:26 2009 +0100
+++ b/entities/__init__.py	Thu Mar 12 19:39:34 2009 +0100
@@ -89,13 +89,12 @@
     @classmethod
     def __initialize__(cls): 
         super(ANYENTITY, cls).__initialize__() # XXX
+        # set a default_ATTR method for rich text format fields
+        # XXX move this away once the old widgets have been dropped!
         eschema = cls.e_schema
-        eschema.format_fields = {}
-        # set a default_ATTR method for rich text format fields
-        for attr, formatattr in eschema.rich_text_fields():
-            if not hasattr(cls, 'default_%s' % formatattr):
-                setattr(cls, 'default_%s' % formatattr, cls._default_format)
-            eschema.format_fields[formatattr] = attr
+        for metaattr, (metadata, attr) in eschema.meta_attributes().iteritems():
+            if metadata == 'format' and not hasattr(cls, 'default_%s' % metaattr):
+                setattr(cls, 'default_%s' % metaattr, cls._default_format)
     
     # meta data api ###########################################################
 
@@ -414,9 +413,9 @@
         """return True if fckeditor should be used to edit entity's attribute named
         `attr`, according to user preferences
         """
-        if self.req.use_fckeditor() and self.has_format(attr):
+        if self.req.use_fckeditor() and self.has_metadata(attr, 'format'):
             if self.has_eid() or '%s_format' % attr in self:
-                return self.format(attr) == 'text/html'
+                return self.attribute_metadata(attr, 'format') == 'text/html'
             return self.req.property_value('ui.default-text-format') == 'text/html'
         return False
 
--- a/entity.py	Thu Mar 12 18:41:26 2009 +0100
+++ b/entity.py	Thu Mar 12 19:39:34 2009 +0100
@@ -461,29 +461,12 @@
             needcheck = False
         return mainattr, needcheck
 
-    @classmethod
-    @obsolete('use method of the same name on the schema')
-    def has_format(cls, attr):
-        """return true if this entity's schema has a format field for the given
-        attribute
-        """
-        return cls.e_schema.has_format(attr)
-        
-    def format(self, attr):
-        """return the mime type format for an attribute (if specified)"""
-        return getattr(self, '%s_format' % attr, None)
-    
-    def text_encoding(self, attr):
-        """return the text encoding for an attribute, default to site encoding
-        """
-        encoding = getattr(self, '%s_encoding' % attr, None)
-        return encoding or self.vreg.property_value('ui.encoding')
-    
-    def has_text_encoding(self, attr):
-        """return true if this entity's schema has ab encoding field for the
-        given attribute
-        """
-        return self.e_schema.has_subject_relation('%s_encoding' % attr)
+    def attribute_metadata(self, attr, metadata):
+        """return a metadata for an attribute (None if unspecified)"""
+        value = getattr(self, '%s_%s' % (attr, metadata), None)
+        if value is None and metadata == 'encoding':
+            value = self.vreg.property_value('ui.encoding')
+        return value
 
     def printable_value(self, attr, value=_marker, attrtype=None,
                         format='text/html', displaytime=True):
@@ -505,17 +488,14 @@
             # description...
             if props.get('internationalizable'):
                 value = self.req._(value)
-            attrformat = self.format(attr)
+            attrformat = self.attribute_metadata(attr, 'format')
             if attrformat:
                 return self.mtc_transform(value, attrformat, format,
                                           self.req.encoding)
         elif attrtype == 'Bytes':
-            attrformat = self.format(attr)
+            attrformat = self.attribute_metadata(attr, 'format')
             if attrformat:
-                try:
-                    encoding = getattr(self, '%s_encoding' % attr)
-                except AttributeError:
-                    encoding = self.req.encoding
+                encoding = self.attribute_metadata(attr, 'encoding')
                 return self.mtc_transform(value.getvalue(), attrformat, format,
                                           encoding)
             return u''
--- a/schema.py	Thu Mar 12 18:41:26 2009 +0100
+++ b/schema.py	Thu Mar 12 19:39:34 2009 +0100
@@ -322,28 +322,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()
-
-    def has_format(self, attr):
-        """return true if this entity's schema has a format field for the given
-        attribute
-        """
-        return self.has_subject_relation('%s_format' % attr)
-
-    def has_format(self, attr):
-        """return true if this entity's schema has an encoding field for the given
-        attribute
-        """
-        return self.has_subject_relation('%s_format' % attr)
-
-    def rich_text_fields(self):
-        """return an iterator on (attribute, format attribute) of rich text field
-
-        (the first tuple element containing the text and the second the text format)
-        """
-        for rschema, _ in self.attribute_definitions():
-            if rschema.type.endswith('_format') and self.has_subject_relation(rschema.type[:-7]):
-                yield self.subject_relation(rschema.type[:-7]), rschema
-                    
+    
     def check_perm(self, session, action, eid=None):
         # NB: session may be a server session or a request object
         user = session.user
--- a/sobjects/hooks.py	Thu Mar 12 18:41:26 2009 +0100
+++ b/sobjects/hooks.py	Thu Mar 12 19:39:34 2009 +0100
@@ -45,16 +45,18 @@
     accepts = ('Any',)
 
     def call(self, session, entity):
-        for formatattr, attr in entity.e_schema.format_fields.iteritems():
-            try:
-                value = entity[attr]
-            except KeyError:
-                continue # no text to tidy
-            if isinstance(value, unicode): # filter out None and Binary
-                if self.event == 'before_add_entity':
-                    fmt = entity.get(formatattr)
-                else:
-                    fmt = entity.get_value(formatattr)
-                if fmt == 'text/html':
-                    entity[attr] = soup2xhtml(value, session.encoding)
+        metaattrs = entity.e_schema.meta_attributes()
+        for metaattr, (metadata, attr) in metaattrs.iteritems():
+            if metadata == 'format':
+                try:
+                    value = entity[attr]
+                except KeyError:
+                    continue # no text to tidy
+                if isinstance(value, unicode): # filter out None and Binary
+                    if self.event == 'before_add_entity':
+                        fmt = entity.get(metaattr)
+                    else:
+                        fmt = entity.get_value(metaattr)
+                    if fmt == 'text/html':
+                        entity[attr] = soup2xhtml(value, session.encoding)
 
--- a/web/form.py	Thu Mar 12 18:41:26 2009 +0100
+++ b/web/form.py	Thu Mar 12 19:39:34 2009 +0100
@@ -475,16 +475,16 @@
     
     def form_field_format(self, field):
         entity = self.entity
-        if field.eidparam and entity.has_format(field.name) and (
+        if field.eidparam and entity.has_metadata(field.name, 'format') and (
             entity.has_eid() or '%s_format' % field.name in entity):
-            return self.entity.format(field.name)
+            return self.entity.attribute_metadata(field.name, 'format')
         return self.req.property_value('ui.default-text-format')
 
     def form_field_encoding(self, field):
         entity = self.entity
-        if field.eidparam and entity.has_encoding(field.name) and (
+        if field.eidparam and entity.has_metadata(field.name, 'encoding') and (
             entity.has_eid() or '%s_encoding' % field.name in entity):
-            return self.entity.text_encoding()
+            return self.entity.attribute_metadata(field.name, 'encoding')
         return super(EntityFieldsForm, self).form_field_encoding(field)
 
     def _form_field_entity_value(self, field, default_initial=True, load_bytes=False):
--- a/web/formfields.py	Thu Mar 12 18:41:26 2009 +0100
+++ b/web/formfields.py	Thu Mar 12 19:39:34 2009 +0100
@@ -373,7 +373,7 @@
             return None
         if targetschema == 'Password':
             return StringField(widget=PasswordInput(), **kwargs)
-        if eschema.has_format(rschema):
+        if eschema.has_metadata(rschema, 'format'):
             constraints = rschema.rproperty(eschema, targetschema, 'constraints')
             for cstr in constraints:
                 if isinstance(cstr, StaticVocabularyConstraint):
--- a/web/views/editcontroller.py	Thu Mar 12 18:41:26 2009 +0100
+++ b/web/views/editcontroller.py	Thu Mar 12 19:39:34 2009 +0100
@@ -201,24 +201,24 @@
             if formparams.has_key('__%s_detach' % attr) or formparams.has_key('%s__detach' % attr):
                 # drop current file value
                 value = None
-            # no need to check value when nor explicit detach nor new file submitted,
-            # since it will think the attribut is not modified
+            # no need to check value when nor explicit detach nor new file
+            # submitted, since it will think the attribute is not modified
             elif isinstance(value, unicode):
                 # file modified using a text widget
-                value = Binary(value.encode(entity.text_encoding(attr)))
+                value = Binary(value.encode(entity.attribute_metadata(attr, 'encoding')))
             else:
                 # (filename, mimetype, stream)
                 val = Binary(value[2].read())
                 if not val.getvalue(): # usually an unexistant file
                     value = None
                 else:
-                    # XXX suppose a File compatible schema
                     val.filename = value[0]
-                    if entity.has_format(attr):
+                    if entity.has_metadata(attr, 'format'):
                         key = '%s_format' % attr
                         formparams[key] = value[1]
                         self.relations.append('X %s_format %%(%s)s'
                                               % (attr, key))
+                    # XXX suppose a File compatible schema
                     if entity.e_schema.has_subject_relation('name') \
                            and not formparams.get('name'):
                         formparams['name'] = value[0]
--- a/web/widgets.py	Thu Mar 12 18:41:26 2009 +0100
+++ b/web/widgets.py	Thu Mar 12 19:39:34 2009 +0100
@@ -410,7 +410,7 @@
             entity.req.fckeditor_config()
             if with_format:
                 if entity.has_eid():
-                    format = entity.format(self.name)
+                    format = entity.attribute_metadata(self.name, 'format')
                 else:
                     format = ''
                 frname = eid_param(self.name + '_format', entity.eid)
@@ -419,7 +419,7 @@
                     frname, format, frname)
             return u'%s<textarea cubicweb:type="wysiwyg" onkeypress="autogrow(this)" name="%s" %s>%s</textarea>' % (
                 hidden, self.rname, self.format_attrs(), dvalue)
-        if with_format and entity.has_format(self.name):
+        if with_format and entity.has_metadata(self.name, 'format'):
             fmtwdg = entity.get_widget(self.name + '_format')
             fmtwdgstr = fmtwdg.edit_render(entity, tabindex=self.attrs['tabindex'])
             self.attrs['tabindex'] = entity.req.next_tabindex()
@@ -467,7 +467,7 @@
     def _file_wdg(self, entity):
         wdgs = [u'<input type="file" name="%s" %s/>' % (self.rname, self.format_attrs())]
         req = entity.req
-        if entity.has_format(self.name) or entity.has_text_encoding(self.name):
+        if entity.has_metadata(self.name, 'format') or entity.has_metadata(self.name, 'encoding'):
             divid = '%s-%s-advanced' % (self.name, entity.eid)
             wdgs.append(u'<a href="%s" title="%s"><img src="%s" alt="%s"/></a>' %
                         (html_escape(toggle_action(divid)),
@@ -509,14 +509,14 @@
     
     def _edit_render(self, entity):
         wdgs = [self._file_wdg(entity)]
-        if entity.format(self.name) in ('text/plain', 'text/html', 'text/rest'):
+        if entity.attribute_metadata(self.name, 'format') in ('text/plain', 'text/html', 'text/rest'):
             msg = self._edit_msg(entity)
             wdgs.append(u'<p><b>%s</b></p>' % msg)
             twdg = TextWidget(self.vreg, self.subjtype, self.rschema, self.objtype)
             twdg.rname = self.rname
             data = getattr(entity, self.name)
             if data:
-                encoding = entity.text_encoding(self.name)
+                encoding = entity.attribute_metadata(self.name, 'encoding')
                 try:
                     entity[self.name] = unicode(data.getvalue(), encoding)
                 except UnicodeError: