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, start=page_from + 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 page = formatter.page 118 pagename = page.page_name 119 _ = request.getText 120 121 output = [] 122 123 results_per_page = request.cfg.search_results_per_page 124 number_of_results = len(pages) 125 126 pages_total = number_of_results / results_per_page 127 pages_before = page_from / results_per_page 128 pages_after = ((number_of_results - page_from) / results_per_page) - 1 129 130 querydict = wikiutil.parseQueryString(request.query_string) 131 132 output.append(formatter.paragraph(on=1)) 133 output.append(formatter.text(_("Result pages:"))) 134 output.append(formatter.text(" ")) 135 136 n = 0 137 while n < pages_before: 138 output.append(formatter.pagelink(on=1, pagename=pagename, querystr=getPagingQueryString(querydict, n * results_per_page))) 139 output.append(formatter.text(str(n + 1))) 140 output.append(formatter.pagelink(on=0)) 141 output.append(formatter.text(" ")) 142 n += 1 143 144 output.append(formatter.text(str(n + 1))) 145 output.append(formatter.text(" ")) 146 n += 1 147 148 while n <= pages_total: 149 output.append(formatter.pagelink(on=1, pagename=pagename, querystr=getPagingQueryString(querydict, n * results_per_page))) 150 output.append(formatter.text(str(n + 1))) 151 output.append(formatter.pagelink(on=0)) 152 output.append(formatter.text(" ")) 153 n += 1 154 155 output.append(formatter.paragraph(on=0)) 156 157 return "".join(output) 158 159 def getPagingQueryString(querydict, page_from): 160 querydict["from"] = page_from 161 return wikiutil.makeQueryString(querydict) 162 163 def int_or_none(x): 164 if x is None: 165 return x 166 else: 167 return int(x) 168 169 # vim: tabstop=4 expandtab shiftwidth=4