Back to index

moin  1.9.0~rc2
Functions
MoinMoin.action.LikePages Namespace Reference

Functions

def execute
def findMatches
def wikiMatches
def closeMatches
def showMatches
def _showMatchGroup

Function Documentation

def MoinMoin.action.LikePages._showMatchGroup (   request,
  matches,
  keys,
  match,
  title,
  show_count = True 
) [private]

Definition at line 212 of file LikePages.py.

00212 
00213 def _showMatchGroup(request, matches, keys, match, title, show_count=True):
00214     _ = request.getText
00215     matchcount = matches.values().count(match)
00216 
00217     if matchcount:
00218         if show_count:
00219             # Render title line
00220             request.write(request.formatter.paragraph(1))
00221             request.write(request.formatter.strong(1))
00222             request.write(request.formatter.text(
00223                 _('%(matchcount)d %(matches)s for "%(title)s"') % {
00224                     'matchcount': matchcount,
00225                     'matches': ' ' + (_('match'), _('matches'))[matchcount != 1],
00226                     'title': title}))
00227             request.write(request.formatter.strong(0))
00228             request.write(request.formatter.paragraph(0))
00229 
00230         # Render links
00231         request.write(request.formatter.bullet_list(1))
00232         for key in keys:
00233             if matches[key] == match:
00234                 request.write(request.formatter.listitem(1))
00235                 request.write(request.formatter.pagelink(1, key, generated=True))
00236                 request.write(request.formatter.text(key))
00237                 request.write(request.formatter.pagelink(0, key, generated=True))
00238                 request.write(request.formatter.listitem(0))
00239         request.write(request.formatter.bullet_list(0))
00240 
00241 

Here is the caller graph for this function:

def MoinMoin.action.LikePages.closeMatches (   pagename,
  pages 
)
Get close matches.

Return all matching pages with rank above cutoff value.

@param pagename: page name to match
@param pages: list of page names
@rtype: list
@return: list of matching pages, sorted by rank

Definition at line 169 of file LikePages.py.

00169 
00170 def closeMatches(pagename, pages):
00171     """ Get close matches.
00172 
00173     Return all matching pages with rank above cutoff value.
00174 
00175     @param pagename: page name to match
00176     @param pages: list of page names
00177     @rtype: list
00178     @return: list of matching pages, sorted by rank
00179     """
00180     # Match using case insensitive matching
00181     # Make mapping from lowerpages to pages - pages might have same name
00182     # with different case (although its stupid).
00183     lower = {}
00184     for name in pages:
00185         key = name.lower()
00186         if key in lower:
00187             lower[key].append(name)
00188         else:
00189             lower[key] = [name]
00190 
00191     # Get all close matches
00192     all_matches = difflib.get_close_matches(pagename.lower(), lower.keys(),
00193                                             len(lower), cutoff=0.6)
00194 
00195     # Replace lower names with original names
00196     matches = []
00197     for name in all_matches:
00198         matches.extend(lower[name])
00199 
00200     return matches
00201 

Here is the caller graph for this function:

def MoinMoin.action.LikePages.execute (   pagename,
  request 
)

Definition at line 21 of file LikePages.py.

00021 
00022 def execute(pagename, request):
00023     _ = request.getText
00024     start, end, matches = findMatches(pagename, request)
00025 
00026     # Error?
00027     if isinstance(matches, (str, unicode)):
00028         request.theme.add_msg(matches, "info")
00029         Page(request, pagename).send_page()
00030         return
00031 
00032     # No matches
00033     if not matches:
00034         request.theme.add_msg(_('No pages like "%s"!') % (pagename, ), "error")
00035         Page(request, pagename).send_page()
00036         return
00037 
00038     # One match - display it
00039     if len(matches) == 1:
00040         request.theme.add_msg(_('Exactly one page like "%s" found, redirecting to page.') % (pagename, ), "info")
00041         Page(request, matches.keys()[0]).send_page()
00042         return
00043 
00044     # more than one match, list 'em
00045     # This action generate data using the user language
00046     request.setContentLanguage(request.lang)
00047 
00048     request.theme.send_title(_('Pages like "%s"') % (pagename), pagename=pagename)
00049 
00050     # Start content - IMPORTANT - without content div, there is no
00051     # direction support!
00052     request.write(request.formatter.startContent("content"))
00053 
00054     showMatches(pagename, request, start, end, matches)
00055 
00056     # End content and send footer
00057     request.write(request.formatter.endContent())
00058     request.theme.send_footer(pagename)
00059     request.theme.send_closing_html()

Here is the call graph for this function:

def MoinMoin.action.LikePages.findMatches (   pagename,
  request,
  s_re = None,
  e_re = None 
)
Find like pages

@param pagename: name to match
@param request: current reqeust
@param s_re: start re for wiki matching
@param e_re: end re for wiki matching
@rtype: tuple
@return: start word, end word, matches dict

