web/views/urlpublishing.py
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Thu, 15 Apr 2010 19:31:10 +0200
branchstable
changeset 5301 f4219a6e62e3
parent 4252 6c4f109c2b03
child 5302 dfd147de06b2
child 5421 8167de96c523
permissions -rw-r--r--
[doc/book] stuff a bit the publishing process (including various docstrings)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
     1
# organization: Logilab
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
     2
# copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
     3
# contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
     4
# license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
     5
"""Associate url's path to view identifier / rql queries.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     6
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
     7
It currently handles url path with the forms:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
* <publishing_method>
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    10
* minimal REST publishing:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    12
  * <eid>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
  * <etype>[/<attribute name>/<attribute value>]*
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
* folder navigation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    16
You can actually control URL (more exactly path) resolution using an
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    17
URL path evaluator.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    19
.. note::
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    20
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    21
 Actionpath and Folderpath execute a query whose results is lost
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    22
 because of redirecting instead of direct traversal.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
from rql import TypeResolverException
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
from cubicweb import RegistryException, typed_eid
2887
1282dc6525c5 give vreg where we need it (eg no bound request)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
    29
from cubicweb.web import NotFound, Redirect, component
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
class PathDontMatch(Exception):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
    """exception used by url evaluators to notify they can't evaluate
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
    a path
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
    """
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
    36
2887
1282dc6525c5 give vreg where we need it (eg no bound request)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
    37
class URLPublisherComponent(component.Component):
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    38
    """Associate url path to view identifier / rql queries, by
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    39
    applying a chain of urlpathevaluator components.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    41
    An evaluator is a URLPathEvaluator subclass with an .evaluate_path
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
    method taking the request object and the path to publish as
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    43
    argument.  It will either return a publishing method identifier
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    44
    and an rql query on success or raise a `PathDontMatch` exception
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    45
    on failure. URL evaluators are called according to their
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    46
    `priority` attribute, with 0 as the greatest priority and greater
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    47
    values as lower priority. The first evaluator returning a result
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    48
    or raising something else than `PathDontMatch` will stop the
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    49
    handlers chain.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2890
diff changeset
    51
    __regid__ = 'urlpublisher'
2887
1282dc6525c5 give vreg where we need it (eg no bound request)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
    52
    vreg = None # XXX necessary until property for deprecation warning is on appobject
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
    53
2887
1282dc6525c5 give vreg where we need it (eg no bound request)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
    54
    def __init__(self, vreg, default_method='view'):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
        super(URLPublisherComponent, self).__init__()
2887
1282dc6525c5 give vreg where we need it (eg no bound request)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
    56
        self.vreg = vreg
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
        self.default_method = default_method
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
    58
        evaluators = []
2887
1282dc6525c5 give vreg where we need it (eg no bound request)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
    59
        for evaluatorcls in vreg['components']['urlpathevaluator']:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
            # instantiation needed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
            evaluator = evaluatorcls(self)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
            evaluators.append(evaluator)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        self.evaluators = sorted(evaluators, key=lambda x: x.priority)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
    64
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
    def process(self, req, path):
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    66
        """Given an url (essentialy caracterized by a path on the
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    67
        server, but additional information may be found in the request
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    68
        object), return a publishing method identifier
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    69
        (e.g. controller) and an optional result set.
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
    70
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    71
        :type req: `cubicweb.web.request.CubicWebRequestBase`
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
        :param req: the request object
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
    73
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        :type path: str
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        :param path: the path of the resource to publish
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4252
diff changeset
    77
        :rtype: tuple(str, `cubicweb.rset.ResultSet` or None)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
        :return: the publishing method identifier and an optional result set
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
    79
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
        :raise NotFound: if no handler is able to decode the given path
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
        parts = [part for part in path.split('/')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
                 if part != ''] or (self.default_method,)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
        if req.form.get('rql'):
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
    85
            if parts[0] in self.vreg['controllers']:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
                return parts[0], None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
            return 'view', None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
        for evaluator in self.evaluators:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
                pmid, rset = evaluator.evaluate_path(req, parts[:])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
                break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
            except PathDontMatch:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
            raise NotFound(path)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
        if pmid is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
            pmid = self.default_method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
        return pmid, rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
   100
2887
1282dc6525c5 give vreg where we need it (eg no bound request)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
   101
class URLPathEvaluator(component.Component):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
    __abstract__ = True
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2890
diff changeset
   103
    __regid__ = 'urlpathevaluator'
2887
1282dc6525c5 give vreg where we need it (eg no bound request)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
   104
    vreg = None # XXX necessary until property for deprecation warning is on appobject
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
    def __init__(self, urlpublisher):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
        self.urlpublisher = urlpublisher
2887
1282dc6525c5 give vreg where we need it (eg no bound request)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2770
diff changeset
   108
        self.vreg = urlpublisher.vreg
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
class RawPathEvaluator(URLPathEvaluator):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
    """handle path of the form::
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
        <publishing_method>?parameters...
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
    priority = 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
    def evaluate_path(self, req, parts):
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
   117
        if len(parts) == 1 and parts[0] in self.vreg['controllers']:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
            return parts[0], None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
        raise PathDontMatch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
