Test coverage for vnccollab.theme.browser.livesearch

vnccollab/      covered 69% (1245 of 4098 uncovered)
    theme/      covered 69% (1245 of 4098 uncovered)
        browser/      covered 74% (507 of 1985 uncovered)
            livesearch.py      covered 96% (5 of 160 uncovered)

    1: from DateTime import DateTime
       
    1: from zope.component import getMultiAdapter
       
    1: from Products.CMFCore.utils import getToolByName
    1: from Products.CMFPlone import PloneMessageFactory as _
    1: from Products.CMFPlone.utils import safe_unicode
    1: from Products.PythonScripts.standard import url_quote_plus
    1: from Products.PythonScripts.standard import html_quote
    1: from Products.CMFPlone.browser.navtree import getNavigationRoot
    1: from Products.Five import BrowserView
       
    1: from vnccollab.common.livesearch import get_query
       
    2: class LiveSearchReplyView(BrowserView):
    1:     def result(self):
    9:         context = self.context
    9:         request = self.request
    9:         response = self.request.response
    9:         q = request.get('q')
    9:         limit = int(request.get('limit', 10))
    9:         path = request.get('path', None)
       
    9:         ploneUtils = getToolByName(context, 'plone_utils')
    9:         portal_url = getToolByName(context, 'portal_url')()
    9:         pretty_title_or_id = ploneUtils.pretty_title_or_id
               #plone_view = context.restrictedTraverse('@@plone')
               #portal_state = context.restrictedTraverse('@@plone_portal_state')
       
    9:         portalProperties = getToolByName(context, 'portal_properties')
    9:         siteProperties = getattr(portalProperties, 'site_properties', None)
    9:         useViewAction = []
    9:         if siteProperties is not None:
    9:             useViewAction = siteProperties.getProperty('typesUseViewActionInListings', [])
       
               # SIMPLE CONFIGURATION
               #USE_ICON = True
    9:         MAX_TITLE = 29
    9:         MAX_DESCRIPTION = 93
       
               # generate a result set for the query
    9:         catalog = context.portal_catalog
       
    9:         mtool = getToolByName(context, 'portal_membership')
       
    9:         friendly_types = ploneUtils.getUserFriendlyTypes()
       
    9:         def quotestring(s):
   18:             return '"%s"' % s
       
    9:         def quote_bad_chars(s):
    9:             bad_chars = ["(", ")"]
   27:             for char in bad_chars:
   18:                 s = s.replace(char, quotestring(char))
    9:             return s
       
    9:         def pretty_date(when):
   36:             result = ('%s %s, %s') % (DateTime(when).strftime('%B'), DateTime(when).strftime('%d'), DateTime(when).strftime('%Y'))
   36:             return result
       
    9:         searchable_text = q
    9:         multispace = u'\u3000'.encode('utf-8')
   54:         for char in ('?', '-', '+', '*', multispace):
   45:             q = q.replace(char, ' ')
    9:         r = q.split()
    9:         r = " AND ".join(r)
    9:         r = quote_bad_chars(r) + '*'
    9:         searchterms = url_quote_plus(r)
       
    9:         site_encoding = context.plone_utils.getSiteEncoding()
       
    9:         params = {'SearchableText': r,
    9:                   'portal_type': friendly_types,
    9:                   'sort_limit': limit + 1}
       
    9:         if path is None:
                   # useful for subsides
    8:             params['path'] = getNavigationRoot(context)
               else:
    1:             params['path'] = path
       
               # search limit+1 results to know if limit is exceeded
    9:         params = get_query(searchable_text, params)
    9:         results = catalog(**params)
       
    9:         searchterm_query = '?searchterm=%s' % url_quote_plus(q)
       
               #request = context.request
               #response = request.response
    9:         response.setHeader('Content-Type', 'text/xml;charset=%s' % site_encoding)
       
               # replace named entities with their numbered counterparts, in the xml the named ones are not correct
               #   ↓      --> ↓
               #   …    --> …
    9:         legend_livesearch = _('legend_livesearch', default='LiveSearch ↓')
    9:         label_no_results_found = _('label_no_results_found', default='No matching results found.')
    9:         label_advanced_search = _('label_advanced_search', default='Advanced Search…')
    9:         label_show_all = _('label_show_all', default='Show all items')
       
    9:         ts = getToolByName(context, 'translation_service')
       
    9:         output = []
       
    9:         def write(s):
  549:             output.append(safe_unicode(s))
       
    9:         if not results:
    2:             write('''<fieldset class="livesearchContainer">''')
    2:             write('''<legend id="livesearchLegend">%s</legend>''' % ts.translate(legend_livesearch, context=request))
    2:             write('''<div class="LSIEFix">''')
    2:             write('''<div id="LSNothingFound">%s</div>''' % ts.translate(label_no_results_found, context=request))
    2:             write('''<ul class="ls-foot">''')
    2:             write('''<li class="LSRow lsrow-adv-search">''')
    2:             write('<b></b><a href="%s" style="font-weight:normal">%s</a>' %
    2:                  (portal_url + '/@@search',
    2:                   ts.translate(label_advanced_search, context=request)))
    2:             write('''</li>''')
    2:             write('''</ul>''')
    2:             write('''</div>''')
    2:             write('''</fieldset>''')
               else:
    7:             write('''<fieldset class="livesearchContainer">''')
    7:             write('''<legend id="livesearchLegend">%s</legend>''' % ts.translate(legend_livesearch, context=request))
    7:             write('''<div class="LSIEFix">''')
    7:             write('''<ul class="LSTable">''')
       
   43:             for result in results[:limit]:
                       # breadcrumbs
   36:                 obj = result.getObject()
   36:                 breadcrumbs_view = getMultiAdapter((obj, request), name='breadcrumbs_view')
   36:                 breadcrumbs = breadcrumbs_view.breadcrumbs()
       
   36:                 ls_breadcrumb = ''
       
   36:                 breadcrumbs_size = len(breadcrumbs) - 1
       
   36:                 if breadcrumbs_size > 0:
   73:                     for ls_key in breadcrumbs[:breadcrumbs_size]:
   42:                         ls_breadcrumb += ('''<a href="%s">%s</a> > ''' % (ls_key['absolute_url'], ls_key['Title']))
       
   36:                 is_folderish = result.is_folderish
       
   36:                 if is_folderish:
   12:                     length_size = len(obj)
                       else:
   24:                     length_size = result.getObjSize
       
                       #icon = plone_view.getIcon(result)
   36:                 img_class = '%s-icon' % ploneUtils.normalizeString(result.portal_type)
       
   36:                 member = mtool.getMemberById(result.Creator)
   36:                 if member is not None:
   36:                     fullname = member.getProperty('fullname')
                       else:
>>>>>> fullname = ''
36: itemUrl = result.getURL() 36: if result.portal_type in useViewAction:
>>>>>> itemUrl += '/view'
36: itemUrl = itemUrl + searchterm_query 36: write('''<li class="LSRow">''') #write(icon.html_tag() or '') 36: write('''<div class="%s ls-content-icon"></div>''' % (img_class)) 36: write('''<div class="ls-details">''') 36: full_title = safe_unicode(pretty_title_or_id(result)) 36: if len(full_title) > MAX_TITLE: 5: display_title = ''.join((full_title[:MAX_TITLE], '...')) else: 31: display_title = full_title 36: full_title = full_title.replace('"', '&quot;') #klass = 'contenttype-%s' % ploneUtils.normalizeString(result.portal_type) 36: klass = 'ls-content-title' 36: write('''<a href="%s" title="%s" class="%s">%s</a>''' % (itemUrl, full_title, klass, display_title)) 36: display_description = safe_unicode(result.Description) 36: if len(display_description) > MAX_DESCRIPTION: 4: display_description = ''.join((display_description[:MAX_DESCRIPTION], '...')) # need to quote it, to avoid injection of html containing javascript and other evil stuff 36: display_description = html_quote(display_description) 36: write('''<div class="LSDescr">%s</div>''' % (display_description)) 36: if breadcrumbs_size > 0: 31: write('''<div class="LSBreadcrumb">in %s</div>''' % (ls_breadcrumb[:-3])) else: 5: write('''<div class="LSBreadcrumb">in Home</div>''') 36: write('''<div class="LSMeta">''') 36: display_type = html_quote(safe_unicode(result.Type)) 36: write('''<span class="LSType">%s</span>''' % (display_type)) 36: if result.Type == 'File' or result.Type == 'Image':
>>>>>> write('''<span class="LSType"> &#8226; %s</span>''' % (length_size))
36: elif result.Type == 'Folder': 12: write('''<span class="LSType"> &#8226; %s item(s)</span>''' % (length_size)) 36: display_creator = html_quote(safe_unicode(fullname)) 36: if len(display_creator) > 0:
>>>>>> write(''' &#8226; Create by <a href="%s/author/%s" class="LSCreator">%s</a>''' %
>>>>>> (portal_url, member.getProperty('id'), display_creator))
36: display_modified = html_quote(safe_unicode((pretty_date(result.modified)))) 36: write('''<span class="LSModified">on %s</span>''' % (display_modified)) 36: write('''</div>''') 36: write('''</div>''') 36: write('''</li>''') 36: full_title, display_title, display_description, display_type = None, None, None, None 7: write('''</ul><ul class="ls-foot">''') 7: if len(results) > limit: # add a more... row 2: write('''<li class="LSRow lsrow-show-all">''') 2: searchquery = '@@search?SearchableText=%s&path=%s' % (searchterms, params['path']) 2: write('<b></b><a href="%s" style="font-weight:normal">%s</a>' % ( 2: searchquery, 2: ts.translate(label_show_all, context=request))) 2: write('''</li>''') 7: write('''<li class="LSRow lsrow-adv-search">''') 7: write('<b></b><a href="%s" style="font-weight:normal">%s</a>' % 7: (portal_url + '/@@search', 7: ts.translate(label_advanced_search, context=request))) 7: write('''</li>''') 7: write('''</ul>''') 7: write('''</div>''') 7: write('''</fieldset>''') 9: return '\n'.join(output).encode(site_encoding)