diff MoinMoin/items/__init__.py @ 1960:5d672f909f27 namespaces

merged default into namespaces branch
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sat, 09 Feb 2013 17:30:19 +0100
parents 3e7fc8bab8b1 70c534eb5596
children 46e8aa18c4d1
line wrap: on
line diff
--- a/MoinMoin/items/__init__.py	Sat Feb 09 17:03:57 2013 +0100
+++ b/MoinMoin/items/__init__.py	Sat Feb 09 17:30:19 2013 +0100
@@ -30,7 +30,7 @@
 
 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__)
@@ -197,6 +197,20 @@
         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')
@@ -521,49 +535,29 @@
 
         return dirs, files
 
-    @timed()
-    def filter_index(self, index, startswith=None, selected_groups=None):
-        """
-        Filter a list of IndexEntry.
-
-        :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()))]
+    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)
 
-        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
+        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 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())