Products.CMFPlone/plip-1486-redirection: Implement prefix based filtering for managing existing alias

Stephan Klinger <jenkins-z4DKO/[email protected]>
Newsgroups gmane.comp.web.zope.plone.cvs
Message-ID <[email protected]>
Repository: Products.CMFPlone
Branch: refs/heads/plip-1486-redirection
Date: 2017-07-10T09:31:40+03:00
Author: Asko Soukka (datakurre) <[email protected]>
Commit: https://github.com/plone/Products.CMFPlone/commit/77f9df72296fd9f28d478807f2268fed49758e0f

Implement prefix based filtering for managing existing aliases

Files changed:
M Products/CMFPlone/controlpanel/browser/redirects-controlpanel.pt
M Products/CMFPlone/controlpanel/browser/redirects.py
M Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_redirection.py

diff --git a/Products/CMFPlone/controlpanel/browser/redirects-controlpanel.pt b/Products/CMFPlone/controlpanel/browser/redirects-controlpanel.pt
index 87cd59d5b..162c5b403 100644
--- a/Products/CMFPlone/controlpanel/browser/redirects-controlpanel.pt
+++ b/Products/CMFPlone/controlpanel/browser/redirects-controlpanel.pt
@@ -117,7 +117,7 @@
       </form>
 
       <form
-          action="${view/view_url}"
+          action="${view/view_url}#manage-existing-aliases"
           method="post"
           id="manage-existing-aliases">
         <fieldset
@@ -126,6 +126,22 @@
             All existing aliases for this site
           </legend>
 
+          <label for="filter-existing-aliases-q" i18n:translate="">Filter by prefix</label>
+          <input
+              type="text"
+              name="q"
+              value=""
+              id="filter-existing-aliases-q"
+               tal:attributes="value python:request.form.get('q', '/')"/>
+          <div class="formControls">
+            <input
+                class="context"
+                type="submit"
+                value="Filter"
+                name="form.button.filter"
+                 i18n:attributes="value" />
+          </div>
+
           <tal:redirects repeat="redirect batch">
             <div>
               <label>
diff --git a/Products/CMFPlone/controlpanel/browser/redirects.py b/Products/CMFPlone/controlpanel/browser/redirects.py
index fa7342fd8..d1a1d6f25 100644
--- a/Products/CMFPlone/controlpanel/browser/redirects.py
+++ b/Products/CMFPlone/controlpanel/browser/redirects.py
@@ -106,15 +106,20 @@ def view_url(self):
 
 
 class RedirectionSet(object):
-    def __init__(self):
+    def __init__(self, query=''):
         self.storage = getUtility(IRedirectionStorage)
 
         portal = getUtility(ISiteRoot)
-        self.portal_path = "/".join(portal.getPhysicalPath())
+        self.portal_path = '/'.join(portal.getPhysicalPath())
         self.portal_path_len = len(self.portal_path)
 
         # noinspection PyProtectedMember
-        self.data = list(self.storage._paths.keys())  # maybe be costly
+        if query:
+            min_k = u'{0:s}/{1:s}'.format(self.portal_path, query.strip('/'))
+            max_k = min_k[:-1] + chr(ord(min_k[-1]) + 1)
+            self.data = list(self.storage._paths.keys(min=min_k, max=max_k))
+        else:
+            self.data = list(self.storage._paths.keys())  # maybe be costly
 
     def __len__(self):
         return len(self.data)
@@ -141,7 +146,7 @@ def make_link(self, pagenumber=None, omit_params=None):
             omit_params = ['ajax_load']
         url = super(RedirectsBatchView, self).make_link(pagenumber,
                                                         omit_params)
-        return url + u'#manage-existing-aliases'
+        return u'{0:s}#manage-existing-aliases'.format(url)
 
 
 class RedirectsControlPanel(BrowserView):
@@ -166,7 +171,7 @@ def redirects(self):
             'redirect' are equal.
         """
         return Batch(
-            RedirectionSet(),
+            RedirectionSet(self.request.form.get('q', '')),
             15,
             int(self.request.form.get('b_start', '0')),
             orphan=1
diff --git a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_redirection.py b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_redirection.py
index cd9cd1e76..1dc129808 100644
--- a/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_redirection.py
+++ b/Products/CMFPlone/controlpanel/tests/test_controlpanel_browser_redirection.py
@@ -11,6 +11,7 @@
 from Products.CMFPlone.testing import \
     PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING
 
+import math
 import unittest
 import transaction
 
@@ -138,3 +139,49 @@ def test_redirection_controlpanel_redirect_alias_exists(self):
             'The provided alias already exists!' in self.browser.contents,
             u'Message "alias already exists" not in page!'
         )
+
+    def test_redirection_controlpanel_filtering(self):
+        storage = getUtility(IRedirectionStorage)
+        portal_path = self.layer['portal'].absolute_url_path()
+        for i in range(1000):
+            storage.add('{0:s}/foo1/{1:s}'.format(portal_path, str(i)),
+                        '{0:s}/bar/{1:s}'.format(portal_path, str(i)))
+        for i in range(1000):
+            storage.add('{0:s}/foo2/{1:s}'.format(portal_path, str(i)),
+                        '{0:s}/bar/{1:s}'.format(portal_path, str(i)))
+
+        redirects = RedirectionSet()
+        self.assertEqual(len(redirects), 2000)
+        redirects = RedirectionSet(query='/foo')
+        self.assertEqual(len(redirects), 2000)
+        redirects = RedirectionSet(query='/foo1')
+        self.assertEqual(len(redirects), 1000)
+        redirects = RedirectionSet(query='/foo2')
+        self.assertEqual(len(redirects), 1000)
+
+        request = self.layer['request'].clone()
+        request.form['q'] = '/foo'
+        view = getMultiAdapter((self.layer['portal'], request),
+                               name='redirection-controlpanel')
+        self.assertEqual(view.redirects().numpages, math.ceil(2000 / 15.))
+
+        request = self.layer['request'].clone()
+        request.form['q'] = '/foo1'
+        view = getMultiAdapter((self.layer['portal'], request),
+                               name='redirection-controlpanel')
+        self.assertEqual(view.redirects().numpages, math.ceil(1000 / 15.))
+
+        request = self.layer['request'].clone()
+        request.form['q'] = '/foo2'
+        view = getMultiAdapter((self.layer['portal'], request),
+                               name='redirection-controlpanel')
+        self.assertEqual(view.redirects().numpages, math.ceil(1000 / 15.))
+
+        request = self.layer['request'].clone()
+        view = getMultiAdapter((self.layer['portal'], request),
+                               name='redirection-controlpanel')
+        self.assertEqual(view.redirects().numpages, math.ceil(2000 / 15.))
+
+        # Filtering without new request does not have effect because memoize
+        request.form['q'] = '/foo2'
+        self.assertEqual(view.redirects().numpages, math.ceil(2000 / 15.))



------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.