cubicweb/req.py
changeset 12567 26744ad37953
parent 12508 a8c1ea390400
child 12845 dd557dca2e86
equal deleted inserted replaced
12566:6b3523f81f42 12567:26744ad37953
    16 # You should have received a copy of the GNU Lesser General Public License along
    16 # You should have received a copy of the GNU Lesser General Public License along
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    18 """Base class for request/session"""
    18 """Base class for request/session"""
    19 
    19 
    20 from datetime import time, datetime, timedelta
    20 from datetime import time, datetime, timedelta
    21 
    21 from urllib.parse import (parse_qs, parse_qsl,
    22 from six import PY2, PY3, text_type
    22                           quote as urlquote, unquote as urlunquote,
    23 from six.moves.urllib.parse import (parse_qs, parse_qsl,
    23                           urlsplit, urlunsplit)
    24                                     quote as urlquote, unquote as urlunquote,
       
    25                                     urlsplit, urlunsplit)
       
    26 
    24 
    27 from logilab.common.decorators import cached
    25 from logilab.common.decorators import cached
    28 from logilab.common.date import ustrftime, strptime, todate, todatetime
    26 from logilab.common.date import ustrftime, strptime, todate, todatetime
    29 
    27 
    30 from rql.utils import rqlvar_maker
    28 from rql.utils import rqlvar_maker
    71         # should be emptied on commit/rollback of the server session / web
    69         # should be emptied on commit/rollback of the server session / web
    72         # connection
    70         # connection
    73         self.user = None
    71         self.user = None
    74         self.lang = None
    72         self.lang = None
    75         self.local_perm_cache = {}
    73         self.local_perm_cache = {}
    76         self._ = text_type
    74         self._ = str
    77 
    75 
    78     def _set_user(self, orig_user):
    76     def _set_user(self, orig_user):
    79         """set the user for this req_session_base
    77         """set the user for this req_session_base
    80 
    78 
    81         A special method is needed to ensure the linked user is linked to the
    79         A special method is needed to ensure the linked user is linked to the
    95         self.lang = lang
    93         self.lang = lang
    96         try:
    94         try:
    97             gettext, pgettext = self.vreg.config.translations[lang]
    95             gettext, pgettext = self.vreg.config.translations[lang]
    98         except KeyError:
    96         except KeyError:
    99             assert self.vreg.config.mode == 'test'
    97             assert self.vreg.config.mode == 'test'
   100             gettext = text_type
    98             gettext = str
   101 
    99 
   102             def pgettext(x, y):
   100             def pgettext(x, y):
   103                 return text_type(y)
   101                 return str(y)
   104 
   102 
   105         # use _cw.__ to translate a message without registering it to the catalog
   103         # use _cw.__ to translate a message without registering it to the catalog
   106         self._ = self.__ = gettext
   104         self._ = self.__ = gettext
   107         self.pgettext = pgettext
   105         self.pgettext = pgettext
   108 
   106 
   272     def url_quote(self, value, safe=''):
   270     def url_quote(self, value, safe=''):
   273         """urllib.quote is not unicode safe, use this method to do the
   271         """urllib.quote is not unicode safe, use this method to do the
   274         necessary encoding / decoding. Also it's designed to quote each
   272         necessary encoding / decoding. Also it's designed to quote each
   275         part of a url path and so the '/' character will be encoded as well.
   273         part of a url path and so the '/' character will be encoded as well.
   276         """
   274         """
   277         if PY2 and isinstance(value, text_type):
       
   278             quoted = urlquote(value.encode(self.encoding), safe=safe)
       
   279             return text_type(quoted, self.encoding)
       
   280         return urlquote(str(value), safe=safe)
   275         return urlquote(str(value), safe=safe)
   281 
   276 
   282     def url_unquote(self, quoted):
   277     def url_unquote(self, quoted):
   283         """returns a unicode unquoted string
   278         """returns a unicode unquoted string
   284 
   279 
   285         decoding is based on `self.encoding` which is the encoding
   280         decoding is based on `self.encoding` which is the encoding
   286         used in `url_quote`
   281         used in `url_quote`
   287         """
   282         """
   288         if PY3:
   283         return urlunquote(quoted)
   289             return urlunquote(quoted)
       
   290         if isinstance(quoted, text_type):
       
   291             quoted = quoted.encode(self.encoding)
       
   292         try:
       
   293             return text_type(urlunquote(quoted), self.encoding)
       
   294         except UnicodeDecodeError:  # might occurs on manually typed URLs
       
   295             return text_type(urlunquote(quoted), 'iso-8859-1')
       
   296 
   284 
   297     def url_parse_qsl(self, querystring):
   285     def url_parse_qsl(self, querystring):
   298         """return a list of (key, val) found in the url quoted query string"""
   286         """return a list of (key, val) found in the url quoted query string"""
   299         if PY3:
       
   300             for key, val in parse_qsl(querystring):
       
   301                 yield key, val
       
   302             return
       
   303         if isinstance(querystring, text_type):
       
   304             querystring = querystring.encode(self.encoding)
       
   305         for key, val in parse_qsl(querystring):
   287         for key, val in parse_qsl(querystring):
   306             try:
   288             yield key, val
   307                 yield text_type(key, self.encoding), text_type(val, self.encoding)
   289         return
   308             except UnicodeDecodeError:  # might occurs on manually typed URLs
       
   309                 yield text_type(key, 'iso-8859-1'), text_type(val, 'iso-8859-1')
       
   310 
   290 
   311     def rebuild_url(self, url, **newparams):
   291     def rebuild_url(self, url, **newparams):
   312         """return the given url with newparams inserted. If any new params
   292         """return the given url with newparams inserted. If any new params
   313         is already specified in the url, it's overriden by the new value
   293         is already specified in the url, it's overriden by the new value
   314 
   294 
   315         newparams may only be mono-valued.
   295         newparams may only be mono-valued.
   316         """
   296         """
   317         if PY2 and isinstance(url, text_type):
       
   318             url = url.encode(self.encoding)
       
   319         schema, netloc, path, query, fragment = urlsplit(url)
   297         schema, netloc, path, query, fragment = urlsplit(url)
   320         query = parse_qs(query)
   298         query = parse_qs(query)
   321         # sort for testing predictability
   299         # sort for testing predictability
   322         for key, val in sorted(newparams.items()):
   300         for key, val in sorted(newparams.items()):
   323             query[key] = (self.url_quote(val),)
   301             query[key] = (self.url_quote(val),)
   384             return u''
   362             return u''
   385         try:
   363         try:
   386             as_string = formatters[attrtype]
   364             as_string = formatters[attrtype]
   387         except KeyError:
   365         except KeyError:
   388             self.error('given bad attrtype %s', attrtype)
   366             self.error('given bad attrtype %s', attrtype)
   389             return text_type(value)
   367             return str(value)
   390         return as_string(value, self, props, displaytime)
   368         return as_string(value, self, props, displaytime)
   391 
   369 
   392     def format_date(self, date, date_format=None, time=False):
   370     def format_date(self, date, date_format=None, time=False):
   393         """return a string for a date time according to instance's
   371         """return a string for a date time according to instance's
   394         configuration
   372         configuration