web/controller.py
author Rémi Cardona <remi.cardona@logilab.fr>
Mon, 21 Sep 2015 17:54:15 +0200
changeset 10721 e9abbaa835f5
parent 10698 bee7de3b4e55
child 10907 9ae707db5265
permissions -rw-r--r--
[tests] Port unittest_cwctl to py3k On python 2, sys.stdout takes bytes-like objects whereas python 3's takes unicode-like objects and handles the encoding on its own.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9229
739ae5366bed [web] stop using deprecated StatusResponse. Closes #3098215
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8697
diff changeset
     1
# copyright 2003-2013 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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
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: 5040
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5886
00a78298d30d cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    18
"""abstract controller classe for CubicWeb web client"""
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
__docformat__ = "restructuredtext en"
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
10698
bee7de3b4e55 [web/controller] req.form is supposed to contain unicode-data
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
    22
from six import PY2
bee7de3b4e55 [web/controller] req.form is supposed to contain unicode-data
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
    23
4897
e402e0b32075 [web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4884
diff changeset
    24
from logilab.mtconverter import xml_escape
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7879
diff changeset
    25
from logilab.common.registry import yes
9229
739ae5366bed [web] stop using deprecated StatusResponse. Closes #3098215
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8697
diff changeset
    26
from logilab.common.deprecation import deprecated
4897
e402e0b32075 [web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4884
diff changeset
    27
722
50a99184cf47 update some imports
sylvain.thenault@logilab.fr
parents: 692
diff changeset
    28
from cubicweb.appobject import AppObject
5694
ce2c108a9595 [pylint] fix detected name errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
    29
from cubicweb.mail import format_mail
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
from cubicweb.web import LOGGER, Redirect, RequestError
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
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
NAVIGATION_PARAMETERS = (('vid', '__redirectvid'),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
                         ('rql', '__redirectrql'),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
                         ('__redirectpath', '__redirectpath'),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
                         ('__redirectparams', '__redirectparams'),
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
                         )
1103
f719caf263de NAV_FORM_PARAMETERS should be a tuple
sylvain.thenault@logilab.fr
parents: 1092
diff changeset
    38
NAV_FORM_PARAMETERS = tuple(fp for ap, fp in NAVIGATION_PARAMETERS)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
def redirect_params(form):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
    """transform redirection parameters into navigation parameters
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
    params = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
    # extract navigation parameters from redirection parameters
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
    for navparam, redirectparam in NAVIGATION_PARAMETERS:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
        if navparam == redirectparam:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
            continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
        if redirectparam in form:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
            params[navparam] = form[redirectparam]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
    return params
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
def append_url_params(url, params):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
    """append raw parameters to the url. Given parameters, if any, are expected
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
    to be already url-quoted.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
    if params:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
        if not '?' in url:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
            url += '?'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    60
            url += '&'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        url += params
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
    return url
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
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
class Controller(AppObject):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
    """a controller is responsible to make necessary stuff to publish
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
    a request. There is usually at least one standard "view" controller
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
    and another linked by forms to edit objects ("edit").
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
    __registry__ = 'controllers'
742
99115e029dca replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 722
diff changeset
    71
    __select__ = yes()
0
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 __init__(self, *args, **kwargs):
2663
2bb628e0cc3b [controller] should catch and set appli argument here now that the old AppObject class is gone
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2650
diff changeset
    74
        self.appli = kwargs.pop('appli', None)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        super(Controller, self).__init__(*args, **kwargs)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
        # attributes use to control after edition redirection
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    77
        self._after_deletion_path = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
        self._edited_entity = None
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
    79
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
    def publish(self, rset=None):
4741
f9a176ebe090 [book/controllers] add some content (overview, api super sketch) for the cubicweb controllers
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4719
diff changeset
    81
        """publish the current request, with an optional input rset"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
        raise NotImplementedError
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
4741
f9a176ebe090 [book/controllers] add some content (overview, api super sketch) for the cubicweb controllers
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4719
diff changeset
    84
    # generic methods useful for concrete implementations ######################
1092
b8fbb95dc0eb process_rql now done in the controller
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
    85
5715
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    86
    def process_rql(self):
1092
b8fbb95dc0eb process_rql now done in the controller
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
    87
        """execute rql if specified"""
5715
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    88
        req = self._cw
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    89
        rql = req.form.get('rql')
1092
b8fbb95dc0eb process_rql now done in the controller
sylvain.thenault@logilab.fr
parents: 1016
diff changeset
    90
        if rql:
5715
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    91
            req.ensure_ro_rql(rql)
10698
bee7de3b4e55 [web/controller] req.form is supposed to contain unicode-data
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10663
diff changeset
    92
            if PY2 and not isinstance(rql, unicode):
5715
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    93
                rql = unicode(rql, req.encoding)
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    94
            pp = req.vreg['components'].select_or_none('magicsearch', req)
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2001
diff changeset
    95
            if pp is not None:
5715
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    96
                return pp.process_query(rql)
6542
f13c47ac9137 [ui controller] closes #1333236: configuring boxes crashes with traceback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5890
diff changeset
    97
        if 'eid' in req.form and not isinstance(req.form['eid'], list):
5715
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    98
            return req.eid_rset(req.form['eid'])
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5694
diff changeset
    99
        return None
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   100
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
    def notify_edited(self, entity):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
        """called by edit_entity() to notify which entity is edited"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
        # NOTE: we can't use entity.rest_path() at this point because
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
        #       rest_path() could rely on schema constraints (such as a required
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
        #       relation) that might not be satisfied yet (in case of creations)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
        if not self._edited_entity:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
            self._edited_entity = entity
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   108
9229
739ae5366bed [web] stop using deprecated StatusResponse. Closes #3098215
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8697
diff changeset
   109
    @deprecated('[3.18] call view.set_http_cache_headers then '
739ae5366bed [web] stop using deprecated StatusResponse. Closes #3098215
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8697
diff changeset
   110
                '.is_client_cache_valid() method and return instead')
4557
a0571ff0cb5d [http cache/json controller] ensure json_view does proper cache validation #390986
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4212
diff changeset
   111
    def validate_cache(self, view):
a0571ff0cb5d [http cache/json controller] ensure json_view does proper cache validation #390986
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 4212
diff changeset
   112
        view.set_http_cache_headers()
4666
737cbdb87e87 3.6 api update (introduced by merge)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4636
diff changeset
   113
        self._cw.validate_cache()
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   114
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   115
    def sendmail(self, recipient, subject, body):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   116
        senderemail = self._cw.user.cw_adapt_to('IEmailable').get_email()
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   117
        msg = format_mail({'email' : senderemail,
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   118
                           'name' : self._cw.user.dc_title(),},
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   119
                          [recipient], body, subject)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   120
        if not self._cw.vreg.config.sendmails([(msg, [recipient])]):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   121
            msg = self._cw._('could not connect to the SMTP server')
7879
9aae456abab5 [pylint] fix pylint detected errors and tweak it so that pylint -E will be much less verbose next time (+ update some copyrights on the way)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7432
diff changeset
   122
            url = self._cw.build_url(__message=msg)
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   123
            raise Redirect(url)
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   124
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
    def reset(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
        """reset form parameters and redirect to a view determinated by given
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
        parameters
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
        newparams = {}
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
        # sets message if needed
7432
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 7293
diff changeset
   131
        # XXX - don't call .message twice since it pops the id
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 7293
diff changeset
   132
        msg = self._cw.message
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 7293
diff changeset
   133
        if msg:
cab99ccdb774 [ui messages, xss] Start migration towards use of _msgid instead of __message (prone to XSS injection) closes #1698245
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 7293
diff changeset
   134
            newparams['_cwmsgid'] = self._cw.set_redirect_message(msg)
8697
574bb05e40a4 [toward py3k] rewrite has_key() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8696
diff changeset
   135
        if '__action_apply' in self._cw.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
            self._return_to_edition_view(newparams)
8697
574bb05e40a4 [toward py3k] rewrite has_key() (part of #2711624)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8696
diff changeset
   137
        if '__action_cancel' in self._cw.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
            self._return_to_lastpage(newparams)
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._return_to_original_view(newparams)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
    def _return_to_original_view(self, newparams):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
        """validate-button case"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
        # transforms __redirect[*] parameters into regular form parameters
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3460
diff changeset
   145
        newparams.update(redirect_params(self._cw.form))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
        # find out if we have some explicit `rql` needs
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
        rql = newparams.pop('rql', None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
        # if rql is needed (explicit __redirectrql or multiple deletions for
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
        # instance), we have to use the old `view?rql=...` form
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
        if rql:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
            path = 'view'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
            newparams['rql'] = rql
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3460
diff changeset
   153
        elif '__redirectpath' in self._cw.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
            # if redirect path was explicitly specified in the form, use it
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3460
diff changeset
   155
            path = self._cw.form['__redirectpath']
4897
e402e0b32075 [web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4884
diff changeset
   156
            if (self._edited_entity and path != self._edited_entity.rest_path()
e402e0b32075 [web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4884
diff changeset
   157
                and '_cwmsgid' in newparams):
6866
51d7868264b1 [after edition ui] closes #1381425: Wrong message : 'entity edited (click here to see created entity)'
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6542
diff changeset
   158
                # are we here on creation or modification?
51d7868264b1 [after edition ui] closes #1381425: Wrong message : 'entity edited (click here to see created entity)'
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6542
diff changeset
   159
                if any(eid == self._edited_entity.eid
10663
54b8a1f249fb [py3k] dict.itervalues → dict.values
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9229
diff changeset
   160
                       for eid in self._cw.data.get('eidmap', {}).values()):
6866
51d7868264b1 [after edition ui] closes #1381425: Wrong message : 'entity edited (click here to see created entity)'
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6542
diff changeset
   161
                    msg = self._cw._('click here to see created entity')
51d7868264b1 [after edition ui] closes #1381425: Wrong message : 'entity edited (click here to see created entity)'
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6542
diff changeset
   162
                else:
51d7868264b1 [after edition ui] closes #1381425: Wrong message : 'entity edited (click here to see created entity)'
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6542
diff changeset
   163
                    msg = self._cw._('click here to see edited entity')
51d7868264b1 [after edition ui] closes #1381425: Wrong message : 'entity edited (click here to see created entity)'
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6542
diff changeset
   164
                msg = u'(<a href="%s">%s</a>)' % (xml_escape(self._edited_entity.absolute_url()), msg)
4897
e402e0b32075 [web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4884
diff changeset
   165
                self._cw.append_to_redirect_message(msg)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
        elif self._after_deletion_path:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
            # else it should have been set during form processing
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
            path, params = self._after_deletion_path
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
            params = dict(params) # params given as tuple
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
            params.update(newparams)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
            newparams = params
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
        elif self._edited_entity:
5040
00782905b720 [form controller] clear caches in case some attribute participating to the rest path has been modified, avoid redirection to a no more existant page (fix #753567)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4897
diff changeset
   173
            # clear caches in case some attribute participating to the rest path
00782905b720 [form controller] clear caches in case some attribute participating to the rest path has been modified, avoid redirection to a no more existant page (fix #753567)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4897
diff changeset
   174
            # has been modified
7293
97505b798975 [entity 3.13 api] rename clear_all_caches into cw_clear_all_cache
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6866
diff changeset
   175
            self._edited_entity.cw_clear_all_caches()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
            path = self._edited_entity.rest_path()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   178
            path = 'view'
3460
e4843535db25 [api] some more _cw / __regid__, automatic tests now pass again
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2890
diff changeset
   179
        url = self._cw.build_url(path, **newparams)
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3460
diff changeset
   180
        url = append_url_params(url, self._cw.form.get('__redirectparams'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
        raise Redirect(url)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   182
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
    def _return_to_edition_view(self, newparams):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
        """apply-button case"""
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3460
diff changeset
   185
        form = self._cw.form
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
        if self._edited_entity:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
            path = self._edited_entity.rest_path()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
            newparams.pop('rql', None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
        # else, fallback on the old `view?rql=...` url form
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3460
diff changeset
   190
        elif 'rql' in self._cw.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
            path = 'view'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
            newparams['rql'] = form['rql']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
        else:
4897
e402e0b32075 [web] start a new message system based on id of message stored in session's data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4884
diff changeset
   194
            self.warning('the edited data seems inconsistent')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
            path = 'view'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
        # pick up the correction edition view
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
        if form.get('__form_id'):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
            newparams['vid'] = form['__form_id']
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        # re-insert copy redirection parameters
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
        for redirectparam in NAV_FORM_PARAMETERS:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
            if redirectparam in form:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
                newparams[redirectparam] = form[redirectparam]
3460
e4843535db25 [api] some more _cw / __regid__, automatic tests now pass again
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 2890
diff changeset
   203
        raise Redirect(self._cw.build_url(path, **newparams))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
    def _return_to_lastpage(self, newparams):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
        """cancel-button case: in this case we are always expecting to go back
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
        where we came from, and this is not easy. Currently we suppose that
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
        __redirectpath is specifying that place if found, else we look in the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        request breadcrumbs for the last visited page.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        """
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3460
diff changeset
   212
        if '__redirectpath' in self._cw.form:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   213
            # if redirect path was explicitly specified in the form, use it
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3460
diff changeset
   214
            path = self._cw.form['__redirectpath']
8254
eff5b930998d [web/controller] fix some cases where _cwmsgid may appears twice
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 7879
diff changeset
   215
            url = self._cw.build_url(path)
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3460
diff changeset
   216
            url = append_url_params(url, self._cw.form.get('__redirectparams'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
        else:
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3460
diff changeset
   218
            url = self._cw.last_visited_page()
8254
eff5b930998d [web/controller] fix some cases where _cwmsgid may appears twice
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 7879
diff changeset
   219
        # The newparams must update the params in all cases
eff5b930998d [web/controller] fix some cases where _cwmsgid may appears twice
Anthony Truchet <anthony.truchet@logilab.fr>
parents: 7879
diff changeset
   220
        url = self._cw.rebuild_url(url, **newparams)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   221
        raise Redirect(url)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
from cubicweb import set_log_methods
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
set_log_methods(Controller, LOGGER)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226