cubicweb/req.py
author Simon Chabot <simon.chabot@logilab.fr>
Thu, 05 Mar 2020 17:49:34 +0100
branch3.26
changeset 12908 5c6d242069b6
parent 12183 af5d0a3c3f1a
child 12508 a8c1ea390400
permissions -rw-r--r--
[pkg] version 3.26.17
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
     1
# copyright 2003-2016 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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
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: 5290
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5924
diff changeset
    18
"""Base class for request/session"""
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
4933
433174d9394f add missing warn imports
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4899
diff changeset
    20
from warnings import warn
2796
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    21
from datetime import time, datetime, timedelta
10603
65ad6980976e [py3k] import URL mangling functions using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10338
diff changeset
    22
10694
7ece2df9cc5c [py3k] unicode vs str vs bytes vs the world
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10687
diff changeset
    23
from six import PY2, PY3, text_type
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    24
from six.moves.urllib.parse import (parse_qs, parse_qsl,
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    25
                                    quote as urlquote, unquote as urlunquote,
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    26
                                    urlsplit, urlunsplit)
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    27
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    28
from logilab.common.decorators import cached
3659
993997b4b41d 3.6 update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3655
diff changeset
    29
from logilab.common.deprecation import deprecated
4466
8b0ca7904820 moved generic datetime manipulation function to lgc
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4459
diff changeset
    30
from logilab.common.date import ustrftime, strptime, todate, todatetime
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    31
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
    32
from rql.utils import rqlvar_maker
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
    33
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
    34
from cubicweb import (Unauthorized, NoSelectableObject, NoResultError,
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
    35
                      MultipleResultsError, uilib)
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    36
from cubicweb.rset import ResultSet
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    37
2796
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    38
ONESECOND = timedelta(0, 1, 0)
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    39
CACHE_REGISTRY = {}
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    40
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    41
7116
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
    42
class FindEntityError(Exception):
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
    43
    """raised when find_one_entity() can not return one and only one entity"""
2796
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    44
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    45
2796
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    46
class Cache(dict):
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    47
    def __init__(self):
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    48
        super(Cache, self).__init__()
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    49
        _now = datetime.now()
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    50
        self.cache_creation_date = _now
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    51
        self.latest_cache_lookup = _now
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    52
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
    53
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    54
class RequestSessionBase(object):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    55
    """base class containing stuff shared by server session and web request
2825
87ac03aed941 doc update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2823
diff changeset
    56
87ac03aed941 doc update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2823
diff changeset
    57
    request/session is the main resources accessor, mainly through it's vreg
87ac03aed941 doc update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2823
diff changeset
    58
    attribute:
5290
15846058378b [doc/book] fix a bit the request chapter, add autodoc
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5199
diff changeset
    59
15846058378b [doc/book] fix a bit the request chapter, add autodoc
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5199
diff changeset
    60
    :attribute vreg: the instance's registry
15846058378b [doc/book] fix a bit the request chapter, add autodoc
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5199
diff changeset
    61
    :attribute vreg.schema: the instance's schema
15846058378b [doc/book] fix a bit the request chapter, add autodoc
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5199
diff changeset
    62
    :attribute vreg.config: the instance's configuration
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    63
    """
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    64
    is_request = True  # False for repository session
8525
c09feae04094 [entity edition] don't remove values from attribute cache on the repository side
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8309
diff changeset
    65
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    66
    def __init__(self, vreg):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    67
        self.vreg = vreg
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    68
        try:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    69
            encoding = vreg.property_value('ui.encoding')
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    70
        except Exception:  # no vreg or property not registered
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    71
            encoding = 'utf-8'
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    72
        self.encoding = encoding
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    73
        # cache result of execution for (rql expr / eids),
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    74
        # should be emptied on commit/rollback of the server session / web
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    75
        # connection
8847
074f9f385f6b [req] explicit `user` attribute
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 8791
diff changeset
    76
        self.user = None
11824
d7ecf6dab085 Fix AttributeError for "lang" on repo/client connections
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11799
diff changeset
    77
        self.lang = None
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    78
        self.local_perm_cache = {}
10672
f6f425a54a8d [py3k] unicode → six.text_type
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10669
diff changeset
    79
        self._ = text_type
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    80
9051
944d66870c6a [req] add a _set_user method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9022
diff changeset
    81
    def _set_user(self, orig_user):
944d66870c6a [req] add a _set_user method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9022
diff changeset
    82
        """set the user for this req_session_base
944d66870c6a [req] add a _set_user method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9022
diff changeset
    83
944d66870c6a [req] add a _set_user method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9022
diff changeset
    84
        A special method is needed to ensure the linked user is linked to the
944d66870c6a [req] add a _set_user method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9022
diff changeset
    85
        connection too.
944d66870c6a [req] add a _set_user method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9022
diff changeset
    86
        """
944d66870c6a [req] add a _set_user method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9022
diff changeset
    87
        rset = self.eid_rset(orig_user.eid, 'CWUser')
11699
b48020a80dc3 Store user groups and properties as session data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11348
diff changeset
    88
        user = self.vreg['etypes'].etype_class('CWUser')(self, rset, row=0)
b48020a80dc3 Store user groups and properties as session data
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11348
diff changeset
    89
        user.cw_attr_cache['login'] = orig_user.login  # cache login
9051
944d66870c6a [req] add a _set_user method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9022
diff changeset
    90
        self.user = user
944d66870c6a [req] add a _set_user method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9022
diff changeset
    91
        self.set_entity_cache(user)
944d66870c6a [req] add a _set_user method
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 9022
diff changeset
    92
8538
00597256de18 [request/session] refactor language handling: don't attempt to sync web/repo languages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8525
diff changeset
    93
    def set_language(self, lang):
00597256de18 [request/session] refactor language handling: don't attempt to sync web/repo languages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8525
diff changeset
    94
        """install i18n configuration for `lang` translation.
00597256de18 [request/session] refactor language handling: don't attempt to sync web/repo languages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8525
diff changeset
    95
00597256de18 [request/session] refactor language handling: don't attempt to sync web/repo languages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8525
diff changeset
    96
        Raises :exc:`KeyError` if translation doesn't exist.
00597256de18 [request/session] refactor language handling: don't attempt to sync web/repo languages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8525
diff changeset
    97
        """
00597256de18 [request/session] refactor language handling: don't attempt to sync web/repo languages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8525
diff changeset
    98
        self.lang = lang
11825
52acf0dbf4cd [web] Simplify a bit language handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
    99
        try:
52acf0dbf4cd [web] Simplify a bit language handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
   100
            gettext, pgettext = self.vreg.config.translations[lang]
52acf0dbf4cd [web] Simplify a bit language handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
   101
        except KeyError:
52acf0dbf4cd [web] Simplify a bit language handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
   102
            assert self.vreg.config.mode == 'test'
52acf0dbf4cd [web] Simplify a bit language handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
   103
            gettext = text_type
52acf0dbf4cd [web] Simplify a bit language handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
   104
52acf0dbf4cd [web] Simplify a bit language handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
   105
            def pgettext(x, y):
52acf0dbf4cd [web] Simplify a bit language handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
   106
                return text_type(y)
52acf0dbf4cd [web] Simplify a bit language handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11824
diff changeset
   107
8538
00597256de18 [request/session] refactor language handling: don't attempt to sync web/repo languages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8525
diff changeset
   108
        # use _cw.__ to translate a message without registering it to the catalog
00597256de18 [request/session] refactor language handling: don't attempt to sync web/repo languages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8525
diff changeset
   109
        self._ = self.__ = gettext
00597256de18 [request/session] refactor language handling: don't attempt to sync web/repo languages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8525
diff changeset
   110
        self.pgettext = pgettext
00597256de18 [request/session] refactor language handling: don't attempt to sync web/repo languages
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8525
diff changeset
   111
9459
d3016c08b4ae [repoapi] drop get_option_value's foreid argument
Julien Cristau <julien.cristau@logilab.fr>
parents: 9442
diff changeset
   112
    def get_option_value(self, option):
8585
3f60f416dddb [dbapi] provide get_option_value over DBAPIRequest (closes #2515522)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8309
diff changeset
   113
        raise NotImplementedError
3f60f416dddb [dbapi] provide get_option_value over DBAPIRequest (closes #2515522)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8309
diff changeset
   114
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   115
    def property_value(self, key):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   116
        """return value of the property with the given key, giving priority to
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   117
        user specific value if any, else using site value
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   118
        """
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   119
        if self.user:
9480
14159c600dad [req] if a user has a None property, fall back to the default
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   120
            val = self.user.property_value(key)
14159c600dad [req] if a user has a None property, fall back to the default
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   121
            if val is not None:
14159c600dad [req] if a user has a None property, fall back to the default
Julien Cristau <julien.cristau@logilab.fr>
parents: 9469
diff changeset
   122
                return val
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   123
        return self.vreg.property_value(key)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   124
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   125
    def etype_rset(self, etype, size=1):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   126
        """return a fake result set for a particular entity type"""
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   127
        rset = ResultSet([('A',)] * size, '%s X' % etype,
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   128
                         description=[(etype,)] * size)
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   129
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   130
        def get_entity(row, col=0, etype=etype, req=self, rset=rset):
7407
a78cc15227ef [deprecation] drop remaining warnings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7121
diff changeset
   131
            return req.vreg['etypes'].etype_class(etype)(req, rset, row, col)
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   132
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   133
        rset.get_entity = get_entity
4850
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   134
        rset.req = self
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   135
        return rset
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   136
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   137
    def eid_rset(self, eid, etype=None):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   138
        """return a result set for the given eid without doing actual query
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   139
        (we have the eid, we can suppose it exists and user has access to the
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   140
        entity)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   141
        """
8748
f5027f8d2478 drop typed_eid() in favour of int() (closes #2742462)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8596
diff changeset
   142
        eid = int(eid)
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   143
        if etype is None:
11765
9cb215e833b0 [cnx] Use entity_type instead of entity_metas()['type']
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11763
diff changeset
   144
            etype = self.entity_type(eid)
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   145
        rset = ResultSet([(eid,)], 'Any X WHERE X eid %(x)s', {'x': eid},
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   146
                         [(etype,)])
4850
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   147
        rset.req = self
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   148
        return rset
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   150
    def empty_rset(self):
5459
6e561796804c [doc/book] regroup form/editcontroller stuff under an "edition control" chapter
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5426
diff changeset
   151
        """ return a guaranteed empty result """
4850
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   152
        rset = ResultSet([], 'Any X WHERE X eid -1')
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   153
        rset.req = self
bd640b137f50 [refactor] drop rset.vreg attribute, vreg should be accessed through rset.req. Also kill decorate_rset, simply set rset.req where we were calling this method.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4835
diff changeset
   154
        return rset
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   155
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   156
    def entity_from_eid(self, eid, etype=None):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   157
        """return an entity instance for the given eid. No query is done"""
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   158
        try:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   159
            return self.entity_cache(eid)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   160
        except KeyError:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   161
            rset = self.eid_rset(eid, etype)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   162
            entity = rset.get_entity(0, 0)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
            self.set_entity_cache(entity)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   164
            return entity
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   165
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   166
    def entity_cache(self, eid):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   167
        raise KeyError
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   168
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   169
    def set_entity_cache(self, entity):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   170
        pass
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   171
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   172
    def create_entity(self, etype, **kwargs):
3629
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3163
diff changeset
   173
        """add a new entity of the given type
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3163
diff changeset
   174
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3163
diff changeset
   175
        Example (in a shell session):
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3163
diff changeset
   176
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   177
        >>> c = create_entity('Company', name=u'Logilab')
5924
b218df942dd4 [book] update rql documentation and some erroneous/deprecated examples
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 5736
diff changeset
   178
        >>> create_entity('Person', firstname=u'John', surname=u'Doe',
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   179
        ...               works_for=c)
3674
387d51af966d backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3659
diff changeset
   180
3629
559cad62c786 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3163
diff changeset
   181
        """
5199
ebb50479d2ab [entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4933
diff changeset
   182
        cls = self.vreg['etypes'].etype_class(etype)
ebb50479d2ab [entity] move req.create_entity content to a cw_instantiate factory method on entity classes, so cube developpers will be able to easily customize instance creation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4933
diff changeset
   183
        return cls.cw_instantiate(self.execute, **kwargs)
2968
0e3460341023 somewhat painful backport of 3.5 branch, should mostly be ok
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2825
diff changeset
   184
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   185
    @deprecated('[3.18] use find(etype, **kwargs).entities()')
7116
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   186
    def find_entities(self, etype, **kwargs):
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   187
        """find entities of the given type and attribute values.
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   188
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   189
        >>> users = find_entities('CWGroup', name=u'users')
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   190
        >>> groups = find_entities('CWGroup')
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   191
        """
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   192
        return self.find(etype, **kwargs).entities()
7116
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   193
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   194
    @deprecated('[3.18] use find(etype, **kwargs).one()')
7116
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   195
    def find_one_entity(self, etype, **kwargs):
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   196
        """find one entity of the given type and attribute values.
7121
c2badb6de3fe cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7116
diff changeset
   197
        raise :exc:`FindEntityError` if can not return one and only one entity.
7116
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   198
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   199
        >>> users = find_one_entity('CWGroup', name=u'users')
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   200
        >>> groups = find_one_entity('CWGroup')
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   201
        Exception()
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   202
        """
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   203
        try:
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   204
            return self.find(etype, **kwargs).one()
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   205
        except (NoResultError, MultipleResultsError) as e:
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   206
            raise FindEntityError("%s: (%s, %s)" % (str(e), etype, kwargs))
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   207
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   208
    def find(self, etype, **kwargs):
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   209
        """find entities of the given type and attribute values.
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   210
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   211
        :returns: A :class:`ResultSet`
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   212
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   213
        >>> users = find('CWGroup', name=u"users").one()
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   214
        >>> groups = find('CWGroup').entities()
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   215
        """
12181
29dae4b0332a [req] use format() instead of % substitution
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12179
diff changeset
   216
        parts = ['Any X WHERE X is {0}'.format(etype)]
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   217
        varmaker = rqlvar_maker(defined='X')
9720
a7210c912507 [req.find] Use vreg.schema.eschema for eschema lookup
Christophe de Vienne <cdevienne@gmail.com>
parents: 9480
diff changeset
   218
        eschema = self.vreg.schema.eschema(etype)
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   219
        for attr, value in kwargs.items():
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   220
            if isinstance(value, list) or isinstance(value, tuple):
12179
14f85569eda2 [req] clearer exception message
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11913
diff changeset
   221
                raise NotImplementedError(
14f85569eda2 [req] clearer exception message
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 11913
diff changeset
   222
                    '{0}: list of values are not supported'.format(attr))
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   223
            if hasattr(value, 'eid'):
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   224
                kwargs[attr] = value.eid
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   225
            if attr.startswith('reverse_'):
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   226
                attr = attr[8:]
12182
50109859da43 [req] raise KeyError instead of AssertionError in req.find()
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12181
diff changeset
   227
                if attr not in eschema.objrels:
50109859da43 [req] raise KeyError instead of AssertionError in req.find()
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12181
diff changeset
   228
                    raise KeyError('{0} not in {1} object relations'.format(attr, eschema))
12181
29dae4b0332a [req] use format() instead of % substitution
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12179
diff changeset
   229
                parts.append('{var} {attr} X, {var} eid %(reverse_{attr})s'.format(
29dae4b0332a [req] use format() instead of % substitution
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12179
diff changeset
   230
                    var=next(varmaker), attr=attr))
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   231
            else:
12183
af5d0a3c3f1a [req] fix find() generating non-rewritable rql on non final relations
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12182
diff changeset
   232
                rel = eschema.subjrels.get(attr)
af5d0a3c3f1a [req] fix find() generating non-rewritable rql on non final relations
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12182
diff changeset
   233
                if rel is None:
12182
50109859da43 [req] raise KeyError instead of AssertionError in req.find()
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12181
diff changeset
   234
                    raise KeyError('{0} not in {1} subject relations'.format(attr, eschema))
12183
af5d0a3c3f1a [req] fix find() generating non-rewritable rql on non final relations
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12182
diff changeset
   235
                if rel.final:
af5d0a3c3f1a [req] fix find() generating non-rewritable rql on non final relations
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12182
diff changeset
   236
                    parts.append('X {attr} %({attr})s'.format(attr=attr))
af5d0a3c3f1a [req] fix find() generating non-rewritable rql on non final relations
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12182
diff changeset
   237
                else:
af5d0a3c3f1a [req] fix find() generating non-rewritable rql on non final relations
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12182
diff changeset
   238
                    parts.append('X {attr} {var}, {var} eid %({attr})s'.format(
af5d0a3c3f1a [req] fix find() generating non-rewritable rql on non final relations
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12182
diff changeset
   239
                        attr=attr, var=next(varmaker)))
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   240
7116
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   241
        rql = ', '.join(parts)
9348
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   242
eacd02792332 [req] New method: RequestSessionBase.find().
Christophe de Vienne <cdevienne@gmail.com>
parents: 8847
diff changeset
   243
        return self.execute(rql, kwargs)
7116
dfd4680a23f0 [session] add find_entities and find_one_entity to session/request API (closes #1550045)
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6750
diff changeset
   244
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   245
    def ensure_ro_rql(self, rql):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   246
        """raise an exception if the given rql is not a select query"""
6747
63bf61e4e130 [security] fix access control problem
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 6321
diff changeset
   247
        first = rql.split(None, 1)[0].lower()
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   248
        if first in ('insert', 'set', 'delete'):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   249
            raise Unauthorized(self._('only select queries are authorized'))
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   250
2796
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   251
    def get_cache(self, cachename):
5290
15846058378b [doc/book] fix a bit the request chapter, add autodoc
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5199
diff changeset
   252
        """cachename should be dotted names as in :
15846058378b [doc/book] fix a bit the request chapter, add autodoc
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 5199
diff changeset
   253
2796
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   254
        - cubicweb.mycache
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   255
        - cubes.blog.mycache
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   256
        - etc.
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   257
        """
9442
fbf2287fb2ce [req] deprecate get_cache (closes #3181499)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9402
diff changeset
   258
        warn.warning('[3.19] .get_cache will disappear soon. '
fbf2287fb2ce [req] deprecate get_cache (closes #3181499)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9402
diff changeset
   259
                     'Distributed caching mechanisms are being introduced instead.'
fbf2287fb2ce [req] deprecate get_cache (closes #3181499)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9402
diff changeset
   260
                     'Other caching mechanism can be used more reliably '
fbf2287fb2ce [req] deprecate get_cache (closes #3181499)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9402
diff changeset
   261
                     'to the same effect.',
fbf2287fb2ce [req] deprecate get_cache (closes #3181499)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 9402
diff changeset
   262
                     DeprecationWarning)
2796
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   263
        if cachename in CACHE_REGISTRY:
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   264
            cache = CACHE_REGISTRY[cachename]
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   265
        else:
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   266
            cache = CACHE_REGISTRY[cachename] = Cache()
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   267
        _now = datetime.now()
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   268
        if _now > cache.latest_cache_lookup + ONESECOND:
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   269
            ecache = self.execute(
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   270
                'Any C,T WHERE C is CWCache, C name %(name)s, C timestamp T',
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   271
                {'name': cachename}).get_entity(0, 0)
2796
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   272
            cache.latest_cache_lookup = _now
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   273
            if not ecache.valid(cache.cache_creation_date):
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   274
                cache.clear()
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   275
                cache.cache_creation_date = _now
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   276
        return cache
14d2c69e12c4 move get_cache to base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2792
diff changeset
   277
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   278
    # url generation methods ##################################################
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   279
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   280
    def build_url(self, *args, **kwargs):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   281
        """return an absolute URL using params dictionary key/values as URL
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   282
        parameters. Values are automatically URL quoted, and the
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   283
        publishing method to use may be specified or will be guessed.
6321
a8a33679f4dd [req] build_url: detect None values in arguments and raise ValueError
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6141
diff changeset
   284
a8a33679f4dd [req] build_url: detect None values in arguments and raise ValueError
Julien Jehannet <julien.jehannet@logilab.fr>
parents: 6141
diff changeset
   285
        raises :exc:`ValueError` if None is found in arguments
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   286
        """
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   287
        # use *args since we don't want first argument to be "anonymous" to
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   288
        # avoid potential clash with kwargs
9022
a1cee6915ea3 [req] drop from_controller on non WebRequest object (Closes #2901079)
pierre-yves
parents: 8847
diff changeset
   289
        method = None
2798
9c650701cb17 stop using controller class attribute, allowing to deprecate appobject.build_url in favor of req.build_url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2796
diff changeset
   290
        if args:
9c650701cb17 stop using controller class attribute, allowing to deprecate appobject.build_url in favor of req.build_url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2796
diff changeset
   291
            assert len(args) == 1, 'only 0 or 1 non-named-argument expected'
9c650701cb17 stop using controller class attribute, allowing to deprecate appobject.build_url in favor of req.build_url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2796
diff changeset
   292
            method = args[0]
9022
a1cee6915ea3 [req] drop from_controller on non WebRequest object (Closes #2901079)
pierre-yves
parents: 8847
diff changeset
   293
        if method is None:
a1cee6915ea3 [req] drop from_controller on non WebRequest object (Closes #2901079)
pierre-yves
parents: 8847
diff changeset
   294
            method = 'view'
2798
9c650701cb17 stop using controller class attribute, allowing to deprecate appobject.build_url in favor of req.build_url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2796
diff changeset
   295
        # XXX I (adim) think that if method is passed explicitly, we should
9c650701cb17 stop using controller class attribute, allowing to deprecate appobject.build_url in favor of req.build_url
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2796
diff changeset
   296
        #     not try to process it and directly call req.build_url()
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   297
        base_url = kwargs.pop('base_url', None)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   298
        if base_url is None:
11913
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   299
            if kwargs.pop('__secure__', None) is not None:
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   300
                warn('[3.25] __secure__ argument is deprecated',
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   301
                     DeprecationWarning, stacklevel=2)
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   302
            base_url = self.base_url()
11799
1bdfe9d4ab83 [req,web/request] Move language prefix handling into web request
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11794
diff changeset
   303
        path = self.build_url_path(method, kwargs)
1bdfe9d4ab83 [req,web/request] Move language prefix handling into web request
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11794
diff changeset
   304
        if not kwargs:
1bdfe9d4ab83 [req,web/request] Move language prefix handling into web request
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11794
diff changeset
   305
            return u'%s%s' % (base_url, path)
1bdfe9d4ab83 [req,web/request] Move language prefix handling into web request
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11794
diff changeset
   306
        return u'%s%s?%s' % (base_url, path, self.build_url_params(**kwargs))
1bdfe9d4ab83 [req,web/request] Move language prefix handling into web request
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11794
diff changeset
   307
1bdfe9d4ab83 [req,web/request] Move language prefix handling into web request
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11794
diff changeset
   308
    def build_url_path(self, method, kwargs):
1bdfe9d4ab83 [req,web/request] Move language prefix handling into web request
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11794
diff changeset
   309
        """return the "path" part of an URL"""
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   310
        if '_restpath' in kwargs:
9022
a1cee6915ea3 [req] drop from_controller on non WebRequest object (Closes #2901079)
pierre-yves
parents: 8847
diff changeset
   311
            assert method == 'view', repr(method)
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   312
            path = kwargs.pop('_restpath')
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   313
        else:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   314
            path = method
11799
1bdfe9d4ab83 [req,web/request] Move language prefix handling into web request
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11794
diff changeset
   315
        return path
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   316
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   317
    def build_url_params(self, **kwargs):
9700
da7d341cca76 an URL -> a URL
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9693
diff changeset
   318
        """return encoded params to incorporate them in a URL"""
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   319
        args = []
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10603
diff changeset
   320
        for param, values in kwargs.items():
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   321
            if not isinstance(values, (list, tuple)):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   322
                values = (values,)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   323
            for value in values:
6582
8eb7883b4223 [pylint] fix a bug of pylint detected errors and i18n pb (calling builtins._ instead of req._)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6321
diff changeset
   324
                assert value is not None
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   325
                args.append(u'%s=%s' % (param, self.url_quote(value)))
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   326
        return '&'.join(args)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   327
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   328
    def url_quote(self, value, safe=''):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   329
        """urllib.quote is not unicode safe, use this method to do the
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   330
        necessary encoding / decoding. Also it's designed to quote each
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   331
        part of a url path and so the '/' character will be encoded as well.
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   332
        """
11868
d5181d7f1389 Some py3k related fixes: use text_type instead of unicode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11825
diff changeset
   333
        if PY2 and isinstance(value, text_type):
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   334
            quoted = urlquote(value.encode(self.encoding), safe=safe)
11868
d5181d7f1389 Some py3k related fixes: use text_type instead of unicode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11825
diff changeset
   335
            return text_type(quoted, self.encoding)
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   336
        return urlquote(str(value), safe=safe)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   337
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   338
    def url_unquote(self, quoted):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   339
        """returns a unicode unquoted string
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   340
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   341
        decoding is based on `self.encoding` which is the encoding
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   342
        used in `url_quote`
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   343
        """
10694
7ece2df9cc5c [py3k] unicode vs str vs bytes vs the world
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10687
diff changeset
   344
        if PY3:
7ece2df9cc5c [py3k] unicode vs str vs bytes vs the world
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10687
diff changeset
   345
            return urlunquote(quoted)
11868
d5181d7f1389 Some py3k related fixes: use text_type instead of unicode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11825
diff changeset
   346
        if isinstance(quoted, text_type):
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   347
            quoted = quoted.encode(self.encoding)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   348
        try:
11868
d5181d7f1389 Some py3k related fixes: use text_type instead of unicode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11825
diff changeset
   349
            return text_type(urlunquote(quoted), self.encoding)
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   350
        except UnicodeDecodeError:  # might occurs on manually typed URLs
11868
d5181d7f1389 Some py3k related fixes: use text_type instead of unicode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11825
diff changeset
   351
            return text_type(urlunquote(quoted), 'iso-8859-1')
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   352
4300
03430023ce82 new url_parse_qs method on base request to parse unicode url formatted query strings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4222
diff changeset
   353
    def url_parse_qsl(self, querystring):
03430023ce82 new url_parse_qs method on base request to parse unicode url formatted query strings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4222
diff changeset
   354
        """return a list of (key, val) found in the url quoted query string"""
10694
7ece2df9cc5c [py3k] unicode vs str vs bytes vs the world
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10687
diff changeset
   355
        if PY3:
7ece2df9cc5c [py3k] unicode vs str vs bytes vs the world
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10687
diff changeset
   356
            for key, val in parse_qsl(querystring):
7ece2df9cc5c [py3k] unicode vs str vs bytes vs the world
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10687
diff changeset
   357
                yield key, val
10753
c90e7bf2dd55 [req] fix url_parse_qsl on py3
Julien Cristau <julien.cristau@logilab.fr>
parents: 10723
diff changeset
   358
            return
11868
d5181d7f1389 Some py3k related fixes: use text_type instead of unicode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11825
diff changeset
   359
        if isinstance(querystring, text_type):
4300
03430023ce82 new url_parse_qs method on base request to parse unicode url formatted query strings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4222
diff changeset
   360
            querystring = querystring.encode(self.encoding)
03430023ce82 new url_parse_qs method on base request to parse unicode url formatted query strings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4222
diff changeset
   361
        for key, val in parse_qsl(querystring):
03430023ce82 new url_parse_qs method on base request to parse unicode url formatted query strings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4222
diff changeset
   362
            try:
11868
d5181d7f1389 Some py3k related fixes: use text_type instead of unicode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11825
diff changeset
   363
                yield text_type(key, self.encoding), text_type(val, self.encoding)
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   364
            except UnicodeDecodeError:  # might occurs on manually typed URLs
11868
d5181d7f1389 Some py3k related fixes: use text_type instead of unicode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11825
diff changeset
   365
                yield text_type(key, 'iso-8859-1'), text_type(val, 'iso-8859-1')
4300
03430023ce82 new url_parse_qs method on base request to parse unicode url formatted query strings
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4222
diff changeset
   366
4891
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   367
    def rebuild_url(self, url, **newparams):
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   368
        """return the given url with newparams inserted. If any new params
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   369
        is already specified in the url, it's overriden by the new value
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   370
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   371
        newparams may only be mono-valued.
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   372
        """
11868
d5181d7f1389 Some py3k related fixes: use text_type instead of unicode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11825
diff changeset
   373
        if PY2 and isinstance(url, text_type):
4891
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   374
            url = url.encode(self.encoding)
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   375
        schema, netloc, path, query, fragment = urlsplit(url)
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   376
        query = parse_qs(query)
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   377
        # sort for testing predictability
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10603
diff changeset
   378
        for key, val in sorted(newparams.items()):
4891
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   379
            query[key] = (self.url_quote(val),)
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   380
        query = '&'.join(u'%s=%s' % (param, value)
10256
f753f364550f [req] make rebuild_url predictable
Julien Cristau <julien.cristau@logilab.fr>
parents: 9821
diff changeset
   381
                         for param, values in sorted(query.items())
4891
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   382
                         for value in values)
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   383
        return urlunsplit((schema, netloc, path, query, fragment))
90203ec7b3e3 [url] new rebuild_url method on base request
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   384
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   385
    # bound user related methods ###############################################
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   386
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   387
    @cached
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   388
    def user_data(self):
9693
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   389
        """returns a dictionary with this user's information.
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   390
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   391
        The keys are :
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   392
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   393
        login
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   394
            The user login
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   395
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   396
        name
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   397
            The user name, returned by user.name()
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   398
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   399
        email
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   400
            The user principal email
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   401
c7a184dd76b2 [doc] Document the user_data dictionnary content
Christophe de Vienne <christophe@unlish.com>
parents: 9386
diff changeset
   402
        """
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   403
        userinfo = {}
4835
13b0b96d7982 [repo] enhanced security handling: deprecates unsafe_execute, in favor of explicit read/write security control using the `enabled_security` context manager. Also code executed on the repository side is now unsafe by default.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4466
diff changeset
   404
        user = self.user
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   405
        userinfo['login'] = user.login
3163
edfe43ceaa35 backport 3.5
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2968
diff changeset
   406
        userinfo['name'] = user.name()
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5527
diff changeset
   407
        userinfo['email'] = user.cw_adapt_to('IEmailable').get_email()
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   408
        return userinfo
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   409
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   410
    # formating methods #######################################################
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   411
2823
a4e3e9b1a9cd backported from appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2808
diff changeset
   412
    def view(self, __vid, rset=None, __fallback_oid=None, __registry='views',
5516
232d13fc3e86 [req] avoid getting w in cw_extra_kwargs when calling .view
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5459
diff changeset
   413
             initargs=None, w=None, **kwargs):
4070
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   414
        """Select object with the given id (`__oid`) then render it.  If the
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   415
        object isn't selectable, try to select fallback object if
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   416
        `__fallback_oid` is specified.
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   417
8238
087bb529035c [spelling] fix dictionnary -> dictionary typo
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7990
diff changeset
   418
        If specified `initargs` is expected to be a dictionary containing
4070
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   419
        arguments that should be given to selection (hence to object's __init__
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   420
        as well), but not to render(). Other arbitrary keyword arguments will be
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   421
        given to selection *and* to render(), and so should be handled by
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   422
        object's call or cell_call method..
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   423
        """
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   424
        if initargs is None:
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   425
            initargs = kwargs
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   426
        else:
6e9f7abee4ef fix initargs handling
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 3720
diff changeset
   427
            initargs.update(kwargs)
3655
af86ab65a282 3.6 updates
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3629
diff changeset
   428
        try:
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   429
            view = self.vreg[__registry].select(__vid, self, rset=rset, **initargs)
7888
e257b4476454 [req] .view should not catch [Object|Registry]NotFound (which is a bug), only NoSelectableObject (closes #1973681)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   430
        except NoSelectableObject:
5709
5606c01d68b2 [view] ensure fallback_oid is specified before trying to select fallback view, else simply raise the exception
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5516
diff changeset
   431
            if __fallback_oid is None:
5606c01d68b2 [view] ensure fallback_oid is specified before trying to select fallback view, else simply raise the exception
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5516
diff changeset
   432
                raise
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   433
            view = self.vreg[__registry].select(__fallback_oid, self, rset=rset, **initargs)
5516
232d13fc3e86 [req] avoid getting w in cw_extra_kwargs when calling .view
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5459
diff changeset
   434
        return view.render(w=w, **kwargs)
2823
a4e3e9b1a9cd backported from appobject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2808
diff changeset
   435
7914
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   436
    def printable_value(self, attrtype, value, props=None, displaytime=True,
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   437
                        formatters=uilib.PRINTERS):
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   438
        """return a displayablye value (i.e. unicode string)"""
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   439
        if value is None:
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   440
            return u''
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   441
        try:
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   442
            as_string = formatters[attrtype]
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   443
        except KeyError:
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   444
            self.error('given bad attrtype %s', attrtype)
11868
d5181d7f1389 Some py3k related fixes: use text_type instead of unicode
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11825
diff changeset
   445
            return text_type(value)
7914
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   446
        return as_string(value, self, props, displaytime)
fb757a7d887e [request, ui] printable_value is now a method of request, and may be given dict of formatters to use (closes #1984743)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7888
diff changeset
   447
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   448
    def format_date(self, date, date_format=None, time=False):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   449
        """return a string for a date time according to instance's
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   450
        configuration
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   451
        """
5710
1c17e47df974 [req] fix format_time w/ 0:0 which is evaluated to False
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5709
diff changeset
   452
        if date is not None:
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   453
            if date_format is None:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   454
                if time:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   455
                    date_format = self.property_value('ui.datetime-format')
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   456
                else:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   457
                    date_format = self.property_value('ui.date-format')
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   458
            return ustrftime(date, date_format)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   459
        return u''
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   460
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   461
    def format_time(self, time):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   462
        """return a string for a time according to instance's
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   463
        configuration
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   464
        """
5710
1c17e47df974 [req] fix format_time w/ 0:0 which is evaluated to False
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5709
diff changeset
   465
        if time is not None:
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   466
            return ustrftime(time, self.property_value('ui.time-format'))
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   467
        return u''
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   468
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   469
    def format_float(self, num):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   470
        """return a string for floating point number according to instance's
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   471
        configuration
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   472
        """
4459
f628abfb3a6c backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4307
diff changeset
   473
        if num is not None:
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   474
            return self.property_value('ui.float-format') % num
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   475
        return u''
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   476
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   477
    def parse_datetime(self, value, etype='Datetime'):
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   478
        """get a datetime or time from a string (according to etype)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   479
        Datetime formatted as Date are accepted
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   480
        """
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   481
        assert etype in ('Datetime', 'Date', 'Time'), etype
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   482
        # XXX raise proper validation error
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   483
        if etype == 'Datetime':
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   484
            format = self.property_value('ui.datetime-format')
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   485
            try:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   486
                return todatetime(strptime(value, format))
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   487
            except ValueError:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   488
                pass
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   489
        elif etype == 'Time':
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   490
            format = self.property_value('ui.time-format')
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   491
            try:
11348
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   492
                # (adim) I can't find a way to parse a time with a custom format
70337ad23145 pep8 + docstrings and comments improvments
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
   493
                date = strptime(value, format)  # this returns a datetime
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   494
                return time(date.hour, date.minute, date.second)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   495
            except ValueError:
4222
5667f493c505 return localized message on parse_datetime errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4070
diff changeset
   496
                raise ValueError(self._('can\'t parse %(value)r (expected %(format)s)')
5667f493c505 return localized message on parse_datetime errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4070
diff changeset
   497
                                 % {'value': value, 'format': format})
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   498
        try:
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   499
            format = self.property_value('ui.date-format')
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   500
            dt = strptime(value, format)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   501
            if etype == 'Datetime':
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   502
                return todatetime(dt)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   503
            return todate(dt)
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   504
        except ValueError:
4222
5667f493c505 return localized message on parse_datetime errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4070
diff changeset
   505
            raise ValueError(self._('can\'t parse %(value)r (expected %(format)s)')
5667f493c505 return localized message on parse_datetime errors
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4070
diff changeset
   506
                             % {'value': value, 'format': format})
2792
135580d15d42 rename and move cw.RequestSessionMixIn to cw.req.RequestSessionBase; move some appobjects methods where they actually belong to
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   507
11913
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   508
    def base_url(self, **kwargs):
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   509
        """Return the root url of the instance."""
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   510
        secure = kwargs.pop('secure', None)
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   511
        if secure is not None:
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   512
            warn('[3.25] secure argument is deprecated', DeprecationWarning, stacklevel=2)
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   513
        if kwargs:
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   514
            raise TypeError('base_url got unexpected keyword arguments %s' % ', '.join(kwargs))
4516c3956d46 Drop support for https-url in all-in-one.conf
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11868
diff changeset
   515
        url = self.vreg.config['base-url']
9818
e3d2012adcd0 [request] Ensure base_url() always has a trailing '/' (closes #3955093)
Rémi Cardona <remi.cardona@logilab.fr>
parents: 9480
diff changeset
   516
        return url if url is None else url.rstrip('/') + '/'