Definition at line 60 of file LikePages.py.

00060 
00061 def findMatches(pagename, request, s_re=None, e_re=None):
00062     """ Find like pages
00063 
00064     @param pagename: name to match
00065     @param request: current reqeust
00066     @param s_re: start re for wiki matching
00067     @param e_re: end re for wiki matching
00068     @rtype: tuple
00069     @return: start word, end word, matches dict
00070     """
00071     # Get full list of pages, with no filtering - very fast. We will
00072     # first search for like pages, then filter the results.
00073     pages = request.rootpage.getPageList(user='', exists='')
00074 
00075     # Remove current page
00076     try:
00077         pages.remove(pagename)
00078     except ValueError:
00079         pass
00080 
00081     # Get matches using wiki way, start and end of word
00082     start, end, matches = wikiMatches(pagename, pages, start_re=s_re,
00083                                       end_re=e_re)
00084 
00085     # Get the best 10 close matches
00086     close_matches = {}
00087     found = 0
00088     for name in closeMatches(pagename, pages):
00089         # Skip names already in matches
00090         if name in matches:
00091             continue
00092 
00093         # Filter deleted pages or pages the user can't read
00094         page = Page(request, name)
00095         if page.exists() and request.user.may.read(name):
00096             close_matches[name] = 8
00097             found += 1
00098             # Stop after 10 matches
00099             if found == 10:
00100                 break
00101 
00102     # Filter deleted pages or pages the user can't read from
00103     # matches. Order is important!
00104     for name in matches.keys(): # we need .keys() because we modify the dict
00105         page = Page(request, name)
00106         if not (page.exists() and request.user.may.read(name)):
00107             del matches[name]
00108 
00109     # Finally, merge both dicts
00110     matches.update(close_matches)
00111 
00112     return start, end, matches
00113 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.action.LikePages.showMatches (   pagename,
  request,
  start,
  end,
  matches,
  show_count = True 
)

Definition at line 202 of file LikePages.py.

00202 
00203 def showMatches(pagename, request, start, end, matches, show_count=True):
00204     keys = matches.keys()
00205     keys.sort()
00206     _showMatchGroup(request, matches, keys, 8, pagename, show_count)
00207     _showMatchGroup(request, matches, keys, 4, "%s/..." % pagename, show_count)
00208     _showMatchGroup(request, matches, keys, 3, "%s...%s" % (start, end), show_count)
00209     _showMatchGroup(request, matches, keys, 1, "%s..." % (start, ), show_count)
00210     _showMatchGroup(request, matches, keys, 2, "...%s" % (end, ), show_count)
00211 

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.action.LikePages.wikiMatches (   pagename,
  pages,
  start_re = None,
  end_re = None 
)
Get pages that starts or ends with same word as this page

Matches are ranked like this:
    4 - page is subpage of pagename
    3 - match both start and end
    2 - match end
    1 - match start

@param pagename: page name to match
@param pages: list of page names
@param start_re: start word re (compile regex)
@param end_re: end word re (compile regex)
@rtype: tuple
@return: start, end, matches dict

Definition at line 114 of file LikePages.py.

00114 
00115 def wikiMatches(pagename, pages, start_re=None, end_re=None):
00116     """
00117     Get pages that starts or ends with same word as this page
00118 
00119     Matches are ranked like this:
00120         4 - page is subpage of pagename
00121         3 - match both start and end
00122         2 - match end
00123         1 - match start
00124 
00125     @param pagename: page name to match
00126     @param pages: list of page names
00127     @param start_re: start word re (compile regex)
00128     @param end_re: end word re (compile regex)
00129     @rtype: tuple
00130     @return: start, end, matches dict
00131     """
00132     if start_re is None:
00133         start_re = re.compile('([%s][%s]+)' % (config.chars_upper,
00134                                                config.chars_lower))
00135     if end_re is None:
00136         end_re = re.compile('([%s][%s]+)$' % (config.chars_upper,
00137                                               config.chars_lower))
00138 
00139     # If we don't get results with wiki words matching, fall back to
00140     # simple first word and last word, using spaces.
00141     words = pagename.split()
00142     match = start_re.match(pagename)
00143     if match:
00144         start = match.group(1)
00145     else:
00146         start = words[0]
00147 
00148     match = end_re.search(pagename)
00149     if match:
00150         end = match.group(1)
00151     else:
00152         end = words[-1]
00153 
00154     matches = {}
00155     subpage = pagename + '/'
00156 
00157     # Find any matching pages and rank by type of match
00158     for name in pages:
00159         if name.startswith(subpage):
00160             matches[name] = 4
00161         else:
00162             if name.startswith(start):
00163                 matches[name] = 1
00164             if name.endswith(end):
00165                 matches[name] = matches.get(name, 0) + 2
00166 
00167     return start, end, matches
00168 

Here is the caller graph for this function: