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.
  • [get | view] (2005-02-08 22:18:31, 5.3 KB) [[attachment:backlinks.patch]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.