#370578: change EmailAddress identical_to/canonical to prefered_form 3.5
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 14 Sep 2009 12:17:31 +0200
branch3.5
changeset 3204 0b766b8a13e1
parent 3200 747d17498cca
child 3205 dc67e9431f34
#370578: change EmailAddress identical_to/canonical to prefered_form
entities/lib.py
entities/test/unittest_base.py
schemas/base.py
test/unittest_schema.py
web/views/emailaddress.py
--- a/entities/lib.py	Mon Sep 14 11:32:07 2009 +0200
+++ b/entities/lib.py	Mon Sep 14 12:17:31 2009 +0200
@@ -11,6 +11,7 @@
 from datetime import datetime
 
 from logilab.common.decorators import cached
+from logilab.common.deprecation import deprecated
 
 from cubicweb import UnknownProperty
 from cubicweb.entity import _marker
@@ -25,7 +26,7 @@
 
 class EmailAddress(AnyEntity):
     id = 'EmailAddress'
-    fetch_attrs, fetch_order = fetch_config(['address', 'alias', 'canonical'])
+    fetch_attrs, fetch_order = fetch_config(['address', 'alias'])
 
     def dc_title(self):
         if self.alias:
@@ -36,15 +37,13 @@
     def email_of(self):
         return self.reverse_use_email and self.reverse_use_email[0]
 
-    @cached
+    @property
+    def prefered(self):
+        return self.prefered_form and self.prefered_form[0] or None
+
+    @deprecated('use .prefered')
     def canonical_form(self):
-        if self.canonical:
-            return self
-        rql = 'EmailAddress X WHERE X identical_to Y, X canonical TRUE, Y eid %(y)s'
-        cnrset = self.req.execute(rql, {'y': self.eid}, 'y')
-        if cnrset:
-            return cnrset.get_entity(0, 0)
-        return None
+        return self.prefered_form and self.prefered_form[0] or self
 
     def related_emails(self, skipeids=None):
         # XXX move to eemail
--- a/entities/test/unittest_base.py	Mon Sep 14 11:32:07 2009 +0200
+++ b/entities/test/unittest_base.py	Mon Sep 14 12:17:31 2009 +0200
@@ -60,16 +60,13 @@
 
 class EmailAddressTC(BaseEntityTC):
     def test_canonical_form(self):
-        eid1 = self.execute('INSERT EmailAddress X: X address "maarten.ter.huurne@philips.com"')[0][0]
-        eid2 = self.execute('INSERT EmailAddress X: X address "maarten@philips.com", X canonical TRUE')[0][0]
-        self.execute('SET X identical_to Y WHERE X eid %s, Y eid %s' % (eid1, eid2))
-        email1 = self.entity('Any X WHERE X eid %(x)s', {'x':eid1}, 'x')
-        email2 = self.entity('Any X WHERE X eid %(x)s', {'x':eid2}, 'x')
-        self.assertEquals(email1.canonical_form().eid, eid2)
-        self.assertEquals(email2.canonical_form(), email2)
-        eid3 = self.execute('INSERT EmailAddress X: X address "toto@logilab.fr"')[0][0]
-        email3 = self.entity('Any X WHERE X eid %s'%eid3)
-        self.assertEquals(email3.canonical_form(), None)
+        email1 = self.execute('INSERT EmailAddress X: X address "maarten.ter.huurne@philips.com"').get_entity(0, 0)
+        email2 = self.execute('INSERT EmailAddress X: X address "maarten@philips.com"').get_entity(0, 0)
+        email3 = self.execute('INSERT EmailAddress X: X address "toto@logilab.fr"').get_entity(0, 0)
+        self.execute('SET X prefered_form Y WHERE X eid %s, Y eid %s' % (email1.eid, email2.eid))
+        self.assertEquals(email1.canonical_form().eid, email2.eid)
+        self.assertEquals(email2.canonical_form(), email2.eid)
+        self.assertEquals(email3.canonical_form(), email3.eid)
 
     def test_mangling(self):
         eid = self.execute('INSERT EmailAddress X: X address "maarten.ter.huurne@philips.com"')[0][0]
--- a/schemas/base.py	Mon Sep 14 11:32:07 2009 +0200
+++ b/schemas/base.py	Mon Sep 14 12:17:31 2009 +0200
@@ -52,11 +52,10 @@
     alias   = String(fulltextindexed=True, maxsize=56)
     address = String(required=True, fulltextindexed=True,
                      indexed=True, unique=True, maxsize=128)
