1 # -*- coding: iso-8859-1 -*- 2 """ 3 MoinMoin - ImprovedMoinSearch library 4 5 @copyright: 2010 Paul Boddie <paul@boddie.org.uk> 6 @license: GNU GPL (v2 or later), see COPYING.txt for details. 7 """ 8 9 from MoinMoin.search import searchPages 10 from MoinMoin.Page import Page 11 from MoinMoin import wikiutil 12 import re 13 14 heading_regexp = re.compile(r"^(?P<level>=+)(?P<heading>.*?)(?P=level)$", re.UNICODE | re.MULTILINE) 15 heading_options_regexp = re.compile(r"heading\s*(?P<min>\d+)?(?:\s*-\s*(?P<max>\d+))?", re.UNICODE) 16 17 def getSearchResultPages(request, query, **kw): 18 19 """ 20 Return matching pages using the given 'request' and search 'query'. Optional 21 keyword arguments are passed to the underlying search infrastructure. 22 """ 23 24 results = searchPages(request, query, **kw) 25 return results.hits 26 27 def getFirstPageHeading(request, page, min_level=1, max_level=1): 28 29 """ 30 Using the given 'request', return the first heading in the given 'page' 31 having a heading level of at least 'min_level' (which is 1 if not specified) 32 and at most 'max_level' (which is 1 if not specified). 33 """ 34 35 full_page = Page(request, page.page_name) 36 body = full_page.get_raw_body() 37 38 for match in heading_regexp.finditer(body): 39 level = len(match.group("level")) 40 41 if (min_level is None or level >= min_level) and \ 42 (max_level is None or level <= max_level): 43 44 return match.group("heading") 45 46 return None 47 48 def formatResultPages(request, formatter, pages, paging, format, page_from=0): 49 50 """ 51 Using the given 'request' and 'formatter', return a formatted string showing 52 the result 'pages', providing paging controls when 'paging' is set to a true 53 value, and providing page details according to the given 'format'. 54 55 If the optional 'pages_from' parameter is set, the result pages from the 56 given result (specified within a range from 0 to the length of the 'pages' 57 collection) will be shown. 58 """ 59 60 if format: 61 m = heading_options_regexp.search(format) 62 else: 63 m = None 64 65 if m: 66 format = "heading" 67 min_level = int_or_none(m.group("min")) 68 max_level = int_or_none(m.group("max")) 69 else: 70 format = "name" 71 72 # Use paging only when there are enough results. 73 74 results_per_page = request.cfg.search_results_per_page 75 paging = paging and len(pages) > results_per_page 76 77 if paging: 78 pages_to_show = pages[page_from:page_from + results_per_page] 79 else: 80 pages_to_show = pages 81 82 # Prepare the output. 83 84 output = [] 85 output.append(formatter.number_list(on=1)) 86 87 for page in pages_to_show: 88 output.append(formatter.listitem(on=1)) 89 90 if format == "heading": 91 text = getFirstPageHeading(request, page, min_level, max_level) or page.page_name 92 else: 93 text = page.page_name 94 95 output.append(formatter.pagelink(on=1, pagename=page.page_name)) 96 output.append(formatter.text(text)) 97 output.append(formatter.pagelink(on=0)) 98 output.append(formatter.listitem(on=0)) 99 100 output.append(formatter.number_list(on=0)) 101 102 # Show paging navigation. 103 104 if paging: 105 output.append(formatPagingNavigation(request, formatter, pages, page_from)) 106 107 return "".join(output) 108 109 def formatPagingNavigation(request, formatter, pages, page_from=0): 110 111 """ 112 Using the given 'request' and 'formatter', return a formatted string showing 113 the paging navigation for the result 'pages', according to the 'page_from' 114 indicator which provides the current position in the result set. 115 """ 116 117 _ = request.getText 118 119 output = [] 120 121 results_per_page = request.cfg.search_results_per_page 122 number_of_results = len(pages) 123 124 pages_total = number_of_results / results_per_page 125 pages_before = page_from / results_per_page 126 pages_after = ((number_of_results - page_from) / results_per_page) - 1 127 128 querydict = wikiutil.parseQueryString(request.query_string) 129 130 output.append(formatter.paragraph(on=1)) 131 output.append(formatter.text(_("Result pages:"))) 132 output.append(formatter.text(" ")) 133 134 n = 0 135 while n < pages_before: 136 output.append(formatter.pagelink(on=1, querystr=getPagingQueryString(querydict, n * results_per_page))) 137 output.append(formatter.text(str(n + 1))) 138 output.append(formatter.pagelink(on=0)) 139 output.append(formatter.text(" ")) 140 n += 1 141 142 output.append(formatter.text(str(n + 1))) 143 output.append(formatter.text(" ")) 144 n += 1 145 146 while n < pages_total: 147 output.append(formatter.pagelink(on=1, querystr=getPagingQueryString(querydict, n * results_per_page))) 148 output.append(formatter.text(str(n + 1))) 149 output.append(formatter.pagelink(on=0)) 150 output.append(formatter.text(" ")) 151 n += 1 152 153 output.append(formatter.paragraph(on=0)) 154 155 return "".join(output) 156 157 def getPagingQueryString(querydict, page_from): 158 querydict["from"] = page_from 159 return wikiutil.makeQueryString(querydict) 160 161 def int_or_none(x): 162 if x is None: 163 return x 164 else: 165 return int(x) 166 167 # vim: tabstop=4 expandtab shiftwidth=4