web/views/urlrewrite.py
author Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
Mon, 27 Feb 2012 17:02:31 +0100
changeset 8298 2a4bc6f75e9c
parent 8238 087bb529035c
child 8632 fa044b9157d7
permissions -rw-r--r--
[twisted] move out url logic from twisted (closes #2200593) Data, fck and static file are now served by cubicweb controller by default. Some hackish url rewriting is necessary to have them selected. This is necessary because cubicweb does not selection controller on multi level path. - 'Expires' header seems to conflict with Cache-Control set by HTTPCacheManger (don't know yet why HTTPCacheManager is involved here) mod_wsgi is now usable in simple cases (e.g. still requires persisten sessions).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6962
220e32f058be [management ui] add views to manage sources similarly to users
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6961
diff changeset
     1
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5313
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5786
7c16a4e7a592 [test] fix stupd name error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    18
"""Rules based url rewriter component, to get configurable RESTful urls"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
import re
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
3856
1c9589e46b16 fix rgx_action to ensure eids given to .execute are correctly typed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3592
diff changeset
    22
from cubicweb import typed_eid
7800
ea496a3ed703 [user management] users and groups management now really lead to that (closes #1931478)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7388
diff changeset
    23
from cubicweb.uilib import domid
722
50a99184cf47 update some imports
sylvain.thenault@logilab.fr
parents: 712
diff changeset
    24
from cubicweb.appobject import AppObject
0
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
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
def rgx(pattern, flags=0):
6175
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5811
diff changeset
    28
    """this is just a convenient shortcut to add the $ sign"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
    return re.compile(pattern+'$', flags)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
712
ce49e3885453 remove autoselectors metaclass, __select__ is built during registration
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 688
diff changeset
    31
class metarewriter(type):
8238
087bb529035c [spelling] fix dictionnary -> dictionary typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7994
diff changeset
    32
    """auto-extend rules dictionary"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
    def __new__(mcs, name, bases, classdict):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
        # collect baseclass' rules
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
        rules = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
        ignore_baseclass_rules = classdict.get('ignore_baseclass_rules', False)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
        if not ignore_baseclass_rules:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
            for base in bases:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
                rules[0:0] = getattr(base, 'rules', [])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
        rules[0:0] = classdict.get('rules', [])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
        inputs = set()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
        for data in rules[:]:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
                input, output, groups = data
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
            except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
                input, output = data
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
            if input in inputs:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
                rules.remove( (input, output) )
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
                inputs.add(input)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
        classdict['rules'] = rules
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
        return super(metarewriter, mcs).__new__(mcs, name, bases, classdict)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
class URLRewriter(AppObject):
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4706
diff changeset
    56
    """Base class for URL rewriters.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4706
diff changeset
    58
    Url rewriters should have a `rules` dict that maps an input URI
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
    to something that should be used for rewriting.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
    The actual logic that defines how the rules dict is used is implemented
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4706
diff changeset
    62
    in the `rewrite` method.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
    A `priority` attribute might be used to indicate which rewriter
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
    should be tried first. The higher the priority is, the earlier the
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4706
diff changeset
    66
    rewriter will be tried.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
    __metaclass__ = metarewriter
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
    __registry__ = 'urlrewriting'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
    __abstract__ = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
    priority = 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    73
    def rewrite(self, req, uri):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
        raise NotImplementedError
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
class SimpleReqRewriter(URLRewriter):
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4706
diff changeset
    78
    """The SimpleReqRewriters uses a `rules` dict that maps input URI
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4706
diff changeset
    79
    (regexp or plain string) to a dictionary to update the request's
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4706
diff changeset
    80
    form.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    81
5301
f4219a6e62e3 [doc/book] stuff a bit the publishing process (including various docstrings)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4706
diff changeset
    82
    If the input uri is a regexp, group substitution is allowed.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2748
diff changeset
    84
    __regid__ = 'simple'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
    rules = [
2748
d2fcf19bfb34 F [registry views] add _registry startup view
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2656
diff changeset
    87
        ('/_', dict(vid='manage')),
d2fcf19bfb34 F [registry views] add _registry startup view
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2656
diff changeset
    88
        ('/_registry', dict(vid='registry')),
d2fcf19bfb34 F [registry views] add _registry startup view
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2656
diff changeset
    89
#        (rgx('/_([^/]+?)/?'), dict(vid=r'\1')),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
        ('/schema',  dict(vid='schema')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
        ('/index', dict(vid='index')),
1879
cb3466e08d81 eproperty -> cwproperty, cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1433
diff changeset
    92
        ('/myprefs', dict(vid='propertiesform')),
cb3466e08d81 eproperty -> cwproperty, cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1433
diff changeset
    93
        ('/siteconfig', dict(vid='systempropertiesform')),
6961
686c59dfc401 [manage view] cleanup manage view and user menu
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6950
diff changeset
    94
        ('/siteinfo', dict(vid='siteinfo')),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
        ('/manage', dict(vid='manage')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
        ('/notfound', dict(vid='404')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
        ('/error', dict(vid='error')),
2422
96da7dc42eb5 quick and dirty support from simple sparql queries + base ui
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    98
        ('/sparql', dict(vid='sparql')),
4706
6035e96b64dd added stats for munin collecting #615844 - from 027bbff3659f
arthur
parents: 4436
diff changeset
    99
        ('/processinfo', dict(vid='processinfo')),
7800
ea496a3ed703 [user management] users and groups management now really lead to that (closes #1931478)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7388
diff changeset
   100
        (rgx('/cwuser', re.I), dict(vid='cw.users-and-groups-management',
ea496a3ed703 [user management] users and groups management now really lead to that (closes #1931478)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7388
diff changeset
   101
                                    tab=domid('cw.users-management'))),
ea496a3ed703 [user management] users and groups management now really lead to that (closes #1931478)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7388
diff changeset
   102
        (rgx('/cwgroup', re.I), dict(vid='cw.users-and-groups-management',
ea496a3ed703 [user management] users and groups management now really lead to that (closes #1931478)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7388
diff changeset
   103
                                     tab=domid('cw.groups-management'))),
7994
af3fb709c061 [management table] upgrade sources groups management table to new api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7800
diff changeset
   104
        (rgx('/cwsource', re.I), dict(vid='cw.sources-management')),
4405
fe31bb5dada5 eschema view is gone away
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
   105
        # XXX should be case insensitive as 'create', but I would like to find another way than
fe31bb5dada5 eschema view is gone away
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
   106
        # relying on the etype_selector
fe31bb5dada5 eschema view is gone away
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
   107
        (rgx('/schema/([^/]+?)/?'),  dict(vid='primary', rql=r'Any X WHERE X is CWEType, X name "\1"')),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
        (rgx('/add/([^/]+?)/?'), dict(vid='creation', etype=r'\1')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
        (rgx('/doc/images/(.+?)/?'), dict(vid='wdocimages', fid=r'\1')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
        (rgx('/doc/?'), dict(vid='wdoc', fid=r'main')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
        (rgx('/doc/(.+?)/?'), dict(vid='wdoc', fid=r'\1')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
        (rgx('/changelog/?'), dict(vid='changelog')),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
        ]
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   114
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
    def rewrite(self, req, uri):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   116
        """for each `input`, `output `in rules, if `uri` matches `input`,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        req's form is updated with `output`
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
        for data in self.rules:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
                inputurl, infos, required_groups = data
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
            except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
                inputurl, infos = data
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
                required_groups = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
            if required_groups and not req.user.matching_groups(required_groups):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
            if isinstance(inputurl, basestring):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
                if inputurl == uri:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
                    req.form.update(infos)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
                    break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
            elif inputurl.match(uri): # it's a regexp
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
                # XXX what about i18n ? (vtitle for instance)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
                for param, value in infos.items():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
                    if isinstance(value, basestring):
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 722
diff changeset
   135
                        req.form[param] = inputurl.sub(value, uri)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
                    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
                        req.form[param] = value
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
                break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
            self.debug("no simple rewrite rule found for %s", uri)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
            raise KeyError(uri)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
        return None, None
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
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
def build_rset(rql, rgxgroups=None, cachekey=None, setuser=False,
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
               vid=None, vtitle=None, form={}, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
7388
dc319ece0bd6 [url rewriting] fix nasty bug in build_rset inner function: the same dictionary is used by all queries, hence triggering potentially important bugs on concurrent requests (this dictionary goes back and forth the repository)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6962
diff changeset
   148
    def do_build_rset(inputurl, uri, req, schema, kwargs=kwargs):
dc319ece0bd6 [url rewriting] fix nasty bug in build_rset inner function: the same dictionary is used by all queries, hence triggering potentially important bugs on concurrent requests (this dictionary goes back and forth the repository)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6962
diff changeset
   149
        kwargs = kwargs.copy()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
        if rgxgroups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
            match = inputurl.match(uri)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
            for arg, group in rgxgroups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
                kwargs[arg] = match.group(group)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
        req.form.update(form)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   155
        if setuser:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
            kwargs['u'] = req.user.eid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
        if vid:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
            req.form['vid'] = vid
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
        if vtitle:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
            req.form['vtitle'] = req._(vtitle) % kwargs
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
        return None, req.execute(rql, kwargs, cachekey)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
    return do_build_rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
def update_form(**kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
    def do_build_rset(inputurl, uri, req, schema):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
        match = inputurl.match(uri)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
        kwargs.update(match.groupdict())
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
        req.form.update(kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
        return None, None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
    return do_build_rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
def rgx_action(rql=None, args=None, cachekey=None, argsgroups=(), setuser=False,
6393
7372100062e8 include fcayre's patch #1060507 to get extra rql query parameters from form content in rgx_action
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6175
diff changeset
   173
               form=None, formgroups=(), transforms={}, rqlformparams=(), controller=None):
3865
f9778a00e47f actually fix rgx_action
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3864
diff changeset
   174
    def do_build_rset(inputurl, uri, req, schema,
f9778a00e47f actually fix rgx_action
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3864
diff changeset
   175
                      cachekey=cachekey # necessary to avoid UnboundLocalError
f9778a00e47f actually fix rgx_action
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3864
diff changeset
   176
                      ):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
        if rql:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
            kwargs = args and args.copy() or {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
            if argsgroups:
3856
1c9589e46b16 fix rgx_action to ensure eids given to .execute are correctly typed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3592
diff changeset
   180
                if cachekey is not None and isinstance(cachekey, basestring):
1c9589e46b16 fix rgx_action to ensure eids given to .execute are correctly typed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3592
diff changeset
   181
                    cachekey = (cachekey,)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
                match = inputurl.match(uri)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
                for key in argsgroups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
                    value = match.group(key)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
                    try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
                        kwargs[key] = transforms[key](value)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
                    except KeyError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
                        kwargs[key] = value
3865
f9778a00e47f actually fix rgx_action
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3864
diff changeset
   189
                    if cachekey is not None and key in cachekey:
3856
1c9589e46b16 fix rgx_action to ensure eids given to .execute are correctly typed
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3592
diff changeset
   190
                        kwargs[key] = typed_eid(value)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
            if setuser:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
                kwargs['u'] = req.user.eid
6393
7372100062e8 include fcayre's patch #1060507 to get extra rql query parameters from form content in rgx_action
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6175
diff changeset
   193
            for param in rqlformparams:
7372100062e8 include fcayre's patch #1060507 to get extra rql query parameters from form content in rgx_action
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6175
diff changeset
   194
                kwargs.setdefault(param, req.form.get(param))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
            rset = req.execute(rql, kwargs, cachekey)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
            rset = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
        form2 = form and form.copy() or {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        if formgroups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
            match = inputurl.match(uri)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
            for key in formgroups:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
                form2[key] = match.group(key)
3537
73b5bec579ba [B] urlrewite: basic patch for i18n vtitle
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 2748
diff changeset
   203
        if "vtitle" in form2:
3592
4c08780e54ed [i18n] msgid tweaks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3537
diff changeset
   204
            form2['vtitle'] = req.__(form2['vtitle'])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
        if form2:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
            req.form.update(form2)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
        return controller, rset
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
    return do_build_rset
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
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
class SchemaBasedRewriter(URLRewriter):
5313
c4fe397379c7 [doc/book] complete the urlrewrite sections with examples
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5301
diff changeset
   212
    """Here, the rules dict maps regexps or plain strings to callbacks
c4fe397379c7 [doc/book] complete the urlrewrite sections with examples
Stephanie Marcu <stephanie.marcu@logilab.fr>
parents: 5301
diff changeset
   213
    that will be called with inputurl, uri, req, schema as parameters.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
    """
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2748
diff changeset
   215
    __regid__ = 'schemabased'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
    rules = [
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
        # rgxp : callback
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: 5424
diff changeset
   218
        (rgx('/search/(.+)'), build_rset(rql=r'Any X ORDERBY FTIRANK(X) DESC WHERE X has_text %(text)s',
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   219
                                         rgxgroups=[('text', 1)])),
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
        ]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
    def rewrite(self, req, uri):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
        # XXX this could be refacted with SimpleReqRewriter
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
        for data in self.rules:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
            try:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
                inputurl, callback, required_groups = data
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
            except ValueError:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
                inputurl, callback = data
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
                required_groups = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
            if required_groups and not req.user.matching_groups(required_groups):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
                continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
            if isinstance(inputurl, basestring):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
                if inputurl == uri:
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3890
diff changeset
   234
                    return callback(inputurl, uri, req, self._cw.vreg.schema)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
            elif inputurl.match(uri): # it's a regexp
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3890
diff changeset
   236
                return callback(inputurl, uri, req, self._cw.vreg.schema)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
            self.debug("no schemabased rewrite rule found for %s", uri)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
            raise KeyError(uri)