bloodhound-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pe...@apache.org
Subject svn commit: r1455845 - in /incubator/bloodhound/trunk/bloodhound_search/bhsearch: api.py query_parser.py search_resources/ticket_search.py templates/bhsearch.html tests/__init__.py tests/query_parser.py tests/web_ui.py web_ui.py whoosh_backend.py
Date Wed, 13 Mar 2013 09:14:01 GMT
Author: peter
Date: Wed Mar 13 09:14:01 2013
New Revision: 1455845

URL: http://svn.apache.org/r1455845
Log:
#421 - search metakeywords $me and $my

Modified:
    incubator/bloodhound/trunk/bloodhound_search/bhsearch/api.py
    incubator/bloodhound/trunk/bloodhound_search/bhsearch/query_parser.py
    incubator/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/ticket_search.py
    incubator/bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch.html
    incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/__init__.py
    incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/query_parser.py
    incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/web_ui.py
    incubator/bloodhound/trunk/bloodhound_search/bhsearch/web_ui.py
    incubator/bloodhound/trunk/bloodhound_search/bhsearch/whoosh_backend.py

Modified: incubator/bloodhound/trunk/bloodhound_search/bhsearch/api.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_search/bhsearch/api.py?rev=1455845&r1=1455844&r2=1455845&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_search/bhsearch/api.py (original)
+++ incubator/bloodhound/trunk/bloodhound_search/bhsearch/api.py Wed Mar 13 09:14:01 2013
@@ -186,7 +186,7 @@ class IQueryParser(Interface):
     """Extension point for Bloodhound Search query parser.
     """
 
-    def parse(query_string):
+    def parse(query_string, context):
         """Parse query from string"""
 
     def parse_filters(filters):
@@ -219,7 +219,7 @@ class IQueryPreprocessor(Interface):
 class IMetaKeywordParser(Interface):
     """Extension point for custom meta keywords."""
 
-    def match(text):
+    def match(text, context):
         """If text matches the keyword, return its transformed value."""
 
 
@@ -255,7 +255,8 @@ class BloodhoundSearchApi(Component):
             pagenum = 1,
             pagelen = 20,
             highlight = False,
-            highlight_fields = None):
+            highlight_fields = None,
+            context = None):
         """Return query result from an underlying search backend.
 
         Arguments:
@@ -271,12 +272,13 @@ class BloodhoundSearchApi(Component):
         :param pagelen: paging support
         :param highlight: highlight matched terms in fields
         :param highlight_fields: list of fields to highlight
+        :param context: request context
 
         :return: result QueryResult
         """
         self.env.log.debug("Receive query request: %s", locals())
 
-        parsed_query = self.parser.parse(query)
+        parsed_query = self.parser.parse(query, context)
 
         parsed_filters = self.parser.parse_filters(filter)
         # TODO: add query parsers and meta keywords post-parsing

