web/request.py
branchstable
changeset 7677 134613d3b353
parent 7660 a1506b5306cc
child 7762 a3f9ba4d44eb
child 7793 8a330017ca4d
equal deleted inserted replaced
7670:6397a9051f65 7677:134613d3b353
    90             self.datadir_url = vreg.config.https_datadir_url
    90             self.datadir_url = vreg.config.https_datadir_url
    91         else:
    91         else:
    92             self.uiprops = vreg.config.uiprops
    92             self.uiprops = vreg.config.uiprops
    93             self.datadir_url = vreg.config.datadir_url
    93             self.datadir_url = vreg.config.datadir_url
    94         # raw html headers that can be added from any view
    94         # raw html headers that can be added from any view
    95         self.html_headers = HTMLHead()
    95         self.html_headers = HTMLHead(self.datadir_url)
    96         # form parameters
    96         # form parameters
    97         self.setup_params(form)
    97         self.setup_params(form)
    98         # dictionnary that may be used to store request data that has to be
    98         # dictionnary that may be used to store request data that has to be
    99         # shared among various components used to publish the request (views,
    99         # shared among various components used to publish the request (views,
   100         # controller, application...)
   100         # controller, application...)
   212             if param in self.no_script_form_params and val:
   212             if param in self.no_script_form_params and val:
   213                 val = self.no_script_form_param(param, val)
   213                 val = self.no_script_form_param(param, val)
   214             if param == '_cwmsgid':
   214             if param == '_cwmsgid':
   215                 self.set_message_id(val)
   215                 self.set_message_id(val)
   216             elif param == '__message':
   216             elif param == '__message':
       
   217                 warn('[3.13] __message in request parameter is deprecated (may '
       
   218                      'only be given to .build_url). Seeing this message usualy '
       
   219                      'means your application hold some <form> where you should '
       
   220                      'replace use of __message hidden input by form.set_message, '
       
   221                      'so new _cwmsgid mechanism is properly used',
       
   222                      DeprecationWarning)
   217                 self.set_message(val)
   223                 self.set_message(val)
   218             else:
   224             else:
   219                 self.form[param] = val
   225                 self.form[param] = val
   220 
   226 
   221     def no_script_form_param(self, param, value):
   227     def no_script_form_param(self, param, value):
   254 
   260 
   255     def reset_headers(self):
   261     def reset_headers(self):
   256         """used by AutomaticWebTest to clear html headers between tests on
   262         """used by AutomaticWebTest to clear html headers between tests on
   257         the same resultset
   263         the same resultset
   258         """
   264         """
   259         self.html_headers = HTMLHead()
   265         self.html_headers = HTMLHead(self.datadir_url)
   260         return self
   266         return self
   261 
   267 
   262     # web state helpers #######################################################
   268     # web state helpers #######################################################
   263 
   269 
   264     @property
   270     @property
   265     def message(self):
   271     def message(self):
   266         try:
   272         try:
   267             return self.session.data.pop(self._msgid, '')
   273             return self.session.data.pop(self._msgid, u'')
   268         except AttributeError:
   274         except AttributeError:
   269             try:
   275             try:
   270                 return self._msg
   276                 return self._msg
   271             except AttributeError:
   277             except AttributeError:
   272                 return None
   278                 return None
   281     @cached
   287     @cached
   282     def redirect_message_id(self):
   288     def redirect_message_id(self):
   283         return make_uid()
   289         return make_uid()
   284 
   290 
   285     def set_redirect_message(self, msg):
   291     def set_redirect_message(self, msg):
       
   292         # TODO - this should probably be merged with append_to_redirect_message
   286         assert isinstance(msg, unicode)
   293         assert isinstance(msg, unicode)
   287         msgid = self.redirect_message_id()
   294         msgid = self.redirect_message_id()
   288         self.session.data[msgid] = msg
   295         self.session.data[msgid] = msg
   289         return msgid
   296         return msgid
   290 
   297 
   291     def append_to_redirect_message(self, msg):
   298     def append_to_redirect_message(self, msg):
   292         msgid = self.redirect_message_id()
   299         msgid = self.redirect_message_id()
   293         currentmsg = self.session.data.get(msgid)
   300         currentmsg = self.session.data.get(msgid)
   294         if currentmsg is not None:
   301         if currentmsg is not None:
   295             currentmsg = '%s %s' % (currentmsg, msg)
   302             currentmsg = u'%s %s' % (currentmsg, msg)
   296         else:
   303         else:
   297             currentmsg = msg
   304             currentmsg = msg
   298         self.session.data[msgid] = currentmsg
   305         self.session.data[msgid] = currentmsg
   299         return msgid
   306         return msgid
   300 
   307 
   413 
   420 
   414     # web edition helpers #####################################################
   421     # web edition helpers #####################################################
   415 
   422 
   416     @cached # so it's writed only once
   423     @cached # so it's writed only once
   417     def fckeditor_config(self):
   424     def fckeditor_config(self):
   418         self.add_js('fckeditor/fckeditor.js')
   425         fckeditor_url = self.build_url('fckeditor/fckeditor.js')
       
   426         self.add_js(fckeditor_url, localfile=False)
   419         self.html_headers.define_var('fcklang', self.lang)
   427         self.html_headers.define_var('fcklang', self.lang)
   420         self.html_headers.define_var('fckconfigpath',
   428         self.html_headers.define_var('fckconfigpath',
   421                                      self.data_url('cubicweb.fckcwconfig.js'))
   429                                      self.data_url('cubicweb.fckcwconfig.js'))
   422     def use_fckeditor(self):
   430     def use_fckeditor(self):
   423         return self.vreg.config.fckeditor_installed() and self.property_value('ui.fckeditor')
   431         return self.vreg.config.fckeditor_installed() and self.property_value('ui.fckeditor')
   452         form = self.form
   460         form = self.form
   453         for param in form:
   461         for param in form:
   454             try:
   462             try:
   455                 name, peid = param.split(':', 1)
   463                 name, peid = param.split(':', 1)
   456             except ValueError:
   464             except ValueError:
   457                 if not param.startswith('__') and param != "eid":
   465                 if not param.startswith('__') and param not in ('eid', '_cw_fields'):
   458                     self.warning('param %s mis-formatted', param)
   466                     self.warning('param %s mis-formatted', param)
   459                 continue
   467                 continue
   460             if peid == eid:
   468             if peid == eid:
   461                 value = form[param]
   469                 value = form[param]
   462                 if value == INTERNAL_FIELD_VALUE:
   470                 if value == INTERNAL_FIELD_VALUE:
   615         # quote or other special characters that will break the js expression.
   623         # quote or other special characters that will break the js expression.
   616         extraparams.setdefault('fname', 'view')
   624         extraparams.setdefault('fname', 'view')
   617         url = self.build_url('json', **extraparams)
   625         url = self.build_url('json', **extraparams)
   618         cbname = build_cb_uid(url[:50])
   626         cbname = build_cb_uid(url[:50])
   619         # think to propagate pageid. XXX see https://www.cubicweb.org/ticket/1753121
   627         # think to propagate pageid. XXX see https://www.cubicweb.org/ticket/1753121
   620         jscode = 'function %s() { $("#%s").%s; }' % (
   628         jscode = u'function %s() { $("#%s").%s; }' % (
   621             cbname, nodeid, js.loadxhtml(url, {'pageid': self.pageid},
   629             cbname, nodeid, js.loadxhtml(url, {'pageid': self.pageid},
   622                                          'get', replacemode))
   630                                          'get', replacemode))
   623         self.html_headers.add_post_inline_script(jscode)
   631         self.html_headers.add_post_inline_script(jscode)
   624         return "javascript: %s()" % cbname
   632         return "javascript: %s()" % cbname
   625 
   633 
   626     # urls/path management ####################################################
   634     # urls/path management ####################################################
       
   635 
       
   636     def build_url(self, *args, **kwargs):
       
   637         """return an absolute URL using params dictionary key/values as URL
       
   638         parameters. Values are automatically URL quoted, and the
       
   639         publishing method to use may be specified or will be guessed.
       
   640         """
       
   641         if '__message' in kwargs:
       
   642             msg = kwargs.pop('__message')
       
   643             kwargs['_cwmsgid'] = self.set_redirect_message(msg)
       
   644         return super(CubicWebRequestBase, self).build_url(*args, **kwargs)
   627 
   645 
   628     def url(self, includeparams=True):
   646     def url(self, includeparams=True):
   629         """return currently accessed url"""
   647         """return currently accessed url"""
   630         return self.base_url() + self.relative_path(includeparams)
   648         return self.base_url() + self.relative_path(includeparams)
   631 
   649 
   888     return 1./score, value
   906     return 1./score, value
   889 
   907 
   890 def _parse_accept_header(raw_header, value_parser=None, value_sort_key=None):
   908 def _parse_accept_header(raw_header, value_parser=None, value_sort_key=None):
   891     """returns an ordered list accepted types
   909     """returns an ordered list accepted types
   892 
   910 
   893     returned value is a list of 2-tuple (value, score), ordered
   911     :param value_parser: a function to parse a raw accept chunk. If None
   894     by score. Exact type of `value` will depend on what `value_parser`
   912     is provided, the function defaults to identity. If a function is provided,
   895     will reutrn. if `value_parser` is None, then the raw value, as found
   913     it must accept 2 parameters ``value`` and ``other_params``. ``value`` is
   896     in the http header, is used.
   914     the value found before the first ';', `other_params` is a dictionary
       
   915     built from all other chunks after this first ';'
       
   916 
       
   917     :param value_sort_key: a key function to sort values found in the accept
       
   918     header. This function will be passed a 3-tuple
       
   919     (raw_value, parsed_value, score). If None is provided, the default
       
   920     sort_key is 1./score
       
   921 
       
   922     :return: a list of 3-tuple (raw_value, parsed_value, score),
       
   923     ordered by score. ``parsed_value`` will be the return value of
       
   924     ``value_parser(raw_value)``
   897     """
   925     """
   898     if value_sort_key is None:
   926     if value_sort_key is None:
   899         value_sort_key = lambda infos: 1./infos[-1]
   927         value_sort_key = lambda infos: 1./infos[-1]
   900     values = []
   928     values = []
   901     for info in raw_header.split(','):
   929     for info in raw_header.split(','):
   926     (type, subtype, type_params) corresponding to the mimetype definition
   954     (type, subtype, type_params) corresponding to the mimetype definition
   927     e.g. : for 'text/*', `mimetypeinfo` will be ('text', '*', {}), for
   955     e.g. : for 'text/*', `mimetypeinfo` will be ('text', '*', {}), for
   928     'text/html;level=1', `mimetypeinfo` will be ('text', '*', {'level': '1'})
   956     'text/html;level=1', `mimetypeinfo` will be ('text', '*', {'level': '1'})
   929     """
   957     """
   930     try:
   958     try:
   931         media_type, media_subtype = value.strip().split('/')
   959         media_type, media_subtype = value.strip().split('/', 1)
   932     except ValueError: # safety belt : '/' should always be present
   960     except ValueError: # safety belt : '/' should always be present
   933         media_type = value.strip()
   961         media_type = value.strip()
   934         media_subtype = '*'
   962         media_subtype = '*'
   935     return (media_type, media_subtype, other_params)
   963     return (media_type, media_subtype, other_params)
   936 
   964