entities/adapters.py
author Rémi Cardona <remi.cardona@logilab.fr>, Julien Cristau <julien.cristau@logilab.fr>
Thu, 26 Nov 2015 11:30:54 +0100
changeset 10935 049209b9e9d6
parent 10732 6231587fcfc5
child 10973 0939ad2edf63
permissions -rw-r--r--
[qunit] stop dealing with filesystem paths qunit tests need a few things served by cubicweb: - qunit itself, which is now handled by CWDevtoolsStaticController (serving files in cubicweb/devtools/data) - standard cubicweb or cubes data files, handled by the DataController - the tests themselves and their dependencies. These can live in <apphome>/data or <apphome>/static and be served by one of the STATIC_CONTROLLERS This avoids having to guess in CWSoftwareRootStaticController where to serve things from (some files may be installed, others are in the source tree), and should hopefully make it possible to have these tests pass when using tox, and to write qunit tests for cubes, outside of cubicweb itself. This requires modifying the tests to only declare URL paths instead of filesystem paths, and moving support files below test/data/static.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9375
8e88576787c3 [schema] fix unique together index handling
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9256
diff changeset
     1
# copyright 2010-2013 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
"""
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    21
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
__docformat__ = "restructuredtext en"
10666
7f6b5f023884 [py3k] replace '_ = unicode' in global scope (closes #7589459)
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    23
from cubicweb import _
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    24
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
    25
from itertools import chain
5720
f0e521487903 [ITree] more fixes, fix fixes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5718
diff changeset
    26
from warnings import warn
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
    27
from hashlib import md5
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
    28
5694
ce2c108a9595 [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5574
diff changeset
    29
from logilab.mtconverter import TransformError
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
    30
from logilab.common.decorators import cached
5694
ce2c108a9595 [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5574
diff changeset
    31
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
    32
from cubicweb import ValidationError, view, ViolatedConstraint
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
    33
from cubicweb.schema import CONSTRAINTS
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
    34
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
    35
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    36
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
    37
class IEmailableAdapter(view.EntityAdapter):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    38
    __regid__ = 'IEmailable'
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    39
    __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
    40
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    41
    def get_email(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    42
        if getattr(self.entity, 'primary_email', None):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    43
            return self.entity.primary_email[0].address
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    44
        if getattr(self.entity, 'use_email', None):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    45
            return self.entity.use_email[0].address
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    46
        return None
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    47
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    48
    def allowed_massmail_keys(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    49
        """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
    50
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    51
        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
    52
        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
    53
        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
    54
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    55
        return set(rschema.type
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    56
                   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
    57
                   if attrtype.type not in ('Password', 'Bytes'))
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    58
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    59
    def as_email_context(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    60
        """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
    61
        build email bodies.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    63
        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
    64
        `allowed_massmail_keys` method.
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    65
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    66
        return dict( (attr, getattr(self.entity, attr))
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    67
                     for attr in self.allowed_massmail_keys() )
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    68
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    69
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
    70
class INotifiableAdapter(view.EntityAdapter):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    71
    __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
    72
    __select__ = is_instance('Any')
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    73
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    74
    def notification_references(self, view):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    75
        """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
    76
        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
    77
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    78
        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
    79
        identifiers of previously sent email(s)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    80
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    81
        itree = self.entity.cw_adapt_to('ITree')
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    82
        if itree is not None:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    83
            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
    84
        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
    85
            return (self.entity.eid,)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    86
        return ()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    87
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    88
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
    89
class IFTIndexableAdapter(view.EntityAdapter):
8518
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
    90
    """standard adapter to handle fulltext indexing
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
    91
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
    92
    .. automethod:: cubicweb.entities.adapters.IFTIndexableAdapter.fti_containers
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
    93
    .. automethod:: cubicweb.entities.adapters.IFTIndexableAdapter.get_words
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
    94
    """
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    95
    __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
    96
    __select__ = is_instance('Any')
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    97
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    98
    def fti_containers(self, _done=None):
8518
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
    99
        """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
   100
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   101
        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
   102
        in the datamodel definition
153a7c9cdca9 [fti] add some documentation
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 8190
diff changeset
   103
        """
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   104
        if _done is None:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   105
            _done = set()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   106
        entity = self.entity
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
        _done.add(entity.eid)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   108
        containers = tuple(entity.e_schema.fulltext_containers())
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   109
        if containers:
9433
dd708175dc43 [adapters] fix a name stomping error (entity)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   110
            for rschema, role in containers:
dd708175dc43 [adapters] fix a name stomping error (entity)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   111
                if role == 'object':
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   112
                    targets = getattr(entity, rschema.type)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   113
                else:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   114
                    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
   115
                for target in targets:
dd708175dc43 [adapters] fix a name stomping error (entity)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   116
                    if target.eid in _done:
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   117
                        continue
9433
dd708175dc43 [adapters] fix a name stomping error (entity)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   118
                    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
   119
                        yield container
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   120
        else:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   121
            yield entity
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   122
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
   123
    # 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
   124
    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
   125
    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
   126
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   127
    def get_words(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   128
        """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
   129
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   130
        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
   131
        on the logilab.database package
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   132
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   133
        :rtype: list
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   134
        :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
   135
        """
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   136
        from logilab.database.fti import tokenize
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   137
        # 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
   138
        entity = self.entity
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   139
        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
   140
        words = {}
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   141
        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
   142
            if (entity.e_schema, rschema) in pending:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   143
                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
   144
            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
   145
            try:
10473
23a2fa8cb725 avoid sanitizing warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 10446
diff changeset
   146
                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
   147
            except TransformError:
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
                continue
7815
2a164a9cf81c [exceptions] stop catching any exception in various places (closes #1942716)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6974
diff changeset
   149
            except Exception:
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   150
                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
   151
                               rschema, entity.eid)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   152
                continue
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   153
            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
   154
                words.setdefault(weight, []).extend(tokenize(value))
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   155
        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
   156
            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
   157
                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
   158
                    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
   159
            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
   160
                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
   161
                    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
   162
        return words
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
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
   164
def merge_weight_dict(maindict, newdict):
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10473
diff changeset
   165
    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
   166
        maindict.setdefault(weight, []).extend(words)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   167
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   168
class IDownloadableAdapter(view.EntityAdapter):
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   169
    """interface for downloadable entities"""
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   170
    __regid__ = 'IDownloadable'
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   171
    __abstract__ = True
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   172
5981
3472c051da77 [idownloadable] fix download_url prototype: should accept arbitrary kwargs to add as form parameters to the generated url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5895
diff changeset
   173
    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
   174
        """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
   175
6231587fcfc5 [py3k] Clarify IDownloadable expected types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10731
diff changeset
   176
        It should be a unicode object containing url-encoded ASCII."""
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   177
        raise NotImplementedError
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   178
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   179
    def download_content_type(self):
10732
6231587fcfc5 [py3k] Clarify IDownloadable expected types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10731
diff changeset
   180
        """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
   181
        raise NotImplementedError
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   182
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   183
    def download_encoding(self):
10732
6231587fcfc5 [py3k] Clarify IDownloadable expected types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10731
diff changeset
   184
        """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
   185
        raise NotImplementedError
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   186
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   187
    def download_file_name(self):
10732
6231587fcfc5 [py3k] Clarify IDownloadable expected types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10731
diff changeset
   188
        """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
   189
        raise NotImplementedError
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   190
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   191
    def download_data(self):
10731
0736e31f8644 [py3k] IDownloadable.download_data() returns bytes
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10671
diff changeset
   192
        """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
   193
        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
   194
6974
6f23b2baf99b add a note
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6864
diff changeset
   195
# XXX should propose to use two different relations for children/parent
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   196
class ITreeAdapter(view.EntityAdapter):
9705
1d40d3b10142 Drop duplicated content in ITreeAdapter docstring
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9700
diff changeset
   197
    """This adapter provides a tree interface.
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   198
9705
1d40d3b10142 Drop duplicated content in ITreeAdapter docstring
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 9700
diff changeset
   199
    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
   200
    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
   201
    implementation.
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   202
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   203
    This class provides the following methods:
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   204
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   205
    .. automethod: iterparents
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   206
    .. automethod: iterchildren
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   207
    .. automethod: prefixiter
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   208
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   209
    .. automethod: is_leaf
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   210
    .. automethod: is_root
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   211
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   212
    .. automethod: root
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   213
    .. automethod: parent
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   214
    .. automethod: children
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   215
    .. automethod: different_type_children
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   216
    .. automethod: same_type_children
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   217
    .. automethod: children_rql
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   218
    .. 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
   219
    """
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
   220
    __regid__ = 'ITree'
9256
697a8181ba30 remove 3.9 bw compat
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9130
diff changeset
   221
    __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
   222
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
   223
    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
   224
    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
   225
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
   226
    def children_rql(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   227
        """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
   228
        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
   229
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
   230
    def different_type_children(self, entities=True):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   231
        """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
   232
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   233
        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
   234
        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
   235
        """
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
   236
        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
   237
                                  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
   238
        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
   239
        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
   240
            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
   241
        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
   242
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
   243
    def same_type_children(self, entities=True):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   244
        """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
   245
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   246
        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
   247
        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
   248
        """
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
   249
        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
   250
                                  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
   251
        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
   252
        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
   253
            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
   254
        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
   255
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
   256
    def is_leaf(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   257
        """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
   258
        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
   259
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
   260
    def is_root(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   261
        """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
   262
        """
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
   263
        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
   264
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
   265
    def root(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   266
        """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
   267
        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
   268
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
   269
    def parent(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   270
        """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
   271
        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
   272
        """
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
   273
        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
   274
            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
   275
                                       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
   276
        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
   277
            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
   278
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
   279
    def children(self, entities=True, sametype=False):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   280
        """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
   281
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   282
        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
   283
        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
   284
        """
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
   285
        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
   286
            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
   287
        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
   288
            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
   289
                                       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
   290
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
   291
    def iterparents(self, strict=True):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   292
        """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
   293
        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
   294
            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
   295
            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
   296
                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
   297
                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
   298
                    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
   299
                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
   300
                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
   301
        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
   302
            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
   303
        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
   304
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
   305
    def iterchildren(self, _done=None):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   306
        """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
   307
        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
   308
            _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
   309
        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
   310
            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
   311
                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
   312
                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
   313
            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
   314
            _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
   315
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
   316
    def prefixiter(self, _done=None):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   317
        """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
   318
        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
   319
            _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
   320
        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
   321
            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
   322
        _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
   323
        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
   324
        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
   325
            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
   326
                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
   327
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
   328
    @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
   329
    def path(self):
6155
16fad8d00787 [doc] clean ITreeAdapter documentation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6011
diff changeset
   330
        """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
   331
        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
   332
        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
   333
        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
   334
        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
   335
            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
   336
                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
   337
                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
   338
            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
   339
            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
   340
                # check we are not jumping to another tree
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
   341
                if (adapter.tree_relation != self.tree_relation or
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
                    adapter.child_role != 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
   343
                    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
   344
                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
   345
                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
   346
            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
   347
                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
   348
        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
   349
        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
   350
5722
61d6a4caa963 [iprogress] move adapter to entities.adapters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5720
diff changeset
   351
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   352
# error handling adapters ######################################################
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   353
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   354
from cubicweb import UniqueTogetherError
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   355
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   356
class IUserFriendlyError(view.EntityAdapter):
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   357
    __regid__ = 'IUserFriendlyError'
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   358
    __abstract__ = True
9130
0f1504a9fb51 [constraint] more robust unicity constraint failures reporting for end-users
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8930
diff changeset
   359
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   360
    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
   361
        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
   362
        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
   363
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   364
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   365
class IUserFriendlyUniqueTogether(IUserFriendlyError):
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   366
    __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
   367
8037
a36bd56f33bb [diet] move iprogress to its own cube. Closes #1916016
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
   368
    def raise_user_exception(self):
9375
8e88576787c3 [schema] fix unique together index handling
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9256
diff changeset
   369
        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
   370
        errors = {}
2cdab5e33542 [i18n] properly translate error messages related to violated unicity constraint.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9918
diff changeset
   371
        msgargs = {}
2cdab5e33542 [i18n] properly translate error messages related to violated unicity constraint.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9918
diff changeset
   372
        i18nvalues = []
9130
0f1504a9fb51 [constraint] more robust unicity constraint failures reporting for end-users
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8930
diff changeset
   373
        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
   374
            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
   375
            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
   376
            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
   377
        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
   378
        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
   379
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   380
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   381
class IUserFriendlyCheckConstraint(IUserFriendlyError):
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   382
    __select__ = match_exception(ViolatedConstraint)
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   383
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   384
    def raise_user_exception(self):
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   385
        _ = self._cw._
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   386
        cstrname = self.exc.cstrname
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   387
        eschema = self.entity.e_schema
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   388
        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
   389
            rdef = rschema.rdef(eschema, attrschema)
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   390
            for constraint in rdef.constraints:
10671
e08102f45237 [py3k] bytes required for hashlib.{md5,sha1}()
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10666
diff changeset
   391
                if cstrname == 'cstr' + md5((eschema.type + rschema.type + constraint.type() + (constraint.serialize() or '')).encode('ascii')).hexdigest():
10446
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   392
                    break
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   393
            else:
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   394
                continue
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   395
            break
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   396
        else:
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   397
            assert 0
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   398
        key = rschema.type + '-subject'
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   399
        msg, args = constraint.failed_message(key, self.entity.cw_edited[rschema.type])
1e6655cff5ab add IUserFriendlyError adapter for violation of check constraints
Julien Cristau <julien.cristau@logilab.fr>
parents: 10301
diff changeset
   400
        raise ValidationError(self.entity.eid, {key: msg}, args)