Modified: incubator/bloodhound/trunk/bloodhound_search/bhsearch/query_parser.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_search/bhsearch/query_parser.py?rev=1455845&r1=1455844&r2=1455845&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_search/bhsearch/query_parser.py (original)
+++ incubator/bloodhound/trunk/bloodhound_search/bhsearch/query_parser.py Wed Mar 13 09:14:01
2013
@@ -39,9 +39,10 @@ class MetaKeywordPlugin(qparser.TaggingP
     expr = r"[$](?P<text>[^ \t\r\n]+)(?= |$|\))"
     nodetype = qparser.syntax.WordNode
 
-    def __init__(self, meta_keyword_parsers=()):
+    def __init__(self, meta_keyword_parsers=(), context=None):
         super(MetaKeywordPlugin, self).__init__()
         self.meta_keyword_parsers = meta_keyword_parsers
+        self.context = context
 
     def match(self, parser, text, pos):
         match = qparser.TaggingPlugin.match(self, parser, text, pos)
@@ -50,7 +51,8 @@ class MetaKeywordPlugin(qparser.TaggingP
 
         candidate = match.text
         for meta_keyword_parser in self.meta_keyword_parsers:
-            expanded_meta_keyword = meta_keyword_parser.match(candidate)
+            expanded_meta_keyword = meta_keyword_parser.match(candidate,
+                                                              self.context)
             if expanded_meta_keyword is not None:
                 node = MetaKeywordNode(parser.tag(expanded_meta_keyword))
                 return node.set_range(match.startchar, match.endchar)
@@ -91,28 +93,13 @@ class DefaultQueryParser(Component):
 
     meta_keyword_parsers = ExtensionPoint(IMetaKeywordParser)
 
-    def __init__(self):
-        super(DefaultQueryParser, self).__init__()
-        self.parser = MultifieldParser(
-            self.field_boosts.keys(),
-            WhooshBackend.SCHEMA,
-            fieldboosts=self.field_boosts
-        )
-        self.parser.add_plugin(
-            MetaKeywordPlugin(meta_keyword_parsers=self.meta_keyword_parsers)
-        )
-
-    def parse(self, query_string):
+    def parse(self, query_string, context=None):
+        parser = self._create_parser(context)
         query_string = query_string.strip()
-
         if query_string == "" or query_string == "*" or query_string == "*:*":
             return query.Every()
-
         query_string = unicode(query_string)
-        parsed_query = self.parser.parse(query_string)
-
-        #todo: impalement pluggable mechanism for query post processing
-        #e.g. meta keyword replacement etc.
+        parsed_query = parser.parse(query_string)
         return parsed_query
 
     def parse_filters(self, filters):
@@ -125,13 +112,25 @@ class DefaultQueryParser(Component):
     def _parse_filter(self, filter):
         return self.parse(unicode(filter))
 
+    def _create_parser(self, context):
+        parser = MultifieldParser(
+            self.field_boosts.keys(),
+            WhooshBackend.SCHEMA,
+            fieldboosts=self.field_boosts
+        )
+        parser.add_plugin(
+            MetaKeywordPlugin(meta_keyword_parsers=self.meta_keyword_parsers,
+                              context=context)
+        )
+        return parser
+
 
 class DocTypeMetaKeywordParser(Component):
     implements(IMetaKeywordParser)
 
     search_participants = ExtensionPoint(ISearchParticipant)
 
-    def match(self, text):
+    def match(self, text, context):
         documents = [p.get_participant_type()
                      for p in self.search_participants]
         if text in documents:
@@ -141,7 +140,7 @@ class DocTypeMetaKeywordParser(Component
 class ResolvedMetaKeywordParser(Component):
     implements(IMetaKeywordParser)
 
-    def match(self, text):
+    def match(self, text, context):
         if text == u'resolved':
             return u'status:(resolved OR closed)'
 
@@ -149,7 +148,23 @@ class ResolvedMetaKeywordParser(Componen
 class UnResolvedMetaKeywordParser(Component):
     implements(IMetaKeywordParser)
 
-    def match(self, text):
+    def match(self, text, context):
         if text == u'unresolved':
             return u'NOT $resolved'
 
+
+class MeMetaKeywordParser(Component):
+    implements(IMetaKeywordParser)
+
+    def match(self, text, context):
+        if text == u'me':
+            username = unicode(context.req.authname)
+            return username
+
+
+class MyMetaKeywordParser(Component):
+    implements(IMetaKeywordParser)
+
+    def match(self, text, context):
+        if text == u'my':
+            return u'owner:$me'

Modified: incubator/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/ticket_search.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/ticket_search.py?rev=1455845&r1=1455844&r2=1455845&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/ticket_search.py
(original)
+++ incubator/bloodhound/trunk/bloodhound_search/bhsearch/search_resources/ticket_search.py
Wed Mar 13 09:14:01 2013
@@ -39,6 +39,7 @@ class TicketFields(IndexFields):
     KEYWORDS = "keywords"
     RESOLUTION = "resolution"
     CHANGES = 'changes'
+    OWNER = 'owner'
 
 class TicketIndexer(BaseIndexer):
     implements(ITicketChangeListener, IIndexParticipant)
@@ -52,6 +53,7 @@ class TicketIndexer(BaseIndexer):
         'status': TicketFields.STATUS,
         'resolution': TicketFields.RESOLUTION,
         'reporter': TicketFields.AUTHOR,
+        'owner': TicketFields.OWNER,
     }
 
     def __init__(self):

Modified: incubator/bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch.html?rev=1455845&r1=1455844&r2=1455845&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch.html (original)
+++ incubator/bloodhound/trunk/bloodhound_search/bhsearch/templates/bhsearch.html Wed Mar
13 09:14:01 2013
@@ -182,7 +182,6 @@
         </div>
       </div>
 
-
       <div class="span12"
           py:if="query and not (results or quickjump)">
         <p id="notfound" class="alert">
@@ -190,6 +189,12 @@
         </p>
       </div>
 
+      <div py:if="debug.enabled" class="span12">
+        <p>DEBUG INFO:
+        <pre>${pprint(debug)}</pre>
+        </p>
+      </div>
+
       <div id="help" class="help-block pull-right" i18n:msg="">
         <strong>Note:</strong> See <a href="${href.wiki('BloodhoundSearch')}">BloodhoundSearch</a>
         for help on searching.

Modified: incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/__init__.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/__init__.py?rev=1455845&r1=1455844&r2=1455845&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/__init__.py (original)
+++ incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/__init__.py Wed Mar 13 09:14:01
2013
@@ -29,6 +29,7 @@ def suite():
     test_suite.addTest(whoosh_backend.suite())
     test_suite.addTest(web_ui.suite())
     test_suite.addTest(api.suite())
+    test_suite.addTest(query_parser.suite())
     test_suite.addTest(ticket_search.suite())
     test_suite.addTest(wiki_search.suite())
     test_suite.addTest(milestone_search.suite())

Modified: incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/query_parser.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/query_parser.py?rev=1455845&r1=1455844&r2=1455845&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/query_parser.py (original)
+++ incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/query_parser.py Wed Mar 13
09:14:01 2013
@@ -69,6 +69,26 @@ class MetaKeywordsParsingTestCase(BaseBl
                              )
                          ]))
 
+    def test_can_parse_keyword_me(self):
+        context = self._mock_context_with_username('username')
+
+        parsed_query = self.parser.parse("author:$me", context)
+
+        self.assertEqual(parsed_query, terms.Term('author', 'username'))
+
+    def test_can_parse_keyword_my(self):
+        context = self._mock_context_with_username('username')
+
+        parsed_query = self.parser.parse("$my", context)
+
+        self.assertEqual(parsed_query, terms.Term('owner', 'username'))
+
+    def _mock_context_with_username(self, username):
+        class context:
+            class req:
+                authname = username
+        return context
+
 
 def suite():
     test_suite = unittest.TestSuite()

Modified: incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/web_ui.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/web_ui.py?rev=1455845&r1=1455844&r2=1455845&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/web_ui.py (original)
+++ incubator/bloodhound/trunk/bloodhound_search/bhsearch/tests/web_ui.py Wed Mar 13 09:14:01
2013
@@ -140,8 +140,8 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
         #act
         data = self.process_request()
         #assert
-        active_type = data["active_type"]
-        self.assertEquals("ticket", active_type)
+        extra_search_options = dict(data["extra_search_fields"])
+        self.assertEquals("ticket", extra_search_options['type'])
 
         resource_types = data["types"]
 
@@ -513,7 +513,8 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
         self.req.args[RequestParameters.VIEW] = "grid"
         data = self.process_request()
         #assert
-        self.assertEqual("grid", data["active_view"])
+        extra_search_options = dict(data["extra_search_fields"])
+        self.assertEqual("grid", extra_search_options["view"])
 
     def test_can_apply_sorting(self):
         #arrange
@@ -585,9 +586,9 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
 
         data = self.process_request()
         #assert
