--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/entities/adapters.py Thu May 20 20:47:55 2010 +0200
@@ -0,0 +1,166 @@
+# copyright 2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This file is part of CubicWeb.
+#
+# CubicWeb is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 2.1 of the License, or (at your option)
+# any later version.
+#
+# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
+"""some basic entity adapter implementations, for interfaces used in the
+framework itself.
+"""
+
+__docformat__ = "restructuredtext en"
+
+from cubicweb.view import EntityAdapter, implements_adapter_compat
+from cubicweb.selectors import implements, relation_possible
+from cubicweb.interfaces import IDownloadable
+
+
+class IEmailableAdapter(EntityAdapter):
+ __regid__ = 'IEmailable'
+ __select__ = relation_possible('primary_email') | relation_possible('use_email')
+
+ def get_email(self):
+ if getattr(self.entity, 'primary_email', None):
+ return self.entity.primary_email[0].address
+ if getattr(self.entity, 'use_email', None):
+ return self.entity.use_email[0].address
+ return None
+
+ def allowed_massmail_keys(self):
+ """returns a set of allowed email substitution keys
+
+ The default is to return the entity's attribute list but you might
+ override this method to allow extra keys. For instance, a Person
+ class might want to return a `companyname` key.
+ """
+ return set(rschema.type
+ for rschema, attrtype in self.entity.e_schema.attribute_definitions()
+ if attrtype.type not in ('Password', 'Bytes'))
+
+ def as_email_context(self):
+ """returns the dictionary as used by the sendmail controller to
+ build email bodies.
+
+ NOTE: the dictionary keys should match the list returned by the
+ `allowed_massmail_keys` method.
+ """
+ return dict( (attr, getattr(self.entity, attr))
+ for attr in self.allowed_massmail_keys() )
+
+
+class INotifiableAdapter(EntityAdapter):
+ __regid__ = 'INotifiable'
+ __select__ = implements('Any')
+
+ @implements_adapter_compat('INotifiableAdapter')
+ def notification_references(self, view):
+ """used to control References field of email send on notification
+ for this entity. `view` is the notification view.
+
+ Should return a list of eids which can be used to generate message
+ identifiers of previously sent email(s)
+ """
+ itree = self.entity.cw_adapt_to('ITree')
+ if itree is not None:
+ return itree.path()[:-1]
+ return ()
+
+
+class IFTIndexableAdapter(EntityAdapter):
+ __regid__ = 'IFTIndexable'
+ __select__ = implements('Any')
+
+ def fti_containers(self, _done=None):
+ if _done is None:
+ _done = set()
+ entity = self.entity
+ _done.add(entity.eid)
+ containers = tuple(entity.e_schema.fulltext_containers())
+ if containers:
+ for rschema, target in containers:
+ if target == 'object':
+ targets = getattr(entity, rschema.type)
+ else:
+ targets = getattr(entity, 'reverse_%s' % rschema)
+ for entity in targets:
+ if entity.eid in _done:
+ continue
+ for container in entity.cw_adapt_to('IFTIndexable').fti_containers(_done):
+ yield container
+ yielded = True
+ else:
+ yield entity
+
+ def get_words(self):
+ """used by the full text indexer to get words to index
+
+ this method should only be used on the repository side since it depends
+ on the logilab.database package
+
+ :rtype: list
+ :return: the list of indexable word of this entity
+ """
+ from logilab.database.fti import tokenize
+ # take care to cases where we're modyfying the schema
+ entity = self.entity
+ pending = self._cw.transaction_data.setdefault('pendingrdefs', set())
+ words = []
+ for rschema in entity.e_schema.indexable_attributes():
+ if (entity.e_schema, rschema) in pending:
+ continue
+ try:
+ value = entity.printable_value(rschema, format='text/plain')
+ except TransformError:
+ continue
+ except:
+ self.exception("can't add value of %s to text index for entity %s",
+ rschema, entity.eid)
+ continue
+ if value:
+ words += tokenize(value)
+ for rschema, role in entity.e_schema.fulltext_relations():
+ if role == 'subject':
+ for entity in getattr(entity, rschema.type):
+ words += entity.cw_adapt_to('IFTIndexable').get_words()
+ else: # if role == 'object':
+ for entity in getattr(entity, 'reverse_%s' % rschema.type):
+ words += entity.cw_adapt_to('IFTIndexable').get_words()
+ return words
+
+
+class IDownloadableAdapter(EntityAdapter):
+ """interface for downloadable entities"""
+ __regid__ = 'IDownloadable'
+ __select__ = implements(IDownloadable) # XXX for bw compat, else should be abstract
+
+ @implements_adapter_compat('IDownloadable')
+ def download_url(self): # XXX not really part of this interface
+ """return an url to download entity's content"""
+ raise NotImplementedError
+ @implements_adapter_compat('IDownloadable')
+ def download_content_type(self):
+ """return MIME type of the downloadable content"""
+ raise NotImplementedError
+ @implements_adapter_compat('IDownloadable')
+ def download_encoding(self):
+ """return encoding of the downloadable content"""
+ raise NotImplementedError
+ @implements_adapter_compat('IDownloadable')
+ def download_file_name(self):
+ """return file name of the downloadable content"""
+ raise NotImplementedError
+ @implements_adapter_compat('IDownloadable')
+ def download_data(self):
+ """return actual data of the downloadable content"""
+ raise NotImplementedError