Attachment 'backlinks.patch'
Download 1 * This patch adds a new search modifier and uses it for backlink searches.
2 --- orig/MoinMoin/Page.py
3 +++ mod/MoinMoin/Page.py
4 @@ -1070,26 +1070,12 @@
5
6 # send the page header
7 if self.default_formatter:
8 -
9 - def quote_whitespace(x):
10 - if x.find(" ")!=-1:
11 - return "'%s'" % x
12 - else:
13 - return x
14 - page_needle = quote_whitespace(self.page_name)
15 - if config.allow_subpages and page_needle.count('/'):
16 - #parts = page_needle.split('/')
17 - #for level in range(1, len(parts)):
18 - # page_needle += (" !" + quote_whitespace(
19 - # "/".join(parts[:level])) + " " +
20 - # quote_whitespace(
21 - # "/" + "/".join(parts[level:])))
22 - page_needle = '/' + page_needle.split('/')[-1]
23 -
24 - link = '%s/%s?action=fullsearch&value=%s&literal=1&case=1&context=180' % (
25 + full_text_query = 'linkto:"%s"' % self.page_name
26 + link = '%s/%s?action=fullsearch&value=%s&context=180' % (
27 request.getScriptname(),
28 wikiutil.quoteWikinameURL(self.page_name),
29 - urllib.quote_plus(page_needle.encode(config.charset), ''))
30 + urllib.quote_plus(full_text_query.encode(config.charset)))
31 +
32 title = self.split_title(request)
33 if self.rev:
34 msg = "<strong>%s</strong><br>%s" % (
35
36
37 --- orig/MoinMoin/search.py
38 +++ mod/MoinMoin/search.py
39 @@ -1,7 +1,9 @@
40 """
41 MoinMoin search engine
42
43 - @copyright: Florian Festi TODO: email
44 + @copyright: MoinMoin:FlorianFesti
45 + MoinMoin:NirSoffer
46 + MoinMoin:AlexanderSchremmer
47 @license: GNU GPL, see COPYING for details
48 """
49
50 @@ -329,6 +331,78 @@
51 return self
52
53
54 +class LinkSearch(BaseExpression):
55 + """ Search the term in the pagelinks """
56 +
57 + def __init__(self, pattern, use_re=False, case=True):
58 + """ Init a title search
59 +
60 + @param pattern: pattern to search for, ascii string or unicode
61 + @param use_re: treat pattern as re of plain text, bool
62 + @param case: do case sensitive search, bool
63 + """
64 + # used for search in links
65 + self._pattern = pattern
66 + # used for search in text
67 + self._textpattern = '(' + self._pattern.replace('/', '|') + ')'
68 + self.negated = 0
69 + self.textsearch = TextSearch(self._textpattern, use_re=1, case=case)
70 + self._build_re(unicode(pattern), use_re=use_re, case=case)
71 +
72 + def _build_re(self, pattern, use_re=False, case=False):
73 + """ Make a regular expression out of a text pattern """
74 + flags = (re.U | re.I, re.U)[case]
75 +
76 + try:
77 + if not use_re:
78 + raise re.error
79 + self.search_re = re.compile(pattern + r'\n', flags)
80 + except re.error:
81 + pattern = re.escape(pattern) + r'\n'
82 + self.pattern = pattern
83 + self.search_re = re.compile(pattern, flags)
84 +
85 + def costs(self):
86 + return 5000 # cheaper than a TextSearch
87 +
88 + def __unicode__(self):
89 + return u'%s!"%s"' % (('', '-')[self.negated], unicode(self._pattern))
90 +
91 + def highlight_re(self):
92 + return u"(%s)" % self._textpattern
93 +
94 + def pageFilter(self):
95 + """ Page filter function for single text search """
96 + return None
97 +
98 + def search(self, page):
99 + # Get matches in page name
100 + matches = []
101 + page_links = '\n'.join(page.getPageLinks(page.request))
102 +
103 + if self.search_re.search(page_links) is not None:
104 + # Search in page text
105 + results = self.textsearch.search(page)
106 + if results:
107 + matches.extend(results)
108 + else: #This happens e.g. for pages that use navigation macros
109 + matches.append(TextMatch(0,0))
110 +
111 + # Decide what to do with the results.
112 + if ((self.negated and matches) or
113 + (not self.negated and not matches)):
114 + return None
115 + elif matches:
116 + return matches
117 + else:
118 + # XXX why not return None or empty list?
119 + return [Match()]
120 +
121 + def indexed_query(self):
122 + return self
123 +
124 +
125 +
126 class IndexedQuery:
127 """unused and experimental"""
128 def __init__(self, queryobject):
129 @@ -396,7 +470,6 @@
130 # before pages that their title does not match.
131 _weight = 100.0
132
133 -
134 class FoundPage:
135 """ Represents a page in a search result """
136
137 @@ -577,6 +650,7 @@
138 title_search = self.titlesearch
139 regex = self.regex
140 case = self.case
141 + linkto = 0
142
143 for m in modifiers:
144 if "title".startswith(m):
145 @@ -585,8 +659,12 @@
146 regex = True
147 elif "case".startswith(m):
148 case = True
149 + elif "linkto".startswith(m):
150 + linkto = True
151
152 - if title_search:
153 + if linkto:
154 + obj = LinkSearch(text, use_re=regex, case=case)
155 + elif title_search:
156 obj = TitleSearch(text, use_re=regex, case=case)
157 else:
158 obj = TextSearch(text, use_re=regex, case=case)
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.