cubicweb/entities/adapters.py
author Simon Chabot <simon.chabot@logilab.fr>
Fri, 28 Feb 2020 17:11:01 +0100
changeset 12892 0df0db725f07
parent 12891 eb0cd6060062
child 12910 c87c3943d6ab
permissions -rw-r--r--
[rdf] Add a basic foaf adapter for CWUser By the way, use RDFLib namespaces
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11761
diff changeset
     1
# copyright 2010-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     3
#
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     4
# This file is part of CubicWeb.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     5
#
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     9
# any later version.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    10
#
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    14
# details.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    15
#
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    18
"""some basic entity adapter implementations, for interfaces used in the
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
framework itself.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    20
"""
10666
7f6b5f023884 [py3k] replace '_ = unicode' in global scope (closes #7589459)
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    21
from cubicweb import _
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
12892
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    23
from hashlib import sha1
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    24
from itertools import chain
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    25
12892
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    26
from rdflib import URIRef, Literal
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    27
5694
ce2c108a9595 [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5574
diff changeset
    28
from logilab.mtconverter import TransformError
12891
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    29
from logilab.common.decorators import cached, cachedproperty
5694
ce2c108a9595 [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5574
diff changeset
    30
12880
59d4ad7e7df3 [adapters] move class EntityAdapter from cubicweb.view to cubicweb.entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12512
diff changeset
    31
from cubicweb.entity import EntityAdapter
59d4ad7e7df3 [adapters] move class EntityAdapter from cubicweb.view to cubicweb.entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12512
diff changeset
    32
from cubicweb import (Unauthorized, ValidationError, ViolatedConstraint,
11946
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    33
                      UniqueTogetherError)
12512
661dd0436c01 [schema] drop monkeypatch "name_for" on BaseConstraint
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12355
diff changeset
    34
from cubicweb.schema import constraint_name_for
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
    35
from cubicweb.predicates import is_instance, relation_possible, match_exception
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    36
12892
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    37
from cubicweb.rdf import NAMESPACES
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    38
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    39
12891
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    40
class EntityRDFAdapter(EntityAdapter):
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    41
    """EntityRDFAdapter is to be specialized for each entity that wants to
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    42
    be converted to RDF using the mechanism from cubicweb.rdf
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    43
    """
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    44
    __abstract__ = True
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    45
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    46
    def __init__(self, _cw, **kwargs):
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    47
        super().__init__(_cw, **kwargs)
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    48
        self.entity.complete()
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    49
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    50
    @cachedproperty
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    51
    def uri(self):
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    52
        return self.entity.cwuri
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    53
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    54
    def triples(self):
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    55
        """return sequence of 3-tuple of rdflib identifiers"""
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    56
        raise NotImplementedError()
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    57
eb0cd6060062 [rdf] add functions and tools to generate rdf graph
Simon Chabot <simon.chabot@logilab.fr>
parents: 12880
diff changeset
    58
12892
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    59
class CWUserFoafAdapter(EntityRDFAdapter):
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    60
    __regid__ = "rdf.foaf"
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    61
    __select__ = is_instance("CWUser")
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    62
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    63
    def triples(self):
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    64
        RDF = NAMESPACES["rdf"]
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    65
        FOAF = NAMESPACES["foaf"]
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    66
        uri = URIRef(self.uri)
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    67
        yield (uri, RDF.type, FOAF.Person)
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    68
        if self.entity.surname:
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    69
            yield (uri, FOAF.familyName, Literal(self.entity.surname))
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    70
        if self.entity.firstname:
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    71
            yield (uri, FOAF.givenName, Literal(self.entity.firstname))
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    72
        emailaddr = self.entity.cw_adapt_to("IEmailable").get_email()
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    73
        if emailaddr:
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    74
            email_digest = sha1(emailaddr.encode("utf-8")).hexdigest()
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    75
            yield (uri, FOAF.mbox_sha1sum, Literal(email_digest))
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    76
0df0db725f07 [rdf] Add a basic foaf adapter for CWUser
Simon Chabot <simon.chabot@logilab.fr>
parents: 12891
diff changeset
    77
12880
59d4ad7e7df3 [adapters] move class EntityAdapter from cubicweb.view to cubicweb.entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12512
diff changeset
    78
class IDublinCoreAdapter(EntityAdapter):
11946
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    79
    __regid__ = 'IDublinCore'
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    80
    __select__ = is_instance('Any')
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    81
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    82
    def title(self):
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    83
        """Return a suitable *unicode* title for entity"""
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    84
        entity = self.entity
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    85
        for rschema, attrschema in entity.e_schema.attribute_definitions():
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    86
            if rschema.meta:
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    87
                continue
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    88
            value = entity.cw_attr_value(rschema.type)
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    89
            if value is not None:
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    90
                # make the value printable (dates, floats, bytes, etc.)
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    91
                return entity.printable_value(
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    92
                    rschema.type, value, attrschema.type, format='text/plain')
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    93
        return u'%s #%s' % (self.type(), entity.eid)
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    94
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    95
    def long_title(self):
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
    96
        """Return a more detailled title for entity"""
12160
608481168432 [entities] Fix backward compat of IDublinCore adapter wrt dc_long_title
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11946
diff changeset
    97
        # go through entity.dc_title for bw compat purpose: if entity define dc_title but not
608481168432 [entities] Fix backward compat of IDublinCore adapter wrt dc_long_title
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11946
diff changeset
    98
        # dc_long_title, we still want it to be considered.
608481168432 [entities] Fix backward compat of IDublinCore adapter wrt dc_long_title
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11946
diff changeset
    99
        return self.entity.dc_title()
11946
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   100
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   101
    def description(self, format='text/plain'):
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   102
        """Return a suitable description for entity"""
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   103
        if 'description' in self.entity.e_schema.subjrels:
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   104
            return self.entity.printable_value('description', format=format)
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   105
        return u''
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   106
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   107
    def authors(self):
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   108
        """Return a suitable description for the author(s) of the entity"""
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   109
        try:
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   110
            return u', '.join(u.name() for u in self.entity.owned_by)
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   111
        except Unauthorized:
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   112
            return u''
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   113
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   114
    def creator(self):
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   115
        """Return a suitable description for the creator of the entity"""
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   116
        if self.entity.creator:
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   117
            return self.entity.creator.name()
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   118
        return u''
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   119
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   120
    def date(self, date_format=None):  # XXX default to ISO 8601 ?
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   121
        """Return latest modification date of entity"""
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   122
        return self._cw.format_date(self.entity.modification_date,
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   123
                                    date_format=date_format)
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   124
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   125
    def type(self, form=''):
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   126
        """Return the display name for the type of entity (translated)"""
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   127
        return self.entity.e_schema.display_name(self._cw, form)
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   128
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   129
    def language(self):
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   130
        """Return language used by this entity (translated)"""
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   131
        eschema = self.entity.e_schema
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   132
        # check if entities has internationalizable attributes
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   133
        # XXX one is enough or check if all String attributes are internationalizable?
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   134
        for rschema, attrschema in eschema.attribute_definitions():
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   135
            if rschema.rdef(eschema, attrschema).internationalizable:
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   136
                return self._cw._(self._cw.user.property_value('ui.language'))
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   137
        return self._cw._(self._cw.vreg.property_value('ui.language'))
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   138
8de62610cea2 [entities] Introduce an IDublinCore adapter
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11767
diff changeset
   139
12880
59d4ad7e7df3 [adapters] move class EntityAdapter from cubicweb.view to cubicweb.entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12512
diff changeset
   140
class IEmailableAdapter(EntityAdapter):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   141
    __regid__ = 'IEmailable'
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   142
    __select__ = relation_possible('primary_email') | relation_possible('use_email')
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   143
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   144
    def get_email(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   145
        if getattr(self.entity, 'primary_email', None):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   146
            return self.entity.primary_email[0].address
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   147
        if getattr(self.entity, 'use_email', None):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
            return self.entity.use_email[0].address
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
        return None
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   150
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   151
    def allowed_massmail_keys(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   152
        """returns a set of allowed email substitution keys
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   153
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   154
        The default is to return the entity's attribute list but you might
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   155
        override this method to allow extra keys.  For instance, a Person
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   156
        class might want to return a `companyname` key.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   157
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   158
        return set(rschema.type
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   159
                   for rschema, attrtype in self.entity.e_schema.attribute_definitions()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   160
                   if attrtype.type not in ('Password', 'Bytes'))
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   161
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   162
    def as_email_context(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
        """returns the dictionary as used by the sendmail controller to
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   164
        build email bodies.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   165
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   166
        NOTE: the dictionary keys should match the list returned by the
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   167
        `allowed_massmail_keys` method.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   168
        """
10974
6557833657d6 a bit of pep8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10973
diff changeset
   169
        return dict((attr, getattr(self.entity, attr))
6557833657d6 a bit of pep8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10973
diff changeset
   170
                    for attr in self.allowed_massmail_keys())
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   171
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   172
12880
59d4ad7e7df3 [adapters] move class EntityAdapter from cubicweb.view to cubicweb.entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12512
diff changeset
   173
class INotifiableAdapter(EntityAdapter):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   174
    __regid__ = 'INotifiable'
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
   175
    __select__ = is_instance('Any')
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   176
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   177
    def notification_references(self, view):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   178
        """used to control References field of email send on notification
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   179
        for this entity. `view` is the notification view.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   180
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   181
        Should return a list of eids which can be used to generate message
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   182
        identifiers of previously sent email(s)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   183
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   184
        itree = self.entity.cw_adapt_to('ITree')
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   185
        if itree is not None:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   186
            return itree.path()[:-1]
10262
5c2a4a0a8dbd [entities] return the entity itself from notification_references if the view uses a random message-id
Julien Cristau <julien.cristau@logilab.fr>
parents: 9918
diff changeset
   187
        if view.msgid_timestamp:
5c2a4a0a8dbd [entities] return the entity itself from notification_references if the view uses a random message-id
Julien Cristau <julien.cristau@logilab.fr>
parents: 9918
diff changeset
   188
            return (self.entity.eid,)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   189
        return ()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   190
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   191
12880
59d4ad7e7df3 [adapters] move class EntityAdapter from cubicweb.view to cubicweb.entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12512
diff changeset
   192
class IFTIndexableAdapter(EntityAdapter):
8518
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   193
    """standard adapter to handle fulltext indexing
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   194
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   195
    .. automethod:: cubicweb.entities.adapters.IFTIndexableAdapter.fti_containers
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   196
    .. automethod:: cubicweb.entities.adapters.IFTIndexableAdapter.get_words
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   197
    """
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   198
    __regid__ = 'IFTIndexable'
5877
0c7b7b76a84f [selectors] provide a new, optimized, is_instance selector that should at some point replace implements (along with the adaptable selector)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5768
diff changeset
   199
    __select__ = is_instance('Any')
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   200
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   201
    def fti_containers(self, _done=None):
8518
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   202
        """return the list of entities to index when handling ``self.entity``
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   203
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   204
        The actual list of entities depends on ``fulltext_container`` usage
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   205
        in the datamodel definition
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   206
        """
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   207
        if _done is None:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   208
            _done = set()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   209
        entity = self.entity
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   210
        _done.add(entity.eid)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   211
        containers = tuple(entity.e_schema.fulltext_containers())
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   212
        if containers:
9433
dd708175dc43 [adapters] fix a name stomping error (entity)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   213
            for rschema, role in containers:
dd708175dc43 [adapters] fix a name stomping error (entity)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   214
                if role == 'object':
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   215
                    targets = getattr(entity, rschema.type)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   216
                else:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   217
                    targets = getattr(entity, 'reverse_%s' % rschema)
9433
dd708175dc43 [adapters] fix a name stomping error (entity)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   218
                for target in targets:
dd708175dc43 [adapters] fix a name stomping error (entity)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   219
                    if target.eid in _done:
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   220
                        continue
9433
dd708175dc43 [adapters] fix a name stomping error (entity)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   221
                    for container in target.cw_adapt_to('IFTIndexable').fti_containers(_done):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   222
                        yield container
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   223
        else:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   224
            yield entity
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   225
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   226
    # weight in ABCD
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   227
    entity_weight = 1.0
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   228
    attr_weight = {}
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   229
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   230
    def get_words(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   231
        """used by the full text indexer to get words to index
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   232
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   233
        this method should only be used on the repository side since it depends
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   234
        on the logilab.database package
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   235
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   236
        :rtype: list
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   237
        :return: the list of indexable word of this entity
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   238
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   239
        from logilab.database.fti import tokenize
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   240
        # take care to cases where we're modyfying the schema
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   241
        entity = self.entity
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   242
        pending = self._cw.transaction_data.setdefault('pendingrdefs', set())
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   243
        words = {}
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   244
        for rschema in entity.e_schema.indexable_attributes():
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   245
            if (entity.e_schema, rschema) in pending:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   246
                continue
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   247
            weight = self.attr_weight.get(rschema, 'C')
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   248
            try:
10473
23a2fa8cb725 avoid sanitizing warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10446
diff changeset
   249
                value = entity.printable_value(rschema, format=u'text/plain')
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   250
            except TransformError:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   251
                continue
7815
2a164a9cf81c [exceptions] stop catching any exception in various places (closes #1942716)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6974
diff changeset
   252
            except Exception:
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   253
                self.exception("can't add value of %s to text index for entity %s",
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   254
                               rschema, entity.eid)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   255
                continue
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   256
            if value:
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   257
                words.setdefault(weight, []).extend(tokenize(value))
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   258
        for rschema, role in entity.e_schema.fulltext_relations():
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   259
            if role == 'subject':
5574
e082a57c2207 [fti] fix name conflict introduced by the new IFTIAdapter
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
   260
                for entity_ in getattr(entity, rschema.type):
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   261
                    merge_weight_dict(words, entity_.cw_adapt_to('IFTIndexable').get_words())
10974
6557833657d6 a bit of pep8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10973
diff changeset
   262
            else:  # if role == 'object':
5574
e082a57c2207 [fti] fix name conflict introduced by the new IFTIAdapter
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
   263
                for entity_ in getattr(entity, 'reverse_%s' % rschema.type):
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   264
                    merge_weight_dict(words, entity_.cw_adapt_to('IFTIndexable').get_words())
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   265
        return words
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   266
10974
6557833657d6 a bit of pep8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10973
diff changeset
   267
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   268
def merge_weight_dict(maindict, newdict):
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10473
diff changeset
   269
    for weight, words in newdict.items():
5768
1e73a466aa69 [fti] support for fti ranking: has_text query results sorted by relevance, and provides a way to control weight per entity / entity's attribute
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5722
diff changeset
   270
        maindict.setdefault(weight, []).extend(words)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   271
10974
6557833657d6 a bit of pep8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10973
diff changeset
   272
12880
59d4ad7e7df3 [adapters] move class EntityAdapter from cubicweb.view to cubicweb.entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12512
diff changeset
   273
class IDownloadableAdapter(EntityAdapter):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   274
    """interface for downloadable entities"""
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   275
    __regid__ = 'IDownloadable'
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   276
    __abstract__ = True
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   277
10974
6557833657d6 a bit of pep8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10973
diff changeset
   278
    def download_url(self, **kwargs):  # XXX not really part of this interface
10732
6231587fcfc5 [py3k] Clarify IDownloadable expected types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10731
diff changeset
   279
        """return a URL to download entity's content
6231587fcfc5 [py3k] Clarify IDownloadable expected types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10731
diff changeset
   280
10974
6557833657d6 a bit of pep8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10973
diff changeset
   281
        It should be a unicode object containing url-encoded ASCII.
6557833657d6 a bit of pep8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10973
diff changeset
   282
        """
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   283
        raise NotImplementedError
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   284
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   285
    def download_content_type(self):
10732
6231587fcfc5 [py3k] Clarify IDownloadable expected types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10731
diff changeset
   286
        """return MIME type (unicode) of the downloadable content"""
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   287
        raise NotImplementedError
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   288
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   289
    def download_encoding(self):
10732
6231587fcfc5 [py3k] Clarify IDownloadable expected types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10731
diff changeset
   290
        """return encoding (unicode) of the downloadable content"""
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   291
        raise NotImplementedError
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   292
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   293
    def download_file_name(self):
10732
6231587fcfc5 [py3k] Clarify IDownloadable expected types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10731
diff changeset
   294
        """return file name (unicode) of the downloadable content"""
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   295
        raise NotImplementedError
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   296
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   297
    def download_data(self):
10731
0736e31f8644 [py3k] IDownloadable.download_data() returns bytes
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10671
diff changeset
   298
        """return actual data (bytes) of the downloadable content"""
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   299
        raise NotImplementedError
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   300
10974
6557833657d6 a bit of pep8
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10973
diff changeset
   301
6974
6f23b2baf99b add a note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6864
diff changeset
   302
# XXX should propose to use two different relations for children/parent
12880
59d4ad7e7df3 [adapters] move class EntityAdapter from cubicweb.view to cubicweb.entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12512
diff changeset
   303
class ITreeAdapter(EntityAdapter):
9705
1d40d3b10142 Drop duplicated content in ITreeAdapter docstring
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9700
diff changeset
   304
    """This adapter provides a tree interface.
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   305
9705
1d40d3b10142 Drop duplicated content in ITreeAdapter docstring
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9700
diff changeset
   306
    It has to be overriden to be configured using the tree_relation,
1d40d3b10142 Drop duplicated content in ITreeAdapter docstring
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9700
diff changeset
   307
    child_role and parent_role class attributes to benefit from this default
1d40d3b10142 Drop duplicated content in ITreeAdapter docstring
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9700
diff changeset
   308
    implementation.
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   309
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   310
    This class provides the following methods:
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   311
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   312
    .. automethod: iterparents
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   313
    .. automethod: iterchildren
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   314
    .. automethod: prefixiter
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   315
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   316
    .. automethod: is_leaf
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   317
    .. automethod: is_root
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   318
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   319
    .. automethod: root
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   320
    .. automethod: parent
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   321
    .. automethod: children
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   322
    .. automethod: different_type_children
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   323
    .. automethod: same_type_children
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   324
    .. automethod: children_rql
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   325
    .. automethod: path
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   326
    """
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   327
    __regid__ = 'ITree'
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   328
    __abstract__ = True
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   329
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   330
    child_role = 'subject'
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   331
    parent_role = 'object'
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   332
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   333
    def children_rql(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   334
        """Returns RQL to get the children of the entity."""
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   335
        return self.entity.cw_related_rql(self.tree_relation, self.parent_role)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   336
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   337
    def different_type_children(self, entities=True):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   338
        """Return children entities of different type as this entity.
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   339
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   340
        According to the `entities` parameter, return entity objects or the
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   341
        equivalent result set.
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   342
        """
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   343
        res = self.entity.related(self.tree_relation, self.parent_role,
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   344
                                  entities=entities)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   345
        eschema = self.entity.e_schema
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   346
        if entities:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   347
            return [e for e in res if e.e_schema != eschema]
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   348
        return res.filtered_rset(lambda x: x.e_schema != eschema, self.entity.cw_col)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   349
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   350
    def same_type_children(self, entities=True):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   351
        """Return children entities of the same type as this entity.
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   352
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   353
        According to the `entities` parameter, return entity objects or the
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   354
        equivalent result set.
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   355
        """
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   356
        res = self.entity.related(self.tree_relation, self.parent_role,
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   357
                                  entities=entities)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   358
        eschema = self.entity.e_schema
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   359
        if entities:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   360
            return [e for e in res if e.e_schema == eschema]
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   361
        return res.filtered_rset(lambda x: x.e_schema is eschema, self.entity.cw_col)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   362
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   363
    def is_leaf(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   364
        """Returns True if the entity does not have any children."""
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   365
        return len(self.children()) == 0
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   366
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   367
    def is_root(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   368
        """Returns true if the entity is root of the tree (e.g. has no parent).
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   369
        """
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   370
        return self.parent() is None
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   371
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   372
    def root(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   373
        """Return the root entity of the tree."""
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   374
        return self._cw.entity_from_eid(self.path()[0])
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   375
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   376
    def parent(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   377
        """Returns the parent entity if any, else None (e.g. if we are on the
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   378
        root).
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   379
        """
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   380
        try:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   381
            return self.entity.related(self.tree_relation, self.child_role,
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   382
                                       entities=True)[0]
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   383
        except (KeyError, IndexError):
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   384
            return None
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   385
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   386
    def children(self, entities=True, sametype=False):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   387
        """Return children entities.
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   388
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   389
        According to the `entities` parameter, return entity objects or the
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   390
        equivalent result set.
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   391
        """
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   392
        if sametype:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   393
            return self.same_type_children(entities)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   394
        else:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   395
            return self.entity.related(self.tree_relation, self.parent_role,
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   396
                                       entities=entities)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   397
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   398
    def iterparents(self, strict=True):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   399
        """Return an iterator on the parents of the entity."""
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   400
        def _uptoroot(self):
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   401
            curr = self
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   402
            while True:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   403
                curr = curr.parent()
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   404
                if curr is None:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   405
                    break
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   406
                yield curr
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   407
                curr = curr.cw_adapt_to('ITree')
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   408
        if not strict:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   409
            return chain([self.entity], _uptoroot(self))
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   410
        return _uptoroot(self)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   411
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   412
    def iterchildren(self, _done=None):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   413
        """Return an iterator over the item's children."""
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   414
        if _done is None:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   415
            _done = set()
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   416
        for child in self.children():
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   417
            if child.eid in _done:
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8801
diff changeset
   418
                self.error('loop in %s tree: %s', child.cw_etype.lower(), child)
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   419
                continue
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   420
            yield child
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   421
            _done.add(child.eid)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   422
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   423
    def prefixiter(self, _done=None):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   424
        """Return an iterator over the item's descendants in a prefixed order."""
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   425
        if _done is None:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   426
            _done = set()
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   427
        if self.entity.eid in _done:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   428
            return
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   429
        _done.add(self.entity.eid)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   430
        yield self.entity
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   431
        for child in self.same_type_children():
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   432
            for entity in child.cw_adapt_to('ITree').prefixiter(_done):
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   433
                yield entity
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   434
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   435
    @cached
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   436
    def path(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   437
        """Returns the list of eids from the root object to this object."""
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   438
        path = []
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   439
        adapter = self
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   440
        entity = adapter.entity
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   441
        while entity is not None:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   442
            if entity.eid in path:
8900
010a59e12d89 use cw_etype instead of __regid__
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8801
diff changeset
   443
                self.error('loop in %s tree: %s', entity.cw_etype.lower(), entity)
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   444
                break
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   445
            path.append(entity.eid)
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   446
            try:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   447
                # check we are not jumping to another tree
12355
c703dc95c82e Fix flake8 issues since release 3.6.0
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12160
diff changeset
   448
                if (adapter.tree_relation != self.tree_relation
c703dc95c82e Fix flake8 issues since release 3.6.0
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12160
diff changeset
   449
                        or adapter.child_role != self.child_role):
5716
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   450
                    break
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   451
                entity = adapter.parent()
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   452
                adapter = entity.cw_adapt_to('ITree')
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   453
            except AttributeError:
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   454
                break
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   455
        path.reverse()
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   456
        return path
0e2af244dea5 [web] move itree adapter to entities, it may be used outside the web interface
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
   457
5722
61d6a4caa963 [iprogress] move adapter to entities.adapters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5720
diff changeset
   458
12880
59d4ad7e7df3 [adapters] move class EntityAdapter from cubicweb.view to cubicweb.entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12512
diff changeset
   459
class ISerializableAdapter(EntityAdapter):
10973
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   460
    """Adapter to serialize an entity to a bare python structure that may be
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   461
    directly serialized to e.g. JSON.
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   462
    """
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   463
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   464
    __regid__ = 'ISerializable'
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   465
    __select__ = is_instance('Any')
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   466
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   467
    def serialize(self):
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   468
        entity = self.entity
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   469
        entity.complete()
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   470
        data = {
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   471
            'cw_etype': entity.cw_etype,
11044
00c5ee272a6d [entities] add eid to ISerializableAdapter
Julien Cristau <julien.cristau@logilab.fr>
parents: 10974
diff changeset
   472
            'eid': entity.eid,
10973
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   473
        }
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   474
        for rschema, __ in entity.e_schema.attribute_definitions():
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   475
            attr = rschema.type
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   476
            try:
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   477
                value = entity.cw_attr_cache[attr]
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   478
            except KeyError:
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   479
                # Bytes
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   480
                continue
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   481
            data[attr] = value
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   482
        return data
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   483
0939ad2edf63 [adapters] Use an adapter for serializing entities to a bare python structure
Rabah Meradi <rabah.meradi@logilab.fr>
parents: 10732
diff changeset
   484
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   485
# error handling adapters ######################################################
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   486
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   487
12880
59d4ad7e7df3 [adapters] move class EntityAdapter from cubicweb.view to cubicweb.entity
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 12512
diff changeset
   488
class IUserFriendlyError(EntityAdapter):
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   489
    __regid__ = 'IUserFriendlyError'
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   490
    __abstract__ = True
9130
0f1504a9fb51 [constraint] more robust unicity constraint failures reporting for end-users
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8930
diff changeset
   491
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   492
    def __init__(self, *args, **kwargs):
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   493
        self.exc = kwargs.pop('exc')
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   494
        super(IUserFriendlyError, self).__init__(*args, **kwargs)
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   495
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   496
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   497
class IUserFriendlyUniqueTogether(IUserFriendlyError):
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   498
    __select__ = match_exception(UniqueTogetherError)
9130
0f1504a9fb51 [constraint] more robust unicity constraint failures reporting for end-users
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8930
diff changeset
   499
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   500
    def raise_user_exception(self):
9375
8e88576787c3 [schema] fix unique together index handling
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9256
diff changeset
   501
        rtypes = self.exc.rtypes
10280
2cdab5e33542 [i18n] properly translate error messages related to violated unicity constraint.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9918
diff changeset
   502
        errors = {}
2cdab5e33542 [i18n] properly translate error messages related to violated unicity constraint.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9918
diff changeset
   503
        msgargs = {}
2cdab5e33542 [i18n] properly translate error messages related to violated unicity constraint.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9918
diff changeset
   504
        i18nvalues = []
9130
0f1504a9fb51 [constraint] more robust unicity constraint failures reporting for end-users
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8930
diff changeset
   505
        for rtype in rtypes:
10280
2cdab5e33542 [i18n] properly translate error messages related to violated unicity constraint.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9918
diff changeset
   506
            errors[rtype] = _('%(KEY-rtype)s is part of violated unicity constraint')
2cdab5e33542 [i18n] properly translate error messages related to violated unicity constraint.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9918
diff changeset
   507
            msgargs[rtype + '-rtype'] = rtype
2cdab5e33542 [i18n] properly translate error messages related to violated unicity constraint.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9918
diff changeset
   508
            i18nvalues.append(rtype + '-rtype')
2cdab5e33542 [i18n] properly translate error messages related to violated unicity constraint.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9918
diff changeset
   509
        errors[''] = _('some relations violate a unicity constraint')
2cdab5e33542 [i18n] properly translate error messages related to violated unicity constraint.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9918
diff changeset
   510
        raise ValidationError(self.entity.eid, errors, msgargs=msgargs, i18nvalues=i18nvalues)
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   511
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   512
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   513
class IUserFriendlyCheckConstraint(IUserFriendlyError):
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   514
    __select__ = match_exception(ViolatedConstraint)
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   515
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   516
    def raise_user_exception(self):
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   517
        cstrname = self.exc.cstrname
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   518
        eschema = self.entity.e_schema
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   519
        for rschema, attrschema in eschema.attribute_definitions():
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   520
            rdef = rschema.rdef(eschema, attrschema)
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   521
            for constraint in rdef.constraints:
12512
661dd0436c01 [schema] drop monkeypatch "name_for" on BaseConstraint
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12355
diff changeset
   522
                if cstrname == constraint_name_for(constraint, rdef):
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   523
                    break
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   524
            else:
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   525
                continue
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   526
            break
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   527
        else:
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   528
            assert 0
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   529
        key = rschema.type + '-subject'
11107
df1f2d853d40 quick fix which closes #0673348 - see comment for more info
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11044
diff changeset
   530
        # use .get since a constraint may be associated to an attribute that isn't edited (e.g.
df1f2d853d40 quick fix which closes #0673348 - see comment for more info
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11044
diff changeset
   531
        # constraint between two attributes). This should be the purpose of an api rework at some
df1f2d853d40 quick fix which closes #0673348 - see comment for more info
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11044
diff changeset
   532
        # point, we currently rely on the fact that such constraint will provide a dedicated user
df1f2d853d40 quick fix which closes #0673348 - see comment for more info
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11044
diff changeset
   533
        # message not relying on the `value` argument
11358
179b5ff3f428 Update to yams 0.44 API
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11129
diff changeset
   534
        value = self.entity.cw_edited.get(rschema.type)
179b5ff3f428 Update to yams 0.44 API
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11129
diff changeset
   535
        msg, args = constraint.failed_message(key, value, self.entity)
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   536
        raise ValidationError(self.entity.eid, {key: msg}, args)