entities/lib.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 30 Mar 2010 19:55:20 +0200
branchstable
changeset 5090 8c39d2bf58fd
parent 4252 6c4f109c2b03
child 5174 78438ad513ca
child 5421 8167de96c523
permissions -rw-r--r--
[repo creation] removing existing entities of 'single' cardinality relatino should be considered as 'activeintegrity' hook. Also don't disable that category during repo creation to avoid pb such as two default workflows for one entity types

"""entity classes for optional library entities

:organization: Logilab
:copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"

from urlparse import urlsplit, urlunsplit
from datetime import datetime

from logilab.common.deprecation import deprecated

from cubicweb import UnknownProperty
from cubicweb.entity import _marker
from cubicweb.entities import AnyEntity, fetch_config

def mangle_email(address):
    try:
        name, host = address.split('@', 1)
    except ValueError:
        return address
    return '%s at %s' % (name, host.replace('.', ' dot '))

class EmailAddress(AnyEntity):
    __regid__ = 'EmailAddress'
    fetch_attrs, fetch_order = fetch_config(['address', 'alias'])

    def dc_title(self):
        if self.alias:
            return '%s <%s>' % (self.alias, self.display_address())
        return self.display_address()

    @property
    def email_of(self):
        return self.reverse_use_email and self.reverse_use_email[0]

    @property
    def prefered(self):
        return self.prefered_form and self.prefered_form[0] or self

    @deprecated('use .prefered')
    def canonical_form(self):
        return self.prefered_form and self.prefered_form[0] or self

    def related_emails(self, skipeids=None):
        # XXX move to eemail
        # check email relations are in the schema first
        subjrels = self.e_schema.object_relations()
        if not ('sender' in subjrels and 'recipients' in subjrels):
            return
        rql = 'DISTINCT Any X, S, D ORDERBY D DESC WHERE X sender Y or X recipients Y, X subject S, X date D, Y eid %(y)s'
        rset = self._cw.execute(rql, {'y': self.eid}, 'y')
        if skipeids is None:
            skipeids = set()
        for i in xrange(len(rset)):
            eid = rset[i][0]
            if eid in skipeids:
                continue
            skipeids.add(eid)
            yield rset.get_entity(i, 0)

    def display_address(self):
        if self._cw.vreg.config['mangle-emails']:
            return mangle_email(self.address)
        return self.address

    def printable_value(self, attr, value=_marker, attrtype=None,
                        format='text/html'):
        """overriden to return displayable address when necessary"""
        if attr == 'address':
            return self.display_address()
        return super(EmailAddress, self).printable_value(attr, value, attrtype, format)

    def after_deletion_path(self):
        """return (path, parameters) which should be used as redirect
        information when this entity is being deleted
        """
        if self.email_of:
            return self.email_of.rest_path(), {}
        return super(EmailAddress, self).after_deletion_path()


class Bookmark(AnyEntity):
    """customized class for Bookmark entities"""
    __regid__ = 'Bookmark'
    fetch_attrs, fetch_order = fetch_config(['title', 'path'])

    def actual_url(self):
        url = self._cw.build_url(self.path)
        if self.title:
            urlparts = list(urlsplit(url))
            if urlparts[3]:
                urlparts[3] += '&vtitle=%s' % self._cw.url_quote(self.title)
            else:
                urlparts[3] = 'vtitle=%s' % self._cw.url_quote(self.title)
            url = urlunsplit(urlparts)
        return url

    def action_url(self):
        return self.absolute_url() + '/follow'


class CWProperty(AnyEntity):
    __regid__ = 'CWProperty'

    fetch_attrs, fetch_order = fetch_config(['pkey', 'value'])
    rest_attr = 'pkey'

    def typed_value(self):
        return self._cw.vreg.typed_value(self.pkey, self.value)

    def dc_description(self, format='text/plain'):
        try:
            return self._cw._(self._cw.vreg.property_info(self.pkey)['help'])
        except UnknownProperty:
            return u''

    def after_deletion_path(self):
        """return (path, parameters) which should be used as redirect
        information when this entity is being deleted
        """
        return 'view', {}


class CWCache(AnyEntity):
    """Cache"""
    __regid__ = 'CWCache'
    fetch_attrs, fetch_order = fetch_config(['name'])

    def touch(self):
        self._cw.execute('SET X timestamp %(t)s WHERE X eid %(x)s',
                         {'t': datetime.now(), 'x': self.eid}, 'x')

    def valid(self, date):
        if date:
            return date > self.timestamp
        return False