1. Thomas Waldmann
  2. moin-2.0

Commits

Thomas Waldmann  committed 5d672f9 Merge

merged default into namespaces branch

  • Participants
  • Parent commits 3e7fc8b, 597e051
  • Branches namespaces

Comments (0)

Files changed (2)

File MoinMoin/items/__init__.py

View file
  • Ignore whitespace
 
 from jinja2 import Markup
 
-from whoosh.query import Term, And, Prefix
+from whoosh.query import Term, Prefix, And, Or, Not
 
 from MoinMoin import log
 logging = log.getLogger(__name__)
         return form
 
 
+UNKNOWN_ITEM_GROUP = "unknown items"
+
+def _build_contenttype_query(groups):
+    """
+    Build a Whoosh query from a list of contenttype groups.
+    """
+    queries = []
+    for g in groups:
+        for e in content_registry.groups[g]:
+            ct_unicode = unicode(e.content_type)
+            queries.append(Term(CONTENTTYPE, ct_unicode))
+            queries.append(Prefix(CONTENTTYPE, ct_unicode + u';'))
+    return Or(queries)
+
 IndexEntry = namedtuple('IndexEntry', 'relname meta')
 
 MixedIndexEntry = namedtuple('MixedIndexEntry', 'relname meta hassubitems')
 
         return dirs, files
 
-    @timed()
-    def filter_index(self, index, startswith=None, selected_groups=None):
-        """
-        Filter a list of IndexEntry.
+    def build_index_query(self, startswith=None, selected_groups=None):
+        prefix = self.subitems_prefix
+        if startswith:
+            query = Prefix(NAME_EXACT, prefix + startswith) | Prefix(NAME_EXACT, prefix + startswith.swapcase())
+        else:
+            query = Prefix(NAME_EXACT, prefix)
 
-        :param startswith: if set, only items whose names start with startswith
-                           are selected.
-        :param selected_groups: if set, only items whose contentypes belong to
-                                the selected contenttype_groups are selected.
-        """
-        if startswith is not None:
-            index = [e for e in index
-                     if e.relname.startswith((startswith, startswith.swapcase()))]
+        if selected_groups:
+            selected_groups = set(selected_groups)
+            has_unknown = UNKNOWN_ITEM_GROUP in selected_groups
+            if has_unknown:
+                selected_groups.remove(UNKNOWN_ITEM_GROUP)
+            ct_query = _build_contenttype_query(selected_groups)
+            if has_unknown:
+                ct_query |= Not(_build_contenttype_query(content_registry.groups))
+            query &= ct_query
 
-        def build_contenttypes(groups):
-            contenttypes = []
-            for g in groups:
-                entries = content_registry.groups.get(g, []) # .get is a temporary workaround for "unknown items" group
-                contenttypes.extend([e.content_type for e in entries])
-            return contenttypes
-
-        def contenttype_match(tested, cts):
-            for ct in cts:
-                if ct.issupertype(tested):
-                    return True
-            return False
-
-        if selected_groups is not None:
-            selected_contenttypes = build_contenttypes(selected_groups)
-            filtered_index = [e for e in index if contenttype_match(Type(e.meta[CONTENTTYPE]), selected_contenttypes)]
-
-            unknown_item_group = "unknown items"
-            if unknown_item_group in selected_groups:
-                all_contenttypes = build_contenttypes(content_registry.group_names)
-                filtered_index.extend([e for e in index
-                                       if not contenttype_match(Type(e.meta[CONTENTTYPE]), all_contenttypes)])
-
-            index = filtered_index
-        return index
+        return query
 
     def get_index(self, startswith=None, selected_groups=None):
-        dirs, files = self.make_flat_index(self.get_subitem_revs())
-        return dirs, self.filter_index(files, startswith, selected_groups)
+        query = Term(WIKINAME, app.cfg.interwikiname) & self.build_index_query(startswith, selected_groups)
+        revs = flaskg.storage.search(query, sortedby=NAME_EXACT, limit=None)
+        return self.make_flat_index(revs)
 
     def get_mixed_index(self):
         dirs, files = self.make_flat_index(self.get_subitem_revs())

File MoinMoin/items/_tests/test_Item.py

View file
  • Ignore whitespace
 
         # test Item.make_flat_index
         # TODO: test Item.get_subitem_revs
-        dirs, files = baseitem.make_flat_index(baseitem.get_subitem_revs())
+        dirs, files = baseitem.get_index()
         assert dirs == build_index(basename, [u'cd', u'ij'])
         assert files == build_index(basename, [u'ab', u'gh', u'ij', u'mn'])
 
             (u'mn', False),
         ])
 
-        # test Item.filter_index
         # check filtered index when startswith param is passed
-        filtered_files = baseitem.filter_index(files, startswith=u'a')
-        assert filtered_files == build_index(basename, [u'ab'])
+        dirs, files = baseitem.get_index(startswith=u'a')
+        assert dirs == []
+        assert files == build_index(basename, [u'ab'])
 
         # check filtered index when contenttype_groups is passed
-        ctgroups = ["image items"]
-        filtered_files = baseitem.filter_index(files, selected_groups=ctgroups)
-        assert filtered_files == build_index(basename, [u'mn'])
-
-        # If we ask for text/plain type, should Foo/cd be returned?
+        ctgroups = ["other text items"]
+        dirs, files = baseitem.get_index(selected_groups=ctgroups)
+        assert dirs == build_index(basename, [u'cd', u'ij'])
+        assert files == build_index(basename, [u'ab', u'gh', u'ij'])
 
     def test_meta_filter(self):
         name = u'Test_item'