Drop most deprecated code in cubicweb.web
authorDenis Laxalde <denis.laxalde@logilab.fr>
Thu, 14 Mar 2019 14:43:18 +0100
changeset 12503 b01dd0ef43aa
parent 12502 e651d5f24cb5
child 12504 362fdb399ff5
Drop most deprecated code in cubicweb.web This includes both Python and JavaScript code. Most code has been deprecated since a very long time (versions 3.1x mostly, more than 5 years ago, and a few things until 3.24). There are still a few deprecated things, most of which are actually used within cubicweb (or in cubes we depend on for tests). I don't know what to do with these... Removed a couple of unused imports along the way. Changelog entry will come in a later changeset.
cubicweb/web/__init__.py
cubicweb/web/application.py
cubicweb/web/box.py
cubicweb/web/controller.py
cubicweb/web/data/cubicweb.ajax.js
cubicweb/web/data/cubicweb.compat.js
cubicweb/web/data/cubicweb.htmlhelpers.js
cubicweb/web/data/cubicweb.js
cubicweb/web/facet.py
cubicweb/web/form.py
cubicweb/web/request.py
cubicweb/web/test/unittest_application.py
cubicweb/web/test/unittest_views_basecontrollers.py
cubicweb/web/views/__init__.py
cubicweb/web/views/ajaxcontroller.py
cubicweb/web/views/basecontrollers.py
cubicweb/web/views/baseviews.py
cubicweb/web/views/boxes.py
cubicweb/web/views/editforms.py
cubicweb/web/views/facets.py
cubicweb/web/views/idownloadable.py
cubicweb/web/views/navigation.py
cubicweb/web/views/plots.py
cubicweb/web/views/primary.py
cubicweb/web/views/reledit.py
cubicweb/web/views/startup.py
cubicweb/web/views/tableview.py
cubicweb/web/views/treeview.py
cubicweb/web/views/workflow.py
cubicweb/web/webconfig.py
--- a/cubicweb/web/__init__.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/__init__.py	Thu Mar 14 14:43:18 2019 +0100
@@ -23,7 +23,6 @@
 from cubicweb import _
 
 from six.moves.urllib.parse import quote as urlquote
-from logilab.common.deprecation import deprecated
 
 from cubicweb.web._exceptions import *
 from cubicweb.utils import json_dumps
--- a/cubicweb/web/application.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/application.py	Thu Mar 14 14:43:18 2019 +0100
@@ -19,14 +19,13 @@
 
 
 import contextlib
-from functools import wraps
 import json
 import sys
 from time import clock, time
 from contextlib import contextmanager
 from warnings import warn
 
-from six import PY2, text_type, binary_type
+from six import text_type, binary_type
 from six.moves import http_client
 
 from rql import BadRQLQuery
@@ -40,40 +39,12 @@
 from cubicweb.web import (
     LOGGER, StatusResponse, DirectResponse, Redirect, NotFound, LogOut,
     RemoteCallFailed, InvalidSession, RequestError, PublishException)
-from cubicweb.web.request import CubicWebRequestBase
 
 # make session manager available through a global variable so the debug view can
 # print information about web session
 SESSION_MANAGER = None
 
 
-def _deprecated_path_arg(func):
-    @wraps(func)
-    def wrapper(self, req, *args, **kwargs):
-        if args or 'path' in kwargs:
-            func_name = func.func_name if PY2 else func.__name__
-            warn('[3.24] path argument got removed from "%s" parameters' % func_name,
-                 DeprecationWarning)
-            path = args[0] if args else kwargs['path']
-            assert path == req.relative_path(False), \
-                'mismatching path, {0} vs {1}'.format(path, req.relative_path(False))
-        return func(self, req)
-    return wrapper
-
-
-def _deprecated_req_path_swapped(func):
-    @wraps(func)
-    def wrapper(self, req, *args, **kwargs):
-        if not isinstance(req, CubicWebRequestBase):
-            warn('[3.15] Application entry point arguments are now (req, path) '
-                 'not (path, req)', DeprecationWarning, 2)
-            path = req
-            req = args[0] if args else kwargs.pop('req')
-            args = (path, ) + args[1:]
-        return func(self, req, *args, **kwargs)
-    return wrapper
-
-
 @contextmanager
 def anonymized_request(req):
     from cubicweb.web.views.authentication import Session
@@ -227,7 +198,6 @@
 
     # publish methods #########################################################
 
-    @_deprecated_path_arg
     def log_handle_request(self, req):
         """wrapper around _publish to log all queries executed for a given
         accessed path
@@ -273,8 +243,6 @@
                     except Exception:
                         self.exception('error while logging queries')
 
-    @_deprecated_req_path_swapped
-    @_deprecated_path_arg
     def main_handle_request(self, req):
         """Process an HTTP request `req`
 
@@ -352,7 +320,6 @@
         assert isinstance(content, binary_type)
         return content
 
