Author: thimal
Date: Wed Aug  6 18:02:52 2014
New Revision: 1616294

URL: http://svn.apache.org/r1616294
Log:
Improved the duplicate ticket search. Now it search for partial and complete 
phrases enter into the summary in new ticket.
change the keywords suggest : add the query page javascript to separate file, 
change the db use so it can find keywords in query page also.

Modified:
    
bloodhound/branches/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/theme.py

Modified: 
bloodhound/branches/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/theme.py
URL: 
http://svn.apache.org/viewvc/bloodhound/branches/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/theme.py?rev=1616294&r1=1616293&r2=1616294&view=diff
==============================================================================
--- 
bloodhound/branches/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/theme.py
 (original)
+++ 
bloodhound/branches/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/theme.py
 Wed Aug  6 18:02:52 2014
@@ -19,8 +19,9 @@
 
 import sys
 
+import re
+
 from trac.util.datefmt import format_datetime, user_time
-from collections import Counter
 
 import fnmatch
 
@@ -28,8 +29,6 @@ from genshi.builder import tag
 from genshi.core import TEXT, Markup
 from genshi.filters.transform import Transformer
 from genshi.output import DocType
-from bhsearch.api import BloodhoundSearchApi
-from bhsearch.web_ui import RequestContext
 
 from trac.config import ListOption, Option
 from trac.core import Component, TracError, implements
@@ -861,8 +860,7 @@ class KeywordSuggestModule(Component):
             self.log.debug("""
                 No keywords found. KeywordSuggestPlugin is disabled.""")
             keywords = []
-        # data = {'keywords': keywords}
-        # add_script_data(req, data)
+
         if filename == 'bh_ticket.html':
             # add_script(req, 'theme/js/keywordsuggest_ticket.js')
             if req.path_info.startswith('/ticket/'):
@@ -890,61 +888,10 @@ class KeywordSuggestModule(Component):
                         });"""
 
         if filename == 'bh_query.html':
-            js = """jQuery(document).ready(function ($) {
-                          function addAutocompleteBehavior() {
-                            var filters = $('#filters');
-                            var contains = $.contains // jQuery 1.4+
-                              || function (container, contained) {
-                              while (contained !== null) {
-                                if (container === contained)
-                                  return true;
-                                contained = contained.parentNode;
-                              }
-                              return false;
-                            };
-                            var listener = function (event) {
-                              var target = event.target || event.srcElement;
-                              filters.each(function () {
-                                if (contains(this, target)) {
-                                  var input = 
$(this).find('input:text').filter(function () {
-                                    return target === this;
-                                  });
-                                  var name = input.attr('name');
-                                  if (input.attr('autocomplete') !== 'off' &&
-                                    /^(?:[0-9]+_)?(?:keywords)$/.test(name)) {
-                                    input.tagsinput({
-                                        typeahead: {
-                                            source: %(keywords)s
-                                            }
-                                        });
-                                    input.focus(); // XXX Workaround for Trac 
0.12.2 and jQuery 1.4.2
-                                  }
-                                }
-                              });
-                            };
-                            if ($.fn.on) {
-                              // delegate method is available in jQuery 1.7+
-                              filters.on('focusin', 'input:text', listener);
-                            }
-                            else if ($.fn.delegate) {
-                              // delegate method is available in jQuery 1.4.2+
-                              filters.delegate('input:text', 'focus', 
listener);
-                            }
-                            else if (window.addEventListener) {
-                              // use capture=true cause focus event doesn't 
bubble in the default
-                              filters.each(function () {
-                                this.addEventListener('focus', listener, true);
-                              });
-                            }
-                            else {
-                              // focusin event bubbles, the event is avialable 
for IE only
-                              filters.each(function () {
-                                this.attachEvent('onfocusin', listener);
-                              });
-                            }
-                          }
-                          addAutocompleteBehavior();
-                });"""
+            data = {'keywords': keywords}
+            add_script_data(req, data)
+            add_script(req, 'theme/js/keywordsuggest_query.js')
+
         # inject transient part of javascript directly into ticket.html 
template
         if req.path_info.startswith('/ticket/') or \
                 req.path_info.startswith('/newticket'):
@@ -952,9 +899,6 @@ class KeywordSuggestModule(Component):
                               'keywords': keywords
                               }
             stream = stream | 
Transformer('.//head').append(tag.script(Markup(js_ticket), 
type='text/javascript'))
-        if req.path_info.startswith('/query'):
-            js_ticket = js % {'keywords': keywords}
-            stream = stream | 
Transformer('.//head').append(tag.script(Markup(js_ticket), 
type='text/javascript'))
 
         return stream
 
@@ -964,29 +908,30 @@ class KeywordSuggestModule(Component):
         """
         #currently all the keywords are taken through the db query and then 
sort them according to there frequency
         # get keywords from db
-        db = self.env.get_db_cnx()
-        cursor = db.cursor()
         keywords = []
-        if self.env.product is not None:
-            product = self.env.product._data['prefix']
-            product_sql = " AND t.product = '%s'" % product
-        else:
-            product_sql = ""
-        sql = """SELECT t.keywords FROM ticket AS t WHERE t.keywords IS NOT 
null%s""" % product_sql
+        with self.env.db_direct_query as db:
+            cursor = db.cursor()
+
+            if self.env.product is not None:
+                product = self.env.product._data['prefix']
+                product_sql = " AND t.product = '%s'" % product
+            else:
+                product_sql = ""
+            sql = """SELECT t.keywords FROM ticket AS t WHERE t.keywords IS 
NOT null%s""" % product_sql
 
-        cursor.execute(sql)
+            cursor.execute(sql)
 
-        for row in cursor:
-            if not row[0] == '':
-                row_val = str(row[0]).split(',')
-                for val in row_val:
-                    keywords.append(val.strip())
-        # sort keywords according to frequency of occurrence
-        if keywords:
-            keyword_dic = Counter(keywords)
-            keywords = sorted(keyword_dic, key=lambda key: -keyword_dic[key])
-        else:
-            keywords = ''
+            for row in cursor:
+                if not row[0] == '':
+                    row_val = str(row[0]).split(',')
+                    for val in row_val:
+                        keywords.append(val.strip())
+            # sort keywords according to frequency of occurrence
+            if keywords:
+                keyword_dic = {keyword: keywords.count(keyword) for keyword in 
keywords}
+                keywords = sorted(keyword_dic, key=lambda key: 
-keyword_dic[key])
+            else:
+                keywords = ''
 
         return keywords
 
@@ -1001,6 +946,7 @@ class DuplicateTicketSearch(Component):
     # ITemplateStreamFilter methods
 
     def filter_stream(self, req, method, filename, stream, data):
+
         add_script(req, 'theme/js/popoverDupSearch.js')
 
         if filename == 'bh_ticket.html':
@@ -1015,15 +961,17 @@ class DuplicateTicketSearch(Component):
     def match_request(self, req):
         """Handle requests sent to /user_list and /ticket/user_list
         """
-        return req.path_info.rstrip('/') == '/duplicate_ticket_search'
+        return re.match('.*/duplicate_ticket_search$', req.path_info)
 
     def process_request(self, req):
-        terms = req.args.get('q').split(' ')
+
+        terms = self._terms_to_search(req)
+        term_split = req.args.get('q').split(' ')
 
         with self.env.db_direct_query as db:
-            sql, args = self._search_to_sql(db, ['summary', 'keywords', 
'description'], terms)
-            sql2, args2 = self._search_to_sql(db, ['newvalue'], terms)
-            sql3, args3 = self._search_to_sql(db, ['value'], terms)
+            sql, args = self._sql_to_search(db, ['summary', 'keywords', 
'description'], terms)
+            sql2, args2 = self._sql_to_search(db, ['newvalue'], terms)
+            sql3, args3 = self._sql_to_search(db, ['value'], terms)
             if self.env.product is not None:
                 product_sql = "product='%s' AND" % 
self.env.product._data['prefix']
             else:
@@ -1048,9 +996,9 @@ class DuplicateTicketSearch(Component):
                 summary_term_count = 0
                 summary_list = summary.split(' ')
                 for s in summary_list:
-                    for t in terms:
+                    for t in term_split:
                         if s.lower() == t.lower():
-                            summary = summary.replace(s,'<em>'+t+'</em>')
+                            summary = summary.replace(s, '<em>'+t+'</em>')
                             summary_term_count += 1
                             break
 
@@ -1064,7 +1012,7 @@ class DuplicateTicketSearch(Component):
 
     # Private methods
 
-    def _search_to_sql(self, db, columns, terms):
+    def _sql_to_search(self, db, columns, terms):
         """Convert a search query into an SQL WHERE clause and corresponding
         parameters.
 
@@ -1080,17 +1028,22 @@ class DuplicateTicketSearch(Component):
             args.extend(['%' + db.like_escape(t) + '%'] * len(columns))
         return sql, tuple(args)
 
+    def _terms_to_search(self, req):
+        """Convert a search query into different terms to search.
 
+        The result is returned as a list of terms.
+        """
+        search_string = req.args.get('q')
+        terms = [search_string]
+        temp_string = search_string
+        search_string_split = search_string.split(' ')
+
+        for i in range(len(search_string_split)-3):
+            search_string = re.sub('^'+search_string_split[i]+' ', '', 
search_string)
+            terms.append(search_string)
+        search_string = temp_string
+        for i in reversed(xrange(3, len(search_string_split))):
+            search_string = re.sub(' '+search_string_split[i]+'$', '', 
search_string)
+            terms.append(search_string)
 
-
-
-
-
-
-
-
-
-
-
-
-
+        return terms
\ No newline at end of file


Reply via email to