comparison 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
comparison
equal deleted inserted replaced
1957:3e7fc8bab8b1 1960:5d672f909f27
28 28
29 from flatland import Form 29 from flatland import Form
30 30
31 from jinja2 import Markup 31 from jinja2 import Markup
32 32
33 from whoosh.query import Term, And, Prefix 33 from whoosh.query import Term, Prefix, And, Or, Not
34 34
35 from MoinMoin import log 35 from MoinMoin import log
36 logging = log.getLogger(__name__) 36 logging = log.getLogger(__name__)
37 37
38 from MoinMoin.security.textcha import TextCha, TextChaizedForm 38 from MoinMoin.security.textcha import TextCha, TextChaizedForm
195 form = cls.from_flat(request.form.items() + request.files.items()) 195 form = cls.from_flat(request.form.items() + request.files.items())
196 TextCha(form).amend_form() 196 TextCha(form).amend_form()
197 return form 197 return form
198 198
199 199
200 UNKNOWN_ITEM_GROUP = "unknown items"
201
202 def _build_contenttype_query(groups):
203 """
204 Build a Whoosh query from a list of contenttype groups.
205 """
206 queries = []
207 for g in groups:
208 for e in content_registry.groups[g]:
209 ct_unicode = unicode(e.content_type)
210 queries.append(Term(CONTENTTYPE, ct_unicode))
211 queries.append(Prefix(CONTENTTYPE, ct_unicode + u';'))
212 return Or(queries)
213
200 IndexEntry = namedtuple('IndexEntry', 'relname meta') 214 IndexEntry = namedtuple('IndexEntry', 'relname meta')
201 215
202 MixedIndexEntry = namedtuple('MixedIndexEntry', 'relname meta hassubitems') 216 MixedIndexEntry = namedtuple('MixedIndexEntry', 'relname meta hassubitems')
203 217
204 class Item(object): 218 class Item(object):
519 else: 533 else:
520 files.append(IndexEntry(relname, rev.meta)) 534 files.append(IndexEntry(relname, rev.meta))
521 535
522 return dirs, files 536 return dirs, files
523 537
524 @timed() 538 def build_index_query(self, startswith=None, selected_groups=None):
525 def filter_index(self, index, startswith=None, selected_groups=None): 539 prefix = self.subitems_prefix
526 """ 540 if startswith:
527 Filter a list of IndexEntry. 541 query = Prefix(NAME_EXACT, prefix + startswith) | Prefix(NAME_EXACT, prefix + startswith.swapcase())
528 542 else:
529 :param startswith: if set, only items whose names start with startswith 543 query = Prefix(NAME_EXACT, prefix)
530 are selected. 544
531 :param selected_groups: if set, only items whose contentypes belong to 545 if selected_groups:
532 the selected contenttype_groups are selected. 546 selected_groups = set(selected_groups)
533 """ 547 has_unknown = UNKNOWN_ITEM_GROUP in selected_groups
534 if startswith is not None: 548 if has_unknown:
535 index = [e for e in index 549 selected_groups.remove(UNKNOWN_ITEM_GROUP)
536 if e.relname.startswith((startswith, startswith.swapcase()))] 550 ct_query = _build_contenttype_query(selected_groups)
537 551 if has_unknown:
538 def build_contenttypes(groups): 552 ct_query |= Not(_build_contenttype_query(content_registry.groups))
539 contenttypes = [] 553 query &= ct_query
540 for g in groups: 554
541 entries = content_registry.groups.get(g, []) # .get is a temporary workaround for "unknown items" group 555 return query
542 contenttypes.extend([e.content_type for e in entries])
543 return contenttypes
544
545 def contenttype_match(tested, cts):
546 for ct in cts:
547 if ct.issupertype(tested):
548 return True
549 return False
550
551 if selected_groups is not None:
552 selected_contenttypes = build_contenttypes(selected_groups)
553 filtered_index = [e for e in index if contenttype_match(Type(e.meta[CONTENTTYPE]), selected_contenttypes)]
554
555 unknown_item_group = "unknown items"
556 if unknown_item_group in selected_groups:
557 all_contenttypes = build_contenttypes(content_registry.group_names)
558 filtered_index.extend([e for e in index
559 if not contenttype_match(Type(e.meta[CONTENTTYPE]), all_contenttypes)])
560
561 index = filtered_index
562 return index
563 556
564 def get_index(self, startswith=None, selected_groups=None): 557 def get_index(self, startswith=None, selected_groups=None):
565 dirs, files = self.make_flat_index(self.get_subitem_revs()) 558 query = Term(WIKINAME, app.cfg.interwikiname) & self.build_index_query(startswith, selected_groups)
566 return dirs, self.filter_index(files, startswith, selected_groups) 559 revs = flaskg.storage.search(query, sortedby=NAME_EXACT, limit=None)
560 return self.make_flat_index(revs)
567 561
568 def get_mixed_index(self): 562 def get_mixed_index(self):
569 dirs, files = self.make_flat_index(self.get_subitem_revs()) 563 dirs, files = self.make_flat_index(self.get_subitem_revs())
570 dirs_dict = dict([(e.relname, MixedIndexEntry(*e, hassubitems=True)) for e in dirs]) 564 dirs_dict = dict([(e.relname, MixedIndexEntry(*e, hassubitems=True)) for e in dirs])
571 index_dict = dict([(e.relname, MixedIndexEntry(*e, hassubitems=False)) for e in files]) 565 index_dict = dict([(e.relname, MixedIndexEntry(*e, hassubitems=False)) for e in files])