Author: thimal
Date: Sat Jul 5 17:08:06 2014
New Revision: 1608062
URL: http://svn.apache.org/r1608062
Log:
initial commit for duplicateTicketSearch component
Added:
bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/htdocs/js/DupeSearch.js
(with props)
Modified:
bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/theme.py
Added:
bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/htdocs/js/DupeSearch.js
URL:
http://svn.apache.org/viewvc/bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/htdocs/js/DupeSearch.js?rev=1608062&view=auto
==============================================================================
---
bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/htdocs/js/DupeSearch.js
(added)
+++
bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/htdocs/js/DupeSearch.js
Sat Jul 5 17:08:06 2014
@@ -0,0 +1,70 @@
+$(document).ready(function() {
+
+ $('div#content.ticket h2#vc-summary').blur(function() {
+ var text = $('div#content.ticket h2#vc-summary').text();
+ if (text.length > 0) {
+
+ var html = '<h5 class="loading">Loading related
tickets..</h5>';
+ var dupeticketlistDiv = $('div#content.ticket
h2#vc-summary + div#dupeticketlist');
+ if (dupeticketlistDiv.length == 0) {
+ $('div#content.ticket
h2#vc-summary').after('<div id="dupeticketlist" style="display:none;"></div>');
+ dupeticketlistDiv = $('div#content.ticket
h2#vc-summary + div#dupeticketlist');
+ }
+ $('ul',dupeticketlistDiv).slideUp('fast');
+ dupeticketlistDiv.html(html).slideDown();
+
+ $.ajax({
+ url:'duplicate_ticket_search',
+ data:{q:text},
+ type:'GET',
+
+ success: function(data, status) {
+ var tickets =data;
+ var ticketBaseHref = 'ticket/';
+ var searchBaseHref =
'bhsearch?type=ticket&q=';
+ var maxTickets = 15;
+
+ var html = '';
+ if (tickets === null) {
+ // error
+ dupeticketlistDiv.html('<h5
class="error">Error loading tickets.</h5>');
+ } else if (tickets.length <= 0) {
+ // no dupe tickets
+ dupeticketlistDiv.slideUp();
+ } else {
+ html = '<h5>Possible related
tickets:</h5><ul style="display:none;">'
+ tickets = tickets.reverse();
+
+ for (var i = 0; i <
tickets.length && i < maxTickets; i++) {
+ var ticket = tickets[i];
+ html += '<li
class="highlight_matches" title="' + ticket.description +
+ '"><a
href="' + ticketBaseHref + ticket.url +
+ '"><span
class="' + htmlencode(ticket.status) + '">#' +
+ ticket.url
+ '</span></a>: ' + htmlencode(ticket.type) + ': ' +
+
ticket.summary + '(' + htmlencode(ticket.status) +
+ (ticket.url
? ': ' + htmlencode(ticket.url) : '') +
+ ')' +
'</li>'
+ }
+ html += '</ul>';
+ if (tickets.length >
maxTickets) {
+ var text =
$('div#content.ticket input#field-summary').val();
+ html += '<a href="' +
searchBaseHref + escape(text) + '">More..</a>';
+ }
+
+ dupeticketlistDiv.html(html);
+ $('> ul',
dupeticketlistDiv).slideDown();
+
+ }
+
+ },
+ error: function(xhr, textStatus, exception) {
+ dupeticketlistDiv.html('<h5
class="error">Error loading tickets: ' + textStatus + '</h5>');
+ }
+ });
+ }
+ });
+
+ function htmlencode(text) {
+ return $('<div/>').text(text).html().replace(/"/g,
'"').replace(/'/g, ''');
+ }
+});
Propchange:
bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/htdocs/js/DupeSearch.js
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/theme.py
URL:
http://svn.apache.org/viewvc/bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/theme.py?rev=1608062&r1=1608061&r2=1608062&view=diff
==============================================================================
---
bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/theme.py
(original)
+++
bloodhound/bep_0013_dynamic_clientside_features/bloodhound_theme/bhtheme/theme.py
Sat Jul 5 17:08:06 2014
@@ -27,6 +27,8 @@ 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
@@ -1086,3 +1088,60 @@ class KeywordSuggestModule(Component):
keywords = ''
return keywords
+
+# component to find duplicate tickets
+#DuplicateTicketSearch component basic structure is taken from trac
DuplicateTicketSearch plugin
+#https://trac-hacks.org/wiki/DuplicateTicketSearchPlugin
+class DuplicateTicketSearch(Component):
+ implements(ITemplateProvider, ITemplateStreamFilter,IRequestHandler)
+
+ # ITemplateProvider methods
+
+ def get_htdocs_dirs(self):
+ from pkg_resources import resource_filename
+ return [('duplicateticketsearch', resource_filename(__name__,
'htdocs'))]
+
+ def get_templates_dirs(self):
+ return []
+
+
+ # ITemplateStreamFilter methods
+
+ def filter_stream(self, req, method, filename, stream, data):
+
+ if filename == 'bh_ticket.html':
+ ticket = data.get('ticket')
+ if ticket and not ticket.id: # only add for new tickets
+ add_script(req, 'duplicateticketsearch/js/DupeSearch.js')
+
+ return stream
+
+ # IRequestHandler methods
+
+ def match_request(self, req):
+ """Handle requests sent to /user_list and /ticket/user_list
+ """
+ return req.path_info.rstrip('/') == '/duplicate_ticket_search'
+
+ def process_request(self, req):
+ product = self.env.product._data['prefix']
+ query_result = BloodhoundSearchApi(self.env).query(
+ req.args.get('q'),
+ pagenum=1,
+ pagelen=10,
+ filter=['type:"ticket"', 'product:"'+product+'"'],
+ highlight=True,
+ )
+ ticket_list = []
+ cnt = 0
+ for ticket in query_result.docs:
+ ticket_list.append(to_json({'summary':
query_result.highlighting[cnt]['summary'], 'description':
query_result.highlighting[cnt]['content'],'type':ticket['type']
,'status':ticket['status'] , 'owner':ticket['author']
,'date':ticket['time'].strftime('%m/%d/%Y') ,'url': ticket['id']}))
+ cnt+1
+ str_list = '['+','.join(ticket_list)+']'
+
+ req.send(str_list, 'application/json')
+
+
+
+
+