-        active_sort = data["active_sort"]
-        self.assertEquals("id, time desc", active_sort["expression"])
-        self.assertNotIn("sort=", active_sort["href"])
+        extra_search_options = dict(data["extra_search_fields"])
+        self.assertEquals("id, time desc", extra_search_options["sort"])
+        #self.assertNotIn("sort=", active_sort["href"])
 
     def test_that_document_summary_contains_highlighted_search_terms(self):
         term = "searchterm"

Modified: incubator/bloodhound/trunk/bloodhound_search/bhsearch/web_ui.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_search/bhsearch/web_ui.py?rev=1455845&r1=1455844&r2=1455845&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_search/bhsearch/web_ui.py (original)
+++ incubator/bloodhound/trunk/bloodhound_search/bhsearch/web_ui.py Wed Mar 13 09:14:01 2013
@@ -60,6 +60,7 @@ class RequestParameters(object):
     FILTER_QUERY = "fq"
     VIEW = "view"
     SORT = "sort"
+    DEBUG = "debug"
 
     def __init__(self, req):
         self.req = req
@@ -85,6 +86,7 @@ class RequestParameters(object):
             DEFAULT_RESULTS_PER_PAGE))
         self.page = int(req.args.getfirst(self.PAGE, '1'))
         self.type = req.args.getfirst(self.TYPE)
+        self.debug = int(req.args.getfirst(self.DEBUG, '0'))
 
         self.params = {
             RequestParameters.FILTER_QUERY: []
@@ -106,6 +108,8 @@ class RequestParameters(object):
             self.params[RequestParameters.FILTER_QUERY] = self.filter_queries
         if self.sort_string:
             self.params[RequestParameters.SORT] = self.sort_string
+        if self.debug:
+            self.params[RequestParameters.DEBUG] = self.debug
 
     def _parse_sort(self, sort_string):
         if not sort_string:
@@ -284,6 +288,7 @@ class BloodhoundSearchModule(Component):
             facets=request_context.facets,
             filter=request_context.query_filter,
             highlight=True,
+            context=request_context,
         )
 
         request_context.process_results(query_result)
@@ -649,6 +654,9 @@ class RequestContext(object):
         self._prepare_result_facet_counts(query_result.facets)
         self._prepare_breadcrumbs_template()
         self.data[self.DATA_DEBUG] = query_result.debug
+        if self.parameters.debug:
+            self.data[self.DATA_DEBUG]['enabled'] = True
+            self.data[self.DATA_SEARCH_EXTRAS].append(('debug', '1'))
         self.data[self.DATA_PAGE_HREF] = self.parameters.create_href()
 
     def _prepare_result_facet_counts(self, result_facets):

Modified: incubator/bloodhound/trunk/bloodhound_search/bhsearch/whoosh_backend.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/trunk/bloodhound_search/bhsearch/whoosh_backend.py?rev=1455845&r1=1455844&r2=1455845&view=diff
==============================================================================
--- incubator/bloodhound/trunk/bloodhound_search/bhsearch/whoosh_backend.py (original)
+++ incubator/bloodhound/trunk/bloodhound_search/bhsearch/whoosh_backend.py Wed Mar 13 09:14:01
2013
@@ -69,7 +69,9 @@ class WhooshBackend(Component):
         content=TEXT(stored=True,
                      analyzer=analysis.StandardAnalyzer(stoplist=None)),
         changes=TEXT(analyzer=analysis.StandardAnalyzer(stoplist=None)),
-        )
+        owner=TEXT(stored=True,
+                   analyzer=analysis.SimpleAnalyzer()),
+    )
 
     max_fragment_size = IntOption('bhsearch', 'max_fragment_size', 240,
                                'The maximum number of characters allowed in a '
@@ -224,6 +226,11 @@ class WhooshBackend(Component):
                                             fields,
                                             highlight_fields,
                                             query_parameters)
+            try:
+                results.debug['actual_query'] = unicode(query.simplify(searcher))
+            except TypeError:
+                # Simplify has a bug that causes it to fail sometimes.
+                pass
         return results
 
     def _workaround_join_query_and_filter(



Mime
View raw message