-    canonical = Boolean(default=False,
-                        description=_('when multiple addresses are equivalent \
+    prefered_form = SubjectRelation('EmailAddress', cardinality='?*',
+                                    description=_('when multiple addresses are equivalent \
 (such as python-projects@logilab.org and python-projects@lists.logilab.org), set this \
-to true on one of them which is the preferred form.'))
-    identical_to = SubjectRelation('EmailAddress')
+to indicate which is the preferred form.'))
 
 class use_email(RelationType):
     """ """
@@ -71,9 +70,7 @@
     """the prefered email"""
     permissions = use_email.permissions
 
-class identical_to(RelationType):
-    """identical_to"""
-    symetric = True
+class prefered_form(RelationType):
     permissions = {
         'read':   ('managers', 'users', 'guests',),
         # XXX should have update permissions on both subject and object,
@@ -207,10 +204,6 @@
         }
 
 
-class see_also(RelationType):
-    """generic relation to link one entity to another"""
-    symetric = True
-
 class ExternalUri(EntityType):
     """a URI representing an object in external data store"""
     uri = String(required=True, unique=True, maxsize=256,
@@ -254,3 +247,25 @@
     name = String(required=True, unique=True, indexed=True,  maxsize=128,
                   description=_('name of the cache'))
     timestamp = Datetime(default='NOW')
+
+
+# "abtract" relation types, not used in cubicweb itself
+
+class identical_to(RelationType):
+    """identical to"""
+    symetric = True
+    permissions = {
+        'read':   ('managers', 'users', 'guests',),
+        # XXX should have update permissions on both subject and object,
+        #     though by doing this we will probably have no way to add
+        #     this relation in the web ui. The easiest way to acheive this
+        #     is probably to be able to have "U has_update_permission O" as
+        #     RQLConstraint of the relation definition, though this is not yet
+        #     possible
+        'add':    ('managers', RRQLExpression('U has_update_permission S'),),
+        'delete': ('managers', RRQLExpression('U has_update_permission S'),),
+        }
+
+class see_also(RelationType):
+    """generic relation to link one entity to another"""
+    symetric = True
--- a/test/unittest_schema.py	Mon Sep 14 11:32:07 2009 +0200
+++ b/test/unittest_schema.py	Mon Sep 14 12:17:31 2009 +0200
@@ -162,7 +162,7 @@
         expected_relations = ['add_permission', 'address', 'alias', 'allowed_transition',
                               'bookmarked_by', 'by_transition',
 
-                              'canonical', 'cardinality', 'comment', 'comment_format',
+                              'cardinality', 'comment', 'comment_format',
                               'composite', 'condition', 'connait', 'constrained_by', 'content',
                               'content_format', 'created_by', 'creation_date', 'cstrtype', 'custom_workflow', 'cwuri',
 
@@ -175,7 +175,7 @@
                               'from_entity', 'from_state', 'fulltext_container', 'fulltextindexed',
 
                               'has_text',
-                              'identical_to', 'identity', 'in_group', 'in_state', 'indexed',
+                              'identity', 'in_group', 'in_state', 'indexed',
                               'initial_state', 'inlined', 'internationalizable', 'is', 'is_instance_of',
 
                               'label', 'last_login_time', 'login',
@@ -186,7 +186,7 @@
 
                               'ordernum', 'owned_by',
 
-                              'path', 'pkey', 'prenom', 'primary_email',
+                              'path', 'pkey', 'prefered_form', 'prenom', 'primary_email',
 
                               'read_permission', 'relation_type', 'require_group',
 
--- a/web/views/emailaddress.py	Mon Sep 14 11:32:07 2009 +0200
+++ b/web/views/emailaddress.py	Mon Sep 14 12:17:31 2009 +0200
@@ -24,17 +24,9 @@
     def render_entity_attributes(self, entity):
         self.w(u'<h3>')
         entity.view('oneline', w=self.w)
-        if not entity.canonical:
-            canonemailaddr = entity.canonical_form()
-            if canonemailaddr:
-                self.w(u'&#160;(<i>%s</i>)' % canonemailaddr.view('oneline'))
-            self.w(u'</h3>')
-        elif entity.identical_to:
-            self.w(u'</h3>')
-            identicaladdr = [e.view('oneline') for e in entity.identical_to]
-            self.field('identical_to', ', '.join(identicaladdr))
-        else:
-            self.w(u'</h3>')
+        if entity.prefered:
+            self.w(u'&#160;(<i>%s</i>)' % entity.prefered.view('oneline'))
+        self.w(u'</h3>')
         try:
             persons = entity.reverse_primary_email
         except Unauthorized: