Back to index

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

Functions

def checkTitleSearch
def isAdvancedSearch
def searchHints
def execute

Function Documentation

Return 1 for title search, 0 for full text search, -1 for idiot spammer
    who tries to press all buttons at once.

When used in FullSearch macro, we have 'titlesearch' parameter with
'0' or '1'. In standard search, we have either 'titlesearch' or
'fullsearch' with localized string. If both missing, default to
True (might happen with Safari) if this isn't an advanced search.

Definition at line 17 of file fullsearch.py.

00017 
00018 def checkTitleSearch(request):
00019     """ Return 1 for title search, 0 for full text search, -1 for idiot spammer
00020         who tries to press all buttons at once.
00021 
00022     When used in FullSearch macro, we have 'titlesearch' parameter with
00023     '0' or '1'. In standard search, we have either 'titlesearch' or
00024     'fullsearch' with localized string. If both missing, default to
00025     True (might happen with Safari) if this isn't an advanced search.
00026 """
00027     form = request.values
00028     if 'titlesearch' in form and 'fullsearch' in form:
00029         ret = -1 # spammer / bot
00030     else:
00031         try:
00032             ret = int(form['titlesearch'])
00033         except ValueError:
00034             ret = 1
00035         except KeyError:
00036             ret = ('fullsearch' not in form and not isAdvancedSearch(request)) and 1 or 0
00037     return ret

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.action.fullsearch.execute (   pagename,
  request,
  fieldname = 'value',
  titlesearch = 0,
  statistic = 0 
)

Definition at line 60 of file fullsearch.py.