-    @_deprecated_path_arg
     def core_handle(self, req):
         """method called by the main publisher to process <req> relative path
 
--- a/cubicweb/web/box.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/box.py	Thu Mar 14 14:43:18 2019 +0100
@@ -23,7 +23,7 @@
 from six import add_metaclass
 
 from logilab.mtconverter import xml_escape
-from logilab.common.deprecation import class_deprecated, class_renamed
+from logilab.common.deprecation import class_deprecated
 
 from cubicweb import Unauthorized, role as get_role
 from cubicweb.schema import display_name
@@ -33,7 +33,6 @@
                                       RawBoxItem)
 from cubicweb.web.action import UnregisteredAction
 from cubicweb.web.component import (
-    AjaxEditRelationCtxComponent,
     EditRelationMixIn,
     Separator,
 )
@@ -195,8 +194,3 @@
         label = super(EditRelationBoxTemplate, self).box_item(
             entity, etarget, rql, label)
         return RawBoxItem(label, liclass=u'invisible')
-
-
-AjaxEditRelationBoxTemplate = class_renamed(
-    'AjaxEditRelationBoxTemplate', AjaxEditRelationCtxComponent,
-    '[3.10] AjaxEditRelationBoxTemplate has been renamed to AjaxEditRelationCtxComponent (%(cls)s)')
--- a/cubicweb/web/controller.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/controller.py	Thu Mar 14 14:43:18 2019 +0100
@@ -23,7 +23,6 @@
 
 from logilab.mtconverter import xml_escape
 from logilab.common.registry import yes
-from logilab.common.deprecation import deprecated
 
 from cubicweb.appobject import AppObject
 from cubicweb.mail import format_mail
@@ -106,12 +105,6 @@
         if not self._edited_entity:
             self._edited_entity = entity
 
-    @deprecated('[3.18] call view.set_http_cache_headers then '
-                '.is_client_cache_valid() method and return instead')
-    def validate_cache(self, view):
-        view.set_http_cache_headers()
-        self._cw.validate_cache()
-
     def sendmail(self, recipient, subject, body):
         senderemail = self._cw.user.cw_adapt_to('IEmailable').get_email()
         msg = format_mail({'email' : senderemail,
--- a/cubicweb/web/data/cubicweb.ajax.js	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/data/cubicweb.ajax.js	Thu Mar 14 14:43:18 2019 +0100
@@ -473,19 +473,8 @@
         }
         // else: rebuild full url by fetching cubicweb:rql, cubicweb:vid, etc.
         var rql = $fragment.attr('cubicweb:rql');
-        var items = $fragment.attr('cubicweb:vid').split('&');
-        var vid = items[0];
+        var vid = $fragment.attr('cubicweb:vid');
         var extraparams = {};
-        // case where vid='myvid&param1=val1&param2=val2': this is a deprecated abuse-case
-        if (items.length > 1) {
-            cw.log("[3.5] you're using extraargs in cubicweb:vid " +
-                   "attribute, this is deprecated, consider using " +
-                   "loadurl instead");
-            for (var j = 1; j < items.length; j++) {
-                var keyvalue = items[j].split('=');
-                extraparams[keyvalue[0]] = keyvalue[1];
-            }
-        }
         var actrql = $fragment.attr('cubicweb:actualrql');
         if (actrql) {
             extraparams['actualrql'] = actrql;
@@ -679,23 +668,6 @@
     jQuery('#lazy-' + divid).trigger('load_' + divid);
 }
 
-/* DEPRECATED *****************************************************************/
-
-// still used in cwo and keyword cubes at least
-reloadComponent = cw.utils.deprecatedFunction(
-    '[3.9] reloadComponent() is deprecated, use loadxhtml instead',
-    function(compid, rql, registry, nodeid, extraargs) {
-        registry = registry || 'components';
-        rql = rql || '';
-        nodeid = nodeid || (compid + 'Component');
-        extraargs = extraargs || {};
-        var node = cw.jqNode(nodeid);
-        return node.loadxhtml(AJAX_BASE_URL, ajaxFuncArgs('component', null, compid,
-                                                          rql, registry, extraargs));
-    }
-);
-
-
 function remoteExec(fname /* ... */) {
     setProgressCursor();
     var props = {
--- a/cubicweb/web/data/cubicweb.compat.js	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/data/cubicweb.compat.js	Thu Mar 14 14:43:18 2019 +0100
@@ -18,12 +18,3 @@
     }
     return result;
 }
-
-
-// skm cube still uses this
-getNodeAttribute = cw.utils.deprecatedFunction(
-    '[3.9] getNodeAttribute(node, attr) is deprecated, use $(node).attr(attr)',
-    function(node, attribute) {
-        return $(node).attr(attribute);
-    }
-);
--- a/cubicweb/web/data/cubicweb.htmlhelpers.js	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/data/cubicweb.htmlhelpers.js	Thu Mar 14 14:43:18 2019 +0100
@@ -10,17 +10,6 @@
 
 
 /**
- * .. function:: baseuri()
- *
- * returns the document's baseURI.
- */
-baseuri = cw.utils.deprecatedFunction(
-    "[3.20] baseuri() is deprecated, use BASE_URL instead",
-    function () {
-        return BASE_URL;
-    });
-
-/**
  * .. function:: setProgressCursor()
  *
  * set body's cursor to 'progress'
--- a/cubicweb/web/data/cubicweb.js	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/data/cubicweb.js	Thu Mar 14 14:43:18 2019 +0100
@@ -426,15 +426,6 @@
 // backward compat
 CubicWeb = cw;
 
-jQuery.extend(cw, {
-    require: cw.utils.deprecatedFunction(
-        '[3.9] CubicWeb.require() is not used anymore',
-        function(module) {}),
-    provide: cw.utils.deprecatedFunction(
-        '[3.9] CubicWeb.provide() is not used anymore',
-        function(module) {})
-});
-
 jQuery(document).ready(function() {
     $(cw).trigger('server-response', [false, document]);
 });
--- a/cubicweb/web/facet.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/facet.py	Thu Mar 14 14:43:18 2019 +0100
@@ -63,7 +63,6 @@
 from logilab.common.graph import has_path
 from logilab.common.decorators import cached, cachedproperty
 from logilab.common.date import datetime2ticks, ustrftime, ticks2datetime
-from logilab.common.deprecation import deprecated
 from logilab.common.registry import yes
 
 from rql import nodes, utils
@@ -89,12 +88,6 @@
     return req.vreg['facets'].object_by_id(facetid, req, select=select,
                                            filtered_variable=filtered_variable)
 
-@deprecated('[3.13] filter_hiddens moved to cubicweb.web.views.facets with '
-            'slightly modified prototype')
-def filter_hiddens(w, baserql, **kwargs):
-    from cubicweb.web.views.facets import filter_hiddens
-    return filter_hiddens(w, baserql, wdgs=kwargs.pop('facets'), **kwargs)
-
 
 ## rqlst manipulation functions used by facets ################################
 
@@ -164,15 +157,6 @@
     # global tree config: DISTINCT, LIMIT, OFFSET
     select.set_distinct(True)
 
-@deprecated('[3.13] use init_facets instead')
-def prepare_facets_rqlst(rqlst, args=None):
-    assert len(rqlst.children) == 1, 'FIXME: union not yet supported'
-    select = rqlst.children[0]
-    filtered_variable = get_filtered_variable(select)
-    baserql = select.as_string(args)
-    prepare_select(select, filtered_variable)
-    return filtered_variable, baserql
-
 def prepare_vocabulary_select(select, filtered_variable, rtype, role,
                               select_target_entity=True):
     """prepare a syntax tree to generate a filter vocabulary rql using the given
@@ -370,11 +354,6 @@
         return var
 
 
-_prepare_vocabulary_rqlst = deprecated('[3.13] renamed prepare_vocabulary_select')(
-    prepare_vocabulary_select)
-_cleanup_rqlst = deprecated('[3.13] renamed to cleanup_select')(cleanup_select)
-
-
 ## base facet classes ##########################################################
 
 class AbstractFacet(AppObject):
@@ -479,11 +458,6 @@
     def wdgclass(self):
         raise NotImplementedError
 
-    @property
-    @deprecated('[3.13] renamed .select')
-    def rqlst(self):
-        return self.select
-
 
 class VocabularyFacet(AbstractFacet):
     """This abstract class extend :class:`AbstractFacet` to use the
--- a/cubicweb/web/form.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/form.py	Thu Mar 14 14:43:18 2019 +0100
@@ -23,7 +23,6 @@
 from six import add_metaclass
 
 from logilab.common.decorators import iclassmethod
-from logilab.common.deprecation import deprecated
 
 from cubicweb.appobject import AppObject
 from cubicweb.view import NOINDEX, NOFOLLOW
--- a/cubicweb/web/request.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/request.py	Thu Mar 14 14:43:18 2019 +0100
@@ -34,7 +34,6 @@
 from rql.utils import rqlvar_maker
 
 from logilab.common.decorators import cached
-from logilab.common.deprecation import deprecated
 
 from cubicweb import AuthenticationError
 from cubicweb.req import RequestSessionBase
@@ -162,16 +161,6 @@
             self.html_headers.define_var('pageid', pid, override=False)
         self.pageid = pid
 
-    def _get_json_request(self):
-        warn('[3.15] self._cw.json_request is deprecated, use self._cw.ajax_request instead',
-             DeprecationWarning, stacklevel=2)
-        return self.ajax_request
-    def _set_json_request(self, value):
-        warn('[3.15] self._cw.json_request is deprecated, use self._cw.ajax_request instead',
-             DeprecationWarning, stacklevel=2)
-        self.ajax_request = value
-    json_request = property(_get_json_request, _set_json_request)
-
     @property
     def authmode(self):
         """Authentification mode of the instance
@@ -696,15 +685,6 @@
         # XXX replace by False once validate_cache bw compat method is dropped
         return None
 
-    @deprecated('[3.18] use .is_client_cache_valid() method instead')
-    def validate_cache(self):
-        """raise a `StatusResponse` exception if a cached page along the way
-        exists and is still usable.
-        """
-        status_code = self.is_client_cache_valid()
-        if status_code is not None:
-            raise StatusResponse(status_code)
-
     # abstract methods to override according to the web front-end #############
 
     def http_method(self):
@@ -812,26 +792,13 @@
         values = _parse_accept_header(accepteds, value_parser, value_sort_key)
         return (raw_value for (raw_value, parsed_value, score) in values)
 
-    @deprecated('[3.17] demote_to_html is deprecated as we always serve html')
-    def demote_to_html(self):
-        """helper method to dynamically set request content type to text/html
-
-        The global doctype and xmldec must also be changed otherwise the browser
-        will display '<[' at the beginning of the page
-        """
-        pass
-
-
     # xml doctype #############################################################
 
-    def set_doctype(self, doctype, reset_xmldecl=None):
+    def set_doctype(self, doctype):
         """helper method to dynamically change page doctype
 
         :param doctype: the new doctype, e.g. '<!DOCTYPE html>'
         """
-        if reset_xmldecl is not None:
-            warn('[3.17] reset_xmldecl is deprecated as we only serve html',
-                 DeprecationWarning, stacklevel=2)
         self.main_stream.set_doctype(doctype)
 
     # page data management ####################################################
@@ -878,16 +845,6 @@
         useragent = self.useragent()
         return useragent and 'MSIE' in useragent
 
-    @deprecated('[3.17] xhtml_browser is deprecated (xhtml is no longer served)')
-    def xhtml_browser(self):
-        """return True if the browser is considered as xhtml compatible.
-
-        If the instance is configured to always return text/html and not
-        application/xhtml+xml, this method will always return False, even though
-        this is semantically different
-        """
-        return False
-
     def html_content_type(self):
         return 'text/html'
 
--- a/cubicweb/web/test/unittest_application.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/test/unittest_application.py	Thu Mar 14 14:43:18 2019 +0100
@@ -760,18 +760,6 @@
             req.form['rql'] = 'rql:Any OV1, X WHERE X custom_workflow OV1?'
             self.app_handle_request(req)
 
-    def test_handle_deprecation(self):
-        """Test deprecation warning for *_handle methods."""
-        with self.admin_access.web_request(url='foo') as req:
-            with self.assertWarns(DeprecationWarning) as cm:
-                self.app.core_handle(req, 'foo')
-            self.assertIn('path argument got removed from "core_handle"',
-                          str(cm.warning))
-            with self.assertWarns(DeprecationWarning) as cm:
-                self.app.main_handle_request('foo', req)
-            self.assertIn('entry point arguments are now (req, path)',
-                          str(cm.warning))
-
 
 if __name__ == '__main__':
     unittest_main()
--- a/cubicweb/web/test/unittest_views_basecontrollers.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/test/unittest_views_basecontrollers.py	Thu Mar 14 14:43:18 2019 +0100
@@ -25,7 +25,6 @@
 import lxml
 
 from logilab.common.testlib import unittest_main
-from logilab.common.decorators import monkeypatch
 
 from cubicweb import Binary, NoSelectableObject, ValidationError, transaction as tx
 from cubicweb.schema import RRQLExpression