class EidPathEvaluator(URLPathEvaluator):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
    """handle path with the form::
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
        <eid>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
    priority = 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
    def evaluate_path(self, req, parts):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
        if len(parts) != 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
            raise PathDontMatch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
        try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
            rset = req.execute('Any X WHERE X eid %(x)s',
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
                               {'x': typed_eid(parts[0])}, 'x')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
        except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
            raise PathDontMatch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
        if rset.rowcount == 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
            raise NotFound()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
        return None, rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
   140
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
class RestPathEvaluator(URLPathEvaluator):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
    """handle path with the form::
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
        <etype>[[/<attribute name>]/<attribute value>]*
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
    priority = 2
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
   147
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
    def evaluate_path(self, req, parts):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
        if not (0 < len(parts) < 4):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
            raise PathDontMatch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
        try:
2273
daf6e178659f new case_insensitive_etypes resource on the cubicweb registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   152
            etype = self.vreg.case_insensitive_etypes[parts.pop(0).lower()]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
        except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
            raise PathDontMatch()
2664
1578e1a57828 [we, test] more api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2657
diff changeset
   155
        cls = self.vreg['etypes'].etype_class(etype)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
        if parts:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
            if len(parts) == 2:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
                attrname = parts.pop(0).lower()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
                try:
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2664
diff changeset
   160
                    cls.e_schema.subjrels[attrname]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
                except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
                    raise PathDontMatch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
                attrname = cls._rest_attr_info()[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
            value = req.url_unquote(parts.pop(0))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
            rset = self.attr_rset(req, etype, attrname, value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
            rset = self.cls_rset(req, cls)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
        if rset.rowcount == 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
            raise NotFound()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
        return None, rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
    def cls_rset(self, req, cls):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
        return req.execute(cls.fetch_rql(req.user))
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
   175
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
    def attr_rset(self, req, etype, attrname, value):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
        rql = u'Any X WHERE X is %s, X %s %%(x)s' % (etype, attrname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
        if attrname == 'eid':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
                rset = req.execute(rql, {'x': typed_eid(value)}, 'x')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
            except (ValueError, TypeResolverException):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
                # conflicting eid/type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
                raise PathDontMatch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
            rset = req.execute(rql, {'x': value})
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
        return rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
class URLRewriteEvaluator(URLPathEvaluator):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
    """tries to find a rewrite rule to apply
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
    URL rewrite rule definitions are stored in URLRewriter objects
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
    priority = 3
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
    def evaluate_path(self, req, parts):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
        # uri <=> req._twreq.path or req._twreq.uri
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
        uri = req.url_unquote('/' + '/'.join(parts))
2657
de974465d381 [appobject] kill VObject class, move base selector classes to appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   198
        evaluators = sorted(self.vreg['urlrewriting'].all_objects(),
de974465d381 [appobject] kill VObject class, move base selector classes to appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   199
                            key=lambda x: x.priority, reverse=True)
de974465d381 [appobject] kill VObject class, move base selector classes to appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
   200
        for rewritercls in evaluators:
2890
fdcb8a2bb6eb fix __init__ parameters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2887
diff changeset
   201
            rewriter = rewritercls(req)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
                # XXX we might want to chain url rewrites
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
                return rewriter.rewrite(req, uri)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
            except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
        raise PathDontMatch()
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 661
diff changeset
   208
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
class ActionPathEvaluator(URLPathEvaluator):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
    """handle path with the form::
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
    <any evaluator path>/<action>
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
    priority = 4
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
    def evaluate_path(self, req, parts):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
        if len(parts) < 2:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
            raise PathDontMatch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
        # remove last part and see if this is something like an actions
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        # if so, call
2770
356e9d7c356d R propagate registry API changes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2664
diff changeset
   221
        # XXX bad smell: refactor to simpler code
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
        try:
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
   223
            actionsreg = self.vreg['actions']
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
            requested = parts.pop(-1)
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
   225
            actions = actionsreg[requested]
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
        except RegistryException:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
            raise PathDontMatch()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
        for evaluator in self.urlpublisher.evaluators:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
            if evaluator is self or evaluator.priority == 0:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
                pmid, rset = evaluator.evaluate_path(req, parts[:])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
            except PathDontMatch:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   236
                try:
2770
356e9d7c356d R propagate registry API changes
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2664
diff changeset
   237
                    action = actionsreg._select_best(actions, req, rset=rset)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
                except RegistryException:
2650
18aec79ec3a3 R [vreg] important refactoring of the vregistry, moving behaviour to end dictionnary (and so leaving room for more flexibility ; keep bw compat ; update api usage in cw
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2293
diff changeset
   239
                    continue
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
                else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
                    # XXX avoid redirect
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
                    raise Redirect(action.url())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
        raise PathDontMatch()