cubicweb/pyramid/resources.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Fri, 17 Mar 2017 16:29:38 +0100
branch3.25
changeset 12074 f5fee548588d
parent 11967 83739be20fab
child 12567 26744ad37953
permissions -rw-r--r--
[pkg] Version 3.25.0rc0 Let's make a release candidate version of CubicWeb 3.25.0 (only for the Python package), in the hope that some issues that we usually discover after release will be sorted out before.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11967
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
     1
# copyright 2017 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
     2
# copyright 2014-2016 UNLISH S.A.S. (Montpellier, FRANCE), all rights reserved.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
     3
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
     4
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
     5
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
     6
# This file is part of CubicWeb.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
     7
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
     8
# CubicWeb is free software: you can redistribute it and/or modify it under the
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
     9
# terms of the GNU Lesser General Public License as published by the Free
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    10
# Software Foundation, either version 2.1 of the License, or (at your option)
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    11
# any later version.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    12
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    13
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    14
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    15
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    16
# details.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    17
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    18
# You should have received a copy of the GNU Lesser General Public License along
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    19
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    20
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    21
"""Pyramid resource definitions for CubicWeb."""
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11820
diff changeset
    22
11630
1400aee10df4 Port to Python3 (closes #14159555)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11599
diff changeset
    23
from six import text_type
11599
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    24
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    25
from rql import TypeResolverException
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    26
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    27
from pyramid.decorator import reify
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    28
from pyramid.httpexceptions import HTTPNotFound
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    29
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    30
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    31
class EntityResource(object):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    32
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    33
    """A resource class for an entity. It provide method to retrieve an entity
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    34
    by eid.
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    35
    """
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    36
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    37
    @classmethod
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    38
    def from_eid(cls):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    39
        def factory(request):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    40
            return cls(request, None, None, request.matchdict['eid'])
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    41
        return factory
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    42
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    43
    def __init__(self, request, cls, attrname, value):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    44
        self.request = request
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    45
        self.cls = cls
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    46
        self.attrname = attrname
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    47
        self.value = value
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    48
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    49
    @reify
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    50
    def rset(self):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    51
        req = self.request.cw_request
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    52
        if self.cls is None:
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    53
            return req.execute('Any X WHERE X eid %(x)s',
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    54
                               {'x': int(self.value)})
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    55
        st = self.cls.fetch_rqlst(self.request.cw_cnx.user, ordermethod=None)
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    56
        st.add_constant_restriction(st.get_variable('X'), self.attrname,
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    57
                                    'x', 'Substitute')
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    58
        if self.attrname == 'eid':
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    59
            try:
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    60
                rset = req.execute(st.as_string(), {'x': int(self.value)})
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    61
            except (ValueError, TypeResolverException):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    62
                # conflicting eid/type
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    63
                raise HTTPNotFound()
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    64
        else:
11630
1400aee10df4 Port to Python3 (closes #14159555)
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11599
diff changeset
    65
            rset = req.execute(st.as_string(), {'x': text_type(self.value)})
11599
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    66
        return rset
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    67
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    68
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    69
class ETypeResource(object):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    70
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    71
    """A resource for etype.
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    72
    """
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    73
    @classmethod
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    74
    def from_match(cls, matchname):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    75
        def factory(request):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    76
            return cls(request, request.matchdict[matchname])
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    77
        return factory
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    78
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    79
    def __init__(self, request, etype):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    80
        vreg = request.registry['cubicweb.registry']
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    81
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    82
        self.request = request
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    83
        self.etype = vreg.case_insensitive_etypes[etype.lower()]
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    84
        self.cls = vreg['etypes'].etype_class(self.etype)
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    85
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    86
    def __getitem__(self, value):
11820
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    87
        # Try eid first, then rest attribute as for URL path evaluation
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    88
        # mecanism in cubicweb.web.views.urlpublishing.
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    89
        for attrname in ('eid', self.cls.cw_rest_attr_info()[0]):
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    90
            resource = EntityResource(self.request, self.cls, attrname, value)
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    91
            try:
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    92
                rset = resource.rset
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    93
            except HTTPNotFound:
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    94
                continue
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    95
            if rset.rowcount:
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    96
                return resource
ec612abc2e2e [pyramid] Try "eid" first when retrieving a subresource of ETypeResource
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11631
diff changeset
    97
        raise KeyError(value)
11599
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    98
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
    99
    @reify
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
   100
    def rset(self):
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
   101
        rql = self.cls.fetch_rql(self.request.cw_cnx.user)
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
   102
        rset = self.request.cw_request.execute(rql)
f8ba6ea94af9 [refactoring] Move EntityResource and ETypeResource to a separate module
Rabah Meradi <rabah.meradi@logilab.fr>
parents:
diff changeset
   103
        return rset