00060 
00061 def execute(pagename, request, fieldname='value', titlesearch=0, statistic=0):
00062     _ = request.getText
00063     titlesearch = checkTitleSearch(request)
00064     if titlesearch < 0:
00065         check_surge_protect(request, kick=True) # get rid of spammer
00066         return
00067 
00068     advancedsearch = isAdvancedSearch(request)
00069 
00070     form = request.values
00071 
00072     # context is relevant only for full search
00073     if titlesearch:
00074         context = 0
00075     elif advancedsearch:
00076         context = 180 # XXX: hardcoded context count for advancedsearch
00077     else:
00078         context = int(form.get('context', 0))
00079 
00080     # Get other form parameters
00081     needle = form.get(fieldname, '')
00082     case = int(form.get('case', 0))
00083     regex = int(form.get('regex', 0)) # no interface currently
00084     hitsFrom = int(form.get('from', 0))
00085     mtime = None
00086     msg = ''
00087     historysearch = 0
00088 
00089     # if advanced search is enabled we construct our own search query
00090     if advancedsearch:
00091         and_terms = form.get('and_terms', '').strip()
00092         or_terms = form.get('or_terms', '').strip()
00093         not_terms = form.get('not_terms', '').strip()
00094         #xor_terms = form.get('xor_terms', '').strip()
00095         categories = form.getlist('categories') or ['']
00096         timeframe = form.get('time', '').strip()
00097         language = form.getlist('language') or ['']
00098         mimetype = form.getlist('mimetype') or [0]
00099         excludeunderlay = form.get('excludeunderlay', 0)
00100         nosystemitems = form.get('nosystemitems', 0)
00101         historysearch = form.get('historysearch', 0)
00102 
00103         mtime = form.get('mtime', '')
00104         if mtime:
00105             mtime_parsed = None
00106 
00107             # get mtime from known date/time formats
00108             for fmt in (request.user.datetime_fmt,
00109                     request.cfg.datetime_fmt, request.user.date_fmt,
00110                     request.cfg.date_fmt):
00111                 try:
00112                     mtime_parsed = time.strptime(mtime, fmt)
00113                 except ValueError:
00114                     continue
00115                 else:
00116                     break
00117 
00118             if mtime_parsed:
00119                 mtime = time.mktime(mtime_parsed)
00120             else:
00121                 # didn't work, let's try parsedatetime
00122                 cal = Calendar()
00123                 mtime_parsed, parsed_what = cal.parse(mtime)
00124                 # XXX it is unclear if usage of localtime here and in parsedatetime module is correct.
00125                 # time.localtime is the SERVER's local time and of no relevance to the user (being
00126                 # somewhere in the world)
00127                 # mktime is reverse function for localtime, so this maybe fixes it again!?
00128                 if parsed_what > 0 and mtime_parsed <= time.localtime():
00129                     mtime = time.mktime(mtime_parsed)
00130                 else:
00131                     mtime_parsed = None # we don't use invalid stuff
00132 
00133             # show info
00134             if mtime_parsed:
00135                 # XXX mtime_msg is not shown in some cases
00136                 mtime_msg = _("(!) Only pages changed since '''%s''' are being displayed!",
00137                               wiki=True) % request.user.getFormattedDateTime(mtime)
00138             else:
00139                 mtime_msg = _('/!\\ The modification date you entered was not '
00140                         'recognized and is therefore not considered for the '
00141                         'search results!', wiki=True)
00142         else:
00143             mtime_msg = None
00144 
00145         word_re = re.compile(r'(\"[\w\s]+"|\w+)')
00146         needle = ''
00147         if categories[0]:
00148             needle += 'category:%s ' % ','.join(categories)
00149         if language[0]:
00150             needle += 'language:%s ' % ','.join(language)
00151         if mimetype[0]:
00152             needle += 'mimetype:%s ' % ','.join(mimetype)
00153         if excludeunderlay:
00154             needle += '-domain:underlay '
00155         if nosystemitems:
00156             needle += '-domain:system '
00157         if and_terms:
00158             needle += '(%s) ' % and_terms
00159         if not_terms:
00160             needle += '(%s) ' % ' '.join(['-%s' % t for t in word_re.findall(not_terms)])
00161         if or_terms:
00162             needle += '(%s) ' % ' or '.join(word_re.findall(or_terms))
00163 
00164     # check for sensible search term
00165     stripped = needle.strip()
00166     if len(stripped) == 0:
00167         request.theme.add_msg(_('Please use a more selective search term instead '
00168                 'of {{{"%s"}}}', wiki=True) % wikiutil.escape(needle), "error")
00169         Page(request, pagename).send_page()
00170         return
00171     needle = stripped
00172 
00173     # Setup for type of search
00174     if titlesearch:
00175         title = _('Title Search: "%s"')
00176         sort = 'page_name'
00177     else:
00178         if advancedsearch:
00179             title = _('Advanced Search: "%s"')
00180         else:
00181             title = _('Full Text Search: "%s"')
00182         sort = 'weight'
00183 
00184     # search the pages
00185     from MoinMoin.search import searchPages, QueryParser, QueryError
00186     try:
00187         query = QueryParser(case=case, regex=regex,
00188                 titlesearch=titlesearch).parse_query(needle)
00189     except QueryError: # catch errors in the search query
00190         request.theme.add_msg(_('Your search query {{{"%s"}}} is invalid. Please refer to '
00191                 'HelpOnSearching for more information.', wiki=True, percent=True) % wikiutil.escape(needle), "error")
00192         Page(request, pagename).send_page()
00193         return
00194 
00195     results = searchPages(request, query, sort, mtime, historysearch)
00196 
00197     # directly show a single hit for title searches
00198     # this is the "quick jump" functionality if you don't remember
00199     # the pagename exactly, but just some parts of it
00200     if titlesearch and len(results.hits) == 1:
00201         page = results.hits[0]
00202         if not page.attachment: # we did not find an attachment
00203             page = Page(request, page.page_name)
00204             highlight = query.highlight_re()
00205             if highlight:
00206                 querydict = {'highlight': highlight}
00207             else:
00208                 querydict = {}
00209             url = page.url(request, querystr=querydict)
00210             request.http_redirect(url)
00211             return
00212     if not results.hits: # no hits?
00213         f = request.formatter
00214         querydict = dict(wikiutil.parseQueryString(request.query_string))
00215         querydict.update({'titlesearch': 0})
00216 
00217         request.theme.add_msg(_('Your search query {{{"%s"}}} didn\'t return any results. '
00218                 'Please change some terms and refer to HelpOnSearching for '
00219                 'more information.%s', wiki=True, percent=True) % (wikiutil.escape(needle),
00220                     titlesearch and ''.join([
00221                         '<br>',
00222                         _('(!) Consider performing a', wiki=True), ' ',
00223                         f.url(1, href=request.page.url(request, querydict, escape=0)),
00224                         _('full-text search with your search terms'),
00225                         f.url(0), '.',
00226                     ]) or ''), "error")
00227         Page(request, pagename).send_page()
00228         return
00229 
00230     # This action generates data using the user language
00231     request.setContentLanguage(request.lang)
00232 
00233     request.theme.send_title(title % needle, pagename=pagename)
00234 
00235     # Start content (important for RTL support)
00236     request.write(request.formatter.startContent("content"))
00237 
00238     # Hints
00239     f = request.formatter
00240     hints = []
00241 
00242     if titlesearch:
00243         querydict = dict(wikiutil.parseQueryString(request.query_string))
00244         querydict.update({'titlesearch': 0})
00245 
00246         hints.append(''.join([
00247             _("(!) You're performing a title search that might not include"
00248                 ' all related results of your search query in this wiki. <<BR>>', wiki=True),
00249             ' ',
00250             f.url(1, href=request.page.url(request, querydict, escape=0)),
00251             f.text(_('Click here to perform a full-text search with your '
00252                 'search terms!')),
00253             f.url(0),
00254         ]))
00255 
00256     if advancedsearch and mtime_msg:
00257         hints.append(mtime_msg)
00258 
00259     if hints:
00260         request.write(searchHints(f, hints))
00261 
00262     # Search stats
00263     request.write(results.stats(request, request.formatter, hitsFrom))
00264 
00265     # Then search results
00266     info = not titlesearch
00267     if context:
00268         output = results.pageListWithContext(request, request.formatter,
00269                 info=info, context=context, hitsFrom=hitsFrom, hitsInfo=1)
00270     else:
00271         output = results.pageList(request, request.formatter, info=info,
00272                 hitsFrom=hitsFrom, hitsInfo=1)
00273 
00274     request.write(output)
00275 
00276     request.write(request.formatter.endContent())
00277     request.theme.send_footer(pagename)
00278     request.theme.send_closing_html()
00279 

Here is the call graph for this function:

Return True if advanced search is requested 

Definition at line 38 of file fullsearch.py.

00038 
00039 def isAdvancedSearch(request):
00040     """ Return True if advanced search is requested """
00041     try:
00042         return int(request.values['advancedsearch'])
00043     except KeyError:
00044         return False
00045 

Here is the caller graph for this function:

def MoinMoin.action.fullsearch.searchHints (   f,
  hints 
)
Return a paragraph showing hints for a search

@param f: the formatter to use
@param hints: list of hints (as strings) to show

Definition at line 46 of file fullsearch.py.

00046 
00047 def searchHints(f, hints):
00048     """ Return a paragraph showing hints for a search
00049 
00050     @param f: the formatter to use
00051     @param hints: list of hints (as strings) to show
00052     """
00053     return ''.join([
00054         f.paragraph(1, attr={'class': 'searchhint'}),
00055         # this is illegal formatter usage anyway, so we can directly use a literal
00056         "<br>".join(hints),
00057         f.paragraph(0),
00058     ])
00059 

Here is the caller graph for this function: