entities/adapters.py
author Rémi Cardona <remi.cardona@logilab.fr>
Mon, 12 Oct 2015 21:06:45 +0200
changeset 10733 9f66ac5eec1e
parent 10732 6231587fcfc5
child 10973 0939ad2edf63
permissions -rw-r--r--
[py3k] http headers should be ascii-only unicode objects
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)