@@ -37,7 +36,6 @@
 from cubicweb.uilib import rql_for_eid
 from cubicweb.web import Redirect, RemoteCallFailed, http_headers, formfields as ff
 from cubicweb.web.views.autoform import get_pending_inserts, get_pending_deletes
-from cubicweb.web.views.basecontrollers import JSonController, xhtmlize, jsonize
 from cubicweb.web.views.ajaxcontroller import ajaxfunc, AjaxFunction
 from cubicweb.server.session import Connection
 from cubicweb.server.hook import Hook, Operation
@@ -760,8 +758,8 @@
         with self.admin_access.web_request(url='edit') as req:
             p = self.create_user(req, u"doe")
             # do not try to skip 'primary_email' for this test
-            old_skips = p.__class__.skip_copy_for
-            p.__class__.skip_copy_for = ()
+            old_skips = p.__class__.cw_skip_copy_for
+            p.__class__.cw_skip_copy_for = ()
             try:
                 e = req.create_entity('EmailAddress', address=u'doe@doe.com')
                 req.execute('SET P use_email E, P primary_email E WHERE P eid %(p)s, E eid %(e)s',
@@ -786,7 +784,7 @@
                 rset = req.execute('CWUser P WHERE P surname "Boom"')
                 self.assertEqual(len(rset), 0)
             finally:
-                p.__class__.skip_copy_for = old_skips
+                p.__class__.cw_skip_copy_for = old_skips
 
     def test_regr_inlined_forms(self):
         with self.admin_access.web_request() as req:
@@ -1020,64 +1018,6 @@
         self.assertEqual(cm.exception.reason, 'no foo method')
 
 
-class JSonControllerTC(AjaxControllerTC):
-    # NOTE: this class performs the same tests as AjaxController but with
-    #       deprecated 'json' controller (i.e. check backward compatibility)
-    tested_controller = 'json'
-
-    def setUp(self):
-        super(JSonControllerTC, self).setUp()
-        self.exposed_remote_funcs = [fname for fname in dir(JSonController)
-                                     if fname.startswith('js_')]
-
-    def tearDown(self):
-        super(JSonControllerTC, self).tearDown()
-        for funcname in dir(JSonController):
-            # remove functions added dynamically during tests
-            if funcname.startswith('js_') and funcname not in self.exposed_remote_funcs:
-                delattr(JSonController, funcname)
-
-    def test_monkeypatch_jsoncontroller(self):
-        with self.assertRaises(RemoteCallFailed):
-            with self.remote_calling('foo'):
-                pass
-        @monkeypatch(JSonController)
-        def js_foo(self):
-            return u'hello'
-        with self.remote_calling('foo') as (res, _):
-            self.assertEqual(res, b'hello')
-
-    def test_monkeypatch_jsoncontroller_xhtmlize(self):
-        with self.assertRaises(RemoteCallFailed):
-            with self.remote_calling('foo'):
-                pass
-        @monkeypatch(JSonController)
-        @xhtmlize
-        def js_foo(self):
-            return u'hello'
-        with self.remote_calling('foo') as (res, _):
-            self.assertEqual(b'<div>hello</div>', res)
-
-    def test_monkeypatch_jsoncontroller_jsonize(self):
-        with self.assertRaises(RemoteCallFailed):
-            with self.remote_calling('foo'):
-                pass
-        @monkeypatch(JSonController)
-        @jsonize
-        def js_foo(self):
-            return 12
-        with self.remote_calling('foo') as (res, _):
-            self.assertEqual(res, b'12')
-
-    def test_monkeypatch_jsoncontroller_stdfunc(self):
-        @monkeypatch(JSonController)
-        @jsonize
-        def js_reledit_form(self):
-            return 12
-        with self.remote_calling('reledit_form') as (res, _):
-            self.assertEqual(res, b'12')
-
-
 class UndoControllerTC(CubicWebTC):
 
     def setUp(self):
--- a/cubicweb/web/views/__init__.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/__init__.py	Thu Mar 14 14:43:18 2019 +0100
@@ -19,15 +19,10 @@
 
 
 
-import os
 import sys
-import tempfile
-
-from six import add_metaclass
 
 from rql import nodes
 from logilab.mtconverter import xml_escape
-from logilab.common.deprecation import class_deprecated
 
 
 def need_table_view(rset, schema):
@@ -126,23 +121,3 @@
         return u'<a href="%s" class="%s">%s</a>' % (
             xml_escape(url), csscls, req.__('New %s' % etype))
     return u''
-
-
-
-@add_metaclass(class_deprecated)
-class TmpFileViewMixin(object):
-    __deprecation_warning__ = '[3.18] %(cls)s is deprecated'
-    binary = True
-    content_type = 'application/octet-stream'
-    cache_max_age = 60*60*2 # stay in http cache for 2 hours by default
-
-    def call(self):
-        self.cell_call()
-
-    def cell_call(self, row=0, col=0):
-        self.cw_row, self.cw_col = row, col # in case one needs it
-        fd, tmpfile = tempfile.mkstemp('.png')
-        os.close(fd)
-        self._generate(tmpfile)
-        self.w(open(tmpfile, 'rb').read())
-        os.unlink(tmpfile)
--- a/cubicweb/web/views/ajaxcontroller.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/ajaxcontroller.py	Thu Mar 14 14:43:18 2019 +0100
@@ -71,7 +71,6 @@
 
 from logilab.common.date import strptime
 from logilab.common.registry import yes
-from logilab.common.deprecation import deprecated
 
 from cubicweb import ObjectNotFound, NoSelectableObject, ValidationError
 from cubicweb.appobject import AppObject
@@ -444,16 +443,6 @@
     """remove user's session data associated to current pageid"""
     self._cw.session.data.pop(self._cw.pageid, None)
 
-@ajaxfunc(output_type='json')
-@deprecated("[3.13] use jQuery.cookie(cookiename, cookievalue, {path: '/'}) in js land instead")
-def set_cookie(self, cookiename, cookievalue):
-    """generates the Set-Cookie HTTP reponse header corresponding
-    to `cookiename` / `cookievalue`.
-    """
-    cookiename, cookievalue = str(cookiename), str(cookievalue)
-    self._cw.set_cookie(cookiename, cookievalue)
-
-
 
 @ajaxfunc
 def delete_relation(self, rtype, subjeid, objeid):
--- a/cubicweb/web/views/basecontrollers.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/basecontrollers.py	Thu Mar 14 14:43:18 2019 +0100
@@ -19,60 +19,18 @@
 object to handle publication.
 """
 
-
-from cubicweb import _
-
-from warnings import warn
-
 from six import text_type
 from six.moves import http_client
 
-from logilab.common.deprecation import deprecated
-
 from cubicweb import (NoSelectableObject, ObjectNotFound, ValidationError,
                       AuthenticationError, UndoTransactionException,
                       Forbidden)
 from cubicweb.utils import json_dumps
 from cubicweb.predicates import (authenticated_user, anonymous_user,
                                 match_form_params)
-from cubicweb.web import Redirect, RemoteCallFailed
-from cubicweb.web.controller import Controller, append_url_params
+from cubicweb.web import Redirect
+from cubicweb.web.controller import Controller
 from cubicweb.web.views import vid_from_rset
-import cubicweb.transaction as tx
-
-@deprecated('[3.15] jsonize is deprecated, use AjaxFunction appobjects instead')
-def jsonize(func):
-    """decorator to sets correct content_type and calls `json_dumps` on
-    results
-    """
-    def wrapper(self, *args, **kwargs):
-        self._cw.set_content_type('application/json')
-        return json_dumps(func(self, *args, **kwargs))
-    wrapper.__name__ = func.__name__
-    return wrapper
-
-@deprecated('[3.15] xhtmlize is deprecated, use AjaxFunction appobjects instead')
-def xhtmlize(func):
-    """decorator to sets correct content_type and calls `xmlize` on results"""
-    def wrapper(self, *args, **kwargs):
-        self._cw.set_content_type(self._cw.html_content_type())
-        result = func(self, *args, **kwargs)
-        return ''.join((u'<div>', result.strip(),
-                        u'</div>'))
-    wrapper.__name__ = func.__name__
-    return wrapper
-
-@deprecated('[3.15] check_pageid is deprecated, use AjaxFunction appobjects instead')
-def check_pageid(func):
-    """decorator which checks the given pageid is found in the
-    user's session data
-    """
-    def wrapper(self, *args, **kwargs):
-        data = self._cw.session.data.get(self._cw.pageid)
-        if data is None:
-            raise RemoteCallFailed(self._cw._('pageid-not-found'))
-        return func(self, *args, **kwargs)
-    return wrapper
 
 
 class LoginController(Controller):
@@ -255,16 +213,6 @@
         return self.response(domid, status, args, entity).encode(self._cw.encoding)
 
 
-class JSonController(Controller):
-    __regid__ = 'json'
-
-    def publish(self, rset=None):
-        warn('[3.15] JSONController is deprecated, use AjaxController instead',
-             DeprecationWarning)
-        ajax_controller = self._cw.vreg['controllers'].select('ajax', self._cw, appli=self.appli)
-        return ajax_controller.publish(rset)
-
-
 class MailBugReportController(Controller):
     __regid__ = 'reportbug'
     __select__ = match_form_params('description')
--- a/cubicweb/web/views/baseviews.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/baseviews.py	Thu Mar 14 14:43:18 2019 +0100
@@ -626,18 +626,3 @@
         url = self.index_url(basepath, key[1], vtitle=vtitle)
         title = self._cw._('archive for %(author)s') % {'author': key[0]}
         return tags.a(label, href=url, title=title)
-
-
-# bw compat ####################################################################
-
-from logilab.common.deprecation import class_moved, class_deprecated
-
-from cubicweb.web.views import boxes, xmlrss, primary, tableview
-PrimaryView = class_moved(primary.PrimaryView)
-SideBoxView = class_moved(boxes.SideBoxView)
-XmlView = class_moved(xmlrss.XMLView)
-XmlItemView = class_moved(xmlrss.XMLItemView)
-XmlRsetView = class_moved(xmlrss.XMLRsetView)
-RssView = class_moved(xmlrss.RSSView)
-RssItemView = class_moved(xmlrss.RSSItemView)
-TableView = class_moved(tableview.TableView)
--- a/cubicweb/web/views/boxes.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/boxes.py	Thu Mar 14 14:43:18 2019 +0100
@@ -28,12 +28,9 @@
 
 from cubicweb import _
 
-from warnings import warn
-
 from six import text_type, add_metaclass
 
 from logilab.mtconverter import xml_escape
-from logilab.common.deprecation import class_deprecated
 
 from cubicweb import Unauthorized
 from cubicweb.predicates import (match_user_groups, match_kwargs,
@@ -230,28 +227,6 @@
 
  # helper classes ##############################################################
 
-@add_metaclass(class_deprecated)
-class SideBoxView(EntityView):
-    """helper view class to display some entities in a sidebox"""
-    __deprecation_warning__ = '[3.10] SideBoxView is deprecated, use RsetBox instead (%(cls)s)'
-
-    __regid__ = 'sidebox'
-
-    def call(self, title=u'', **kwargs):
-        """display a list of entities by calling their <item_vid> view"""
-        if 'dispctrl' in self.cw_extra_kwargs:
-            # XXX do not modify dispctrl!
-            self.cw_extra_kwargs['dispctrl'].setdefault('subvid', 'outofcontext')
-            self.cw_extra_kwargs['dispctrl'].setdefault('use_list_limit', 1)
-        if title:
-            self.cw_extra_kwargs['title'] = title
-        self.cw_extra_kwargs.setdefault('context', 'incontext')
-        box = self._cw.vreg['ctxcomponents'].select(
-            'rsetbox', self._cw, rset=self.cw_rset, vid='autolimited',
-            **self.cw_extra_kwargs)
-        box.render(self.w)
-
-
 class ContextualBoxLayout(component.Layout):
     __select__ = match_context('incontext', 'left', 'right') & contextual()
     # predefined class in cubicweb.css: contextualBox | contextFreeBox
--- a/cubicweb/web/views/editforms.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/editforms.py	Thu Mar 14 14:43:18 2019 +0100
@@ -26,7 +26,6 @@
 from six.moves import range
 
 from logilab.common.registry import yes
-from logilab.common.deprecation import class_moved
 
 from cubicweb import _
 from cubicweb import tags
@@ -299,9 +298,3 @@
                                              copy_nav_params=True,
                                              formvid='edition')
         form.render(w=self.w)
-
-
-# click and edit handling ('reledit') ##########################################
-
-ClickAndEditFormView = class_moved(reledit.ClickAndEditFormView)
-AutoClickAndEditFormView = class_moved(reledit.AutoClickAndEditFormView)
--- a/cubicweb/web/views/facets.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/facets.py	Thu Mar 14 14:43:18 2019 +0100
@@ -20,8 +20,6 @@
 
 from cubicweb import _
 
-from warnings import warn
-
 from logilab.mtconverter import xml_escape
 from logilab.common.decorators import cachedproperty
 from logilab.common.registry import objectify_predicate, yes
@@ -129,7 +127,7 @@
     needs_js = ['cubicweb.ajax.js', 'cubicweb.facets.js']
     needs_css = ['cubicweb.facets.css']
 
-    def generate_form(self, w, rset, divid, vid, vidargs=None, mainvar=None,
+    def generate_form(self, w, rset, divid, vid, mainvar=None,
                       paginate=False, cssclass='', hiddens=None, **kwargs):
         """display a form to filter some view's content
 
@@ -163,12 +161,7 @@
         self._cw.add_css(self.needs_css)
         self._cw.html_headers.define_var('facetLoadingMsg',
                                          self._cw._('facet-loading-msg'))
-        if vidargs is not None:
-            warn("[3.14] vidargs is deprecated. Maybe you're using some TableView?",
-                 DeprecationWarning, stacklevel=2)
-        else:
-            vidargs = {}
-        vidargs = dict((k, v) for k, v in vidargs.items() if v)
+        vidargs = {}
         facetargs = xml_escape(json_dumps([divid, vid, paginate, vidargs]))
         w(u'<form id="%sForm" class="%s" method="post" action="" '
           'cubicweb:facetargs="%s" >' % (divid, cssclass, facetargs))
--- a/cubicweb/web/views/idownloadable.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/idownloadable.py	Thu Mar 14 14:43:18 2019 +0100
@@ -25,7 +25,6 @@
 from six.moves import range
 
 from logilab.mtconverter import BINARY_ENCODINGS, TransformError, xml_escape
-from logilab.common.deprecation import class_renamed, deprecated
 
 from cubicweb import tags
 from cubicweb.view import EntityView
--- a/cubicweb/web/views/navigation.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/navigation.py	Thu Mar 14 14:43:18 2019 +0100
@@ -55,7 +55,6 @@
 from rql.nodes import VariableRef, Constant
 
 from logilab.mtconverter import xml_escape
-from logilab.common.deprecation import deprecated
 
 from cubicweb.predicates import paginated_rset, sorted_rset, adaptable
 from cubicweb.uilib import cut
--- a/cubicweb/web/views/plots.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/plots.py	Thu Mar 14 14:43:18 2019 +0100
@@ -17,18 +17,10 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """basic plot views"""
 
-
-from cubicweb import _
-
-from six import add_metaclass
-from six.moves import range
-
-from logilab.common.date import datetime2ticks
-from logilab.common.deprecation import class_deprecated
 from logilab.common.registry import objectify_predicate
 from logilab.mtconverter import xml_escape
 
-from cubicweb.utils import UStringIO, json_dumps
+from cubicweb.utils import UStringIO
 from cubicweb.predicates import multi_columns_rset
 from cubicweb.web.views import baseviews
 
@@ -87,89 +79,6 @@
         raise NotImplementedError
 
 
-@add_metaclass(class_deprecated)
-class FlotPlotWidget(PlotWidget):
-    """PlotRenderer widget using Flot"""
-    __deprecation_warning__ = '[3.14] cubicweb.web.views.plots module is deprecated, use the jqplot cube instead'
-    onload = u"""
-var fig = jQuery('#%(figid)s');
-if (fig.attr('cubicweb:type') != 'prepared-plot') {
-    %(plotdefs)s
-    jQuery.plot(jQuery('#%(figid)s'), [%(plotdata)s],
-        {points: {show: true},
-         lines: {show: true},
-         grid: {hoverable: true},
-         /*yaxis : {tickFormatter : suffixFormatter},*/
-         xaxis: {mode: %(mode)s}});
-    jQuery('#%(figid)s').data({mode: %(mode)s, dateformat: %(dateformat)s});
-    jQuery('#%(figid)s').bind('plothover', onPlotHover);
-    fig.attr('cubicweb:type','prepared-plot');
-}
-"""
-
-    def __init__(self, labels, plots, timemode=False):
-        self.labels = labels
-        self.plots = plots # list of list of couples
-        self.timemode = timemode
-
-    def dump_plot(self, plot):
-        if self.timemode:
-            plot = [(datetime2ticks(x), y) for x, y in plot]
-        return json_dumps(plot)
-
-    def _render(self, req, width=500, height=400):
-        if req.ie_browser():
-            req.add_js('excanvas.js')
-        req.add_js(('jquery.flot.js', 'cubicweb.flot.js'))
-        figid = u'figure%s' % next(req.varmaker)
-        plotdefs = []
-        plotdata = []
-        self.w(u'<div id="%s" style="width: %spx; height: %spx;"></div>' %
-               (figid, width, height))
-        for idx, (label, plot) in enumerate(zip(self.labels, self.plots)):
-            plotid = '%s_%s' % (figid, idx)
-            plotdefs.append('var %s = %s;' % (plotid, self.dump_plot(plot)))
-            # XXX ugly but required in order to not crash my demo
-            plotdata.append("{label: '%s', data: %s}" % (label.replace(u'&', u''), plotid))
-        fmt = req.property_value('ui.date-format') # XXX datetime-format
-        # XXX TODO make plot options customizable
-        req.html_headers.add_onload(self.onload %
-                                    {'plotdefs': '\n'.join(plotdefs),
-                                     'figid': figid,
-                                     'plotdata': ','.join(plotdata),
-                                     'mode': self.timemode and "'time'" or 'null',
-                                     'dateformat': '"%s"' % fmt})
-
-
-@add_metaclass(class_deprecated)
-class PlotView(baseviews.AnyRsetView):
-    __deprecation_warning__ = '[3.14] cubicweb.web.views.plots module is deprecated, use the jqplot cube instead'
-    __regid__ = 'plot'
-    title = _('generic plot')
-    __select__ = multi_columns_rset() & all_columns_are_numbers()
-    timemode = False
-    paginable = False
-
-    def call(self, width=500, height=400):
-        # prepare data
-        rqlst = self.cw_rset.syntax_tree()
-        # XXX try to make it work with unions
-        varnames = [var.name for var in rqlst.children[0].get_selected_variables()][1:]
-        abscissa = [row[0] for row in self.cw_rset]
-        plots = []
-        nbcols = len(self.cw_rset.rows[0])
-        for col in range(1, nbcols):
-            data = [row[col] for row in self.cw_rset]
-            plots.append(filterout_nulls(abscissa, data))
-        plotwidget = FlotPlotWidget(varnames, plots, timemode=self.timemode)
-        plotwidget.render(self._cw, width, height, w=self.w)
-
-
-class TimeSeriePlotView(PlotView):
-    __select__ = multi_columns_rset() & columns_are_date_then_numbers()
-    timemode = True
-
-
 try:
     from GChartWrapper import Pie, Pie3D
 except ImportError:
--- a/cubicweb/web/views/primary.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/primary.py	Thu Mar 14 14:43:18 2019 +0100
@@ -40,9 +40,6 @@
 
 from cubicweb import _
 
-from warnings import warn
-
-from logilab.common.deprecation import deprecated
 from logilab.mtconverter import xml_escape
 
 from cubicweb import Unauthorized, NoSelectableObject
--- a/cubicweb/web/views/reledit.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/reledit.py	Thu Mar 14 14:43:18 2019 +0100
@@ -23,10 +23,8 @@
 from cubicweb import _
 
 import copy
-from warnings import warn
 
 from logilab.mtconverter import xml_escape
-from logilab.common.deprecation import deprecated, class_renamed
 from logilab.common.decorators import cached
 
 from cubicweb import neg_role
@@ -390,9 +388,6 @@
         self._close_form_wrapper()
 
 
-ClickAndEditFormView = class_renamed('ClickAndEditFormView', AutoClickAndEditFormView)
-
-
 @ajaxfunc(output_type='xhtml')
 def reledit_form(self):
     req = self._cw
--- a/cubicweb/web/views/startup.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/startup.py	Thu Mar 14 14:43:18 2019 +0100
@@ -25,7 +25,6 @@
 from cubicweb import _
 
 from logilab.common.textutils import unormalize
-from logilab.common.deprecation import deprecated
 from logilab.mtconverter import xml_escape
 
 from cubicweb.view import StartupView
@@ -167,7 +166,3 @@
     """
     __regid__ = 'index'
     title = _('view_index')
-
-    @deprecated('[3.11] display_folders method is deprecated, backport it if needed')
-    def display_folders(self):
-        return 'Folder' in self._cw.vreg.schema and self._cw.execute('Any COUNT(X) WHERE X is Folder')[0][0]
--- a/cubicweb/web/views/tableview.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/tableview.py	Thu Mar 14 14:43:18 2019 +0100
@@ -1211,128 +1211,3 @@
         else:
             # XXX why do we need a fallback view here?
             self.wview(cellvid or 'final', self.cw_rset, 'null', row=row, col=col)
-
-
-class InitialTableView(TableView):
-    """same display as  table view but consider two rql queries :
-
-    * the default query (ie `rql` form parameter), which is only used to select
-      this view and to build the filter form. This query should have the same
-      structure as the actual without actual restriction (but link to
-      restriction variables) and usually with a limit for efficiency (limit set
-      to 2 is advised)
-
-    * the actual query (`actualrql` form parameter) whose results will be
-      displayed with default restrictions set
-    """
-    __regid__ = 'initialtable'
-    __select__ = nonempty_rset()
-    # should not be displayed in possible view since it expects some specific
-    # parameters
-    title = None
-
-    def call(self, title=None, subvid=None, headers=None, divid=None,
-             paginate=False, displaycols=None, displayactions=None,
-             mainindex=None):
-        """Dumps a table displaying a composite query"""
-        try:
-            actrql = self._cw.form['actualrql']
-        except KeyError:
-            actrql = self.cw_rset.printable_rql()
-        else:
-            self._cw.ensure_ro_rql(actrql)
-        displaycols = self.displaycols(displaycols, headers)
-        if displayactions is None and 'displayactions' in self._cw.form:
-            displayactions = True
-        if divid is None and 'divid' in self._cw.form:
-            divid = self._cw.form['divid']
-        self.w(u'<div class="section">')
-        if not title and 'title' in self._cw.form:
-            # pop title so it's not displayed by the table view as well
-            title = self._cw.form.pop('title')
-        if title:
-            self.w(u'<h2>%s</h2>\n' % title)
-        if mainindex is None:
-            mainindex = self.main_var_index()
-        if mainindex is not None:
-            actions = self.form_filter(divid, displaycols, displayactions,
-                                       displayfilter=True, paginate=paginate,
-                                       hidden=True)
-        else:
-            actions = ()
-        if not subvid and 'subvid' in self._cw.form:
-            subvid = self._cw.form.pop('subvid')
-        self._cw.view('table', self._cw.execute(actrql),
-                      'noresult', w=self.w, displayfilter=False, subvid=subvid,
-                      displayactions=displayactions, displaycols=displaycols,
-                      actions=actions, headers=headers, divid=divid)
-        self.w(u'</div>\n')
-
-
-class EditableInitialTableTableView(InitialTableView):
-    __regid__ = 'editable-initialtable'
-    finalview = 'editable-final'
-
-
-@add_metaclass(class_deprecated)
-class EntityAttributesTableView(EntityView):
-    """This table displays entity attributes in a table and allow to set a
-    specific method to help building cell content for each attribute as well as
-    column header.
-
-    Table will render entity cell by using the appropriate build_COLNAME_cell
-    methods if defined otherwise cell content will be entity.COLNAME.
-
-    Table will render column header using the method header_for_COLNAME if
-    defined otherwise COLNAME will be used.
-    """
-    __deprecation_warning__ = '[3.14] %(cls)s is deprecated'
-    __abstract__ = True
-    columns = ()
-    table_css = "listing"
-    css_files = ()
-
-    def call(self, columns=None):
-        if self.css_files:
-            self._cw.add_css(self.css_files)
-        _ = self._cw._
-        self.columns = columns or self.columns
-        sample = self.cw_rset.get_entity(0, 0)
-        self.w(u'<table class="%s">' % self.table_css)
-        self.table_header(sample)
-        self.w(u'<tbody>')
-        for row in range(self.cw_rset.rowcount):
-            self.cell_call(row=row, col=0)
-        self.w(u'</tbody>')
-        self.w(u'</table>')
-
-    def cell_call(self, row, col):
-        _ = self._cw._
-        entity = self.cw_rset.get_entity(row, col)
-        entity.complete()
-        infos = {}
-        for col in self.columns:
-            meth = getattr(self, 'build_%s_cell' % col, None)
-            # find the build method or try to find matching attribute
-            if meth:
-                content = meth(entity)
-            else:
-                content = entity.printable_value(col)
-            infos[col] = content
-        self.w(u"""<tr onmouseover="$(this).addClass('highlighted');"
-            onmouseout="$(this).removeClass('highlighted')">""")
-        line = u''.join(u'<td>%%(%s)s</td>' % col for col in self.columns)
-        self.w(line % infos)
-        self.w(u'</tr>\n')
-
-    def table_header(self, sample):
-        """builds the table's header"""
-        self.w(u'<thead><tr>')
-        for column in self.columns:
-            meth = getattr(self, 'header_for_%s' % column, None)
-            if meth:
-                colname = meth(sample)
-            else:
-                colname = self._cw._(column)
-            self.w(u'<th>%s</th>' % xml_escape(colname))
-        self.w(u'</tr></thead>\n')
--- a/cubicweb/web/views/treeview.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/treeview.py	Thu Mar 14 14:43:18 2019 +0100
@@ -22,8 +22,6 @@
 
 from cubicweb import _
 
-from warnings import warn
-
 from logilab.mtconverter import xml_escape
 
 from cubicweb.utils import make_uid, json
@@ -150,11 +148,7 @@
 jQuery("#tree-%s").treeview({toggle: toggleTree, prerendered: true});""" % treeid)
 
     def call(self, subvid=None, treeid=None,
-             initial_load=True, initial_thru_ajax=None, **morekwargs):
-        if initial_thru_ajax is not None:
-            msg = '[3.24] initial_thru_ajax argument is deprecated'
-            warn(msg, DeprecationWarning, stacklevel=2)
-
+             initial_load=True, **morekwargs):
         subvid, treeid = self._init_params(subvid, treeid,
                                            initial_load, morekwargs)
         ulid = ' '
--- a/cubicweb/web/views/workflow.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/views/workflow.py	Thu Mar 14 14:43:18 2019 +0100
@@ -24,12 +24,9 @@
 
 from cubicweb import _
 
-import os
-
-from six import add_metaclass, text_type
+from six import text_type
 
 from logilab.mtconverter import xml_escape
-from logilab.common.deprecation import class_deprecated
 
 from cubicweb import Unauthorized
 from cubicweb.predicates import (one_line_rset,
@@ -38,7 +35,6 @@
 from cubicweb.view import EntityView
 from cubicweb.web import stdmsgs, action, component, form
 from cubicweb.web import formwidgets as fwdgs
-from cubicweb.web.views import TmpFileViewMixin
 from cubicweb.web.views import uicfg, forms, ibreadcrumbs
 from cubicweb.web.views.tabs import TabbedPrimaryView, PrimaryTab
 from cubicweb.web.views.dotgraphview import DotGraphView, DotPropsHandler
@@ -444,24 +440,3 @@
 
     def build_dotpropshandler(self):
         return WorkflowDotPropsHandler(self._cw)
-
-
-@add_metaclass(class_deprecated)
-class TmpPngView(TmpFileViewMixin, EntityView):
-    __deprecation_warning__ = '[3.18] %(cls)s is deprecated'
-    __regid__ = 'tmppng'
-    __select__ = match_form_params('tmpfile')
-    content_type = 'image/png'
-    binary = True
-
-    def cell_call(self, row=0, col=0):
-        key = self._cw.form['tmpfile']
-        if key not in self._cw.session.data:
-            # the temp file is gone and there's nothing
-            # we can do about it
-            # we should probably write it to some well
-            # behaved place and serve it
-            return
-        tmpfile = self._cw.session.data.pop(key)
-        self.w(open(tmpfile, 'rb').read())
-        os.unlink(tmpfile)
--- a/cubicweb/web/webconfig.py	Wed Mar 13 13:37:49 2019 +0100
+++ b/cubicweb/web/webconfig.py	Thu Mar 14 14:43:18 2019 +0100
@@ -29,7 +29,6 @@
 from six import text_type
 
 from logilab.common.decorators import cached, cachedproperty
-from logilab.common.deprecation import deprecated
 from logilab.common.configuration import merge_options
 
 from cubicweb import ConfigurationError
@@ -292,10 +291,6 @@
                 continue
             yield key, pdef
 
-    @deprecated('[3.22] call req.cnx.repo.get_versions() directly')
-    def vc_config(self):
-        return self.repository().get_versions()
-
     @cachedproperty
     def _instance_salt(self):
         """This random key/salt is used to sign content to be sent back by