You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bloodhound.apache.org by ju...@apache.org on 2013/02/27 13:52:43 UTC
svn commit: r1450762 [3/3] - in
/incubator/bloodhound/branches/bep_0003_multiproduct: ./
bloodhound_dashboard/ bloodhound_dashboard/bhdashboard/htdocs/css/
bloodhound_dashboard/bhdashboard/htdocs/img/
bloodhound_dashboard/bhdashboard/htdocs/js/ bloodho...
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/base.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/base.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/base.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/base.py Wed Feb 27 12:52:42 2013
@@ -19,8 +19,11 @@
# under the License.
r"""Base classes for Bloodhound Search plugin."""
-from trac.core import Component
-from trac.config import BoolOption
+import re
+
+from bhsearch.api import ISearchWikiSyntaxFormatter
+from trac.core import Component, implements
+from trac.config import BoolOption, ExtensionOption
class BaseIndexer(Component):
"""
@@ -29,6 +32,12 @@ class BaseIndexer(Component):
silence_on_error = BoolOption('bhsearch', 'silence_on_error', "True",
"""If true, do not throw an exception during indexing a resource""")
+ wiki_formatter = ExtensionOption('bhsearch', 'wiki_syntax_formatter',
+ ISearchWikiSyntaxFormatter, 'SimpleSearchWikiSyntaxFormatter',
+ 'Name of the component implementing wiki syntax to text formatter \
+ interface: ISearchWikiSyntaxFormatter.')
+
+
class BaseSearchParticipant(Component):
default_view = None
@@ -52,4 +61,26 @@ class BaseSearchParticipant(Component):
return (not req or self.required_permission in req.perm)
def get_participant_type(self):
- return self.participant_type
\ No newline at end of file
+ return self.participant_type
+
+class SimpleSearchWikiSyntaxFormatter(Component):
+ """
+ This class provide very naive formatting of wiki syntax to text
+ appropriate for indexing and search result presentation.
+ A lot of things can be improved here.
+ """
+ implements(ISearchWikiSyntaxFormatter)
+
+ STRIP_CHARS = re.compile(r'([=#\'\"\*/])')
+ REPLACE_CHARS = re.compile(r'([=#\[\]\{\}|])')
+
+ WHITE_SPACE_RE = re.compile(r'([\s]+)')
+ def format(self, wiki_content):
+ if not wiki_content:
+ return wiki_content
+ intermediate = self.STRIP_CHARS.sub("", wiki_content)
+ intermediate = self.REPLACE_CHARS.sub(" ", intermediate)
+ result = self.WHITE_SPACE_RE.sub(" ", intermediate)
+ return result.strip()
+
+
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/milestone_search.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/milestone_search.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/milestone_search.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/milestone_search.py Wed Feb 27 12:52:42 2013
@@ -23,6 +23,7 @@ from bhsearch import BHSEARCH_CONFIG_SEC
from bhsearch.api import (IIndexParticipant, BloodhoundSearchApi, IndexFields,
ISearchParticipant)
from bhsearch.search_resources.base import BaseIndexer, BaseSearchParticipant
+from bhsearch.search_resources.ticket_search import TicketIndexer
from trac.ticket import IMilestoneChangeListener, Milestone
from trac.config import ListOption, Option
from trac.core import implements
@@ -64,11 +65,13 @@ class MilestoneIndexer(BaseIndexer):
raise
def _rename_milestone(self, milestone, old_name):
- #todo: reindex tickets that are referencing the renamed milestone
try:
doc = self.build_doc(milestone)
search_api = BloodhoundSearchApi(self.env)
- search_api.change_doc_id(doc, old_name)
+ with search_api.start_operation() as operation_context:
+ search_api.change_doc_id(doc, old_name, operation_context)
+ TicketIndexer(self.env).reindex_tickets(
+ search_api, operation_context, milestone=milestone.name)
except Exception, e:
if self.silence_on_error:
self.log.error("Error occurs during renaming milestone from \
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/ticket_search.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/ticket_search.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/ticket_search.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/ticket_search.py Wed Feb 27 12:52:42 2013
@@ -24,7 +24,7 @@ from bhsearch.api import ISearchParticip
IIndexParticipant, IndexFields
from bhsearch.search_resources.base import BaseIndexer, BaseSearchParticipant
from genshi.builder import tag
-from trac.ticket.api import ITicketChangeListener
+from trac.ticket.api import ITicketChangeListener, TicketSystem
from trac.ticket import Ticket
from trac.ticket.query import Query
from trac.config import ListOption, Option
@@ -54,6 +54,10 @@ class TicketIndexer(BaseIndexer):
'reporter': TicketFields.AUTHOR,
}
+ def __init__(self):
+ self.fields = TicketSystem(self.env).get_ticket_fields()
+ self.text_area_fields = set(
+ f['name'] for f in self.fields if f['type'] =='textarea')
#ITicketChangeListener methods
def ticket_created(self, ticket):
@@ -77,14 +81,35 @@ class TicketIndexer(BaseIndexer):
else:
raise
+ def reindex_tickets(self, search_api, operation_context, milestone=None):
+ for ticket in self._fetch_tickets(milestone):
+ self._index_ticket(ticket, search_api, operation_context)
+
+ def _fetch_tickets(self, milestone = None):
+# with self.env.db_transaction as db:
+ for ticket_id in self._fetch_ids(milestone):
+ yield Ticket(self.env, ticket_id)
+
+ def _fetch_ids(self, milestone):
+ sql = "SELECT id FROM ticket"
+ args = []
+ conditions = []
+ if milestone:
+ args.append(milestone)
+ conditions.append("milestone=%s")
+ if conditions:
+ sql = sql + " WHERE " + " AND ".join(conditions)
+ for row in self.env.db_query(sql, args):
+ yield int(row[0])
+
+
def _index_ticket(
- self,
- ticket,
- ):
+ self, ticket, search_api = None, operation_context = None):
try:
- search_api = BloodhoundSearchApi(self.env)
+ if not search_api:
+ search_api = BloodhoundSearchApi(self.env)
doc = self.build_doc(ticket)
- search_api.add_doc(doc)
+ search_api.add_doc(doc, operation_context)
except Exception, e:
if self.silence_on_error:
self.log.error("Error occurs during ticket indexing. \
@@ -103,17 +128,18 @@ class TicketIndexer(BaseIndexer):
for field, index_field in self.optional_fields.iteritems():
if field in ticket.values:
- doc[index_field] = ticket.values[field]
+ field_content = ticket.values[field]
+ if field in self.text_area_fields:
+ field_content = self.wiki_formatter.format(field_content)
+ doc[index_field] = field_content
doc[TicketFields.CHANGES] = u'\n\n'.join(
- [x[4] for x in ticket.get_changelog() if x[2] == u'comment'])
+ [self.wiki_formatter.format(x[4]) for x in ticket.get_changelog()
+ if x[2] == u'comment'])
return doc
def get_entries_for_index(self):
- #is there any better way to get all tickets?
- query_records = self._load_ticket_ids()
- for record in query_records:
- ticket = Ticket(self.env, record["id"])
+ for ticket in self._fetch_tickets():
yield self.build_doc(ticket)
def _load_ticket_ids(self):
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/wiki_search.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/wiki_search.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/wiki_search.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/search_resources/wiki_search.py Wed Feb 27 12:52:42 2013
@@ -99,7 +99,7 @@ class WikiIndexer(BaseIndexer):
IndexFields.TYPE: WIKI_TYPE,
IndexFields.TIME: page.time,
IndexFields.AUTHOR: page.author,
- IndexFields.CONTENT: page.text,
+ IndexFields.CONTENT: self.wiki_formatter.format(page.text),
}
return doc
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/__init__.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/__init__.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/__init__.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/__init__.py Wed Feb 27 12:52:42 2013
@@ -21,7 +21,7 @@ import unittest
from bhsearch.tests import (whoosh_backend, index_with_whoosh, web_ui,
api)
from bhsearch.tests.search_resources import (ticket_search, wiki_search,
- milestone_search)
+ milestone_search, base)
def suite():
test_suite = unittest.TestSuite()
@@ -32,6 +32,7 @@ def suite():
test_suite.addTest(ticket_search.suite())
test_suite.addTest(wiki_search.suite())
test_suite.addTest(milestone_search.suite())
+ test_suite.addTest(base.suite())
return test_suite
if __name__ == '__main__':
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/base.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/base.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/base.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/base.py Wed Feb 27 12:52:42 2013
@@ -38,7 +38,7 @@ class BaseBloodhoundSearchTest(unittest.
def setUp(self, enabled = None, create_req = False):
if not enabled:
- enabled = ['bhsearch.*']
+ enabled = ['trac.*', 'bhsearch.*']
self.env = EnvironmentStub(enable=enabled)
self.env.path = tempfile.mkdtemp('bhsearch-tempenv')
self.env.config.set('bhsearch', 'silence_on_error', "False")
@@ -75,7 +75,8 @@ class BaseBloodhoundSearchTest(unittest.
def insert_ticket(self, summary, **kw):
"""Helper for inserting a ticket into the database"""
ticket = self.create_ticket(summary, **kw)
- return ticket.insert()
+ ticket.insert()
+ return ticket
def create_wiki(self, name, text, **kw):
page = WikiPage(self.env, name)
@@ -93,7 +94,8 @@ class BaseBloodhoundSearchTest(unittest.
milestone = self.create_milestone(
name = name,
description = description)
- return milestone.insert()
+ milestone.insert()
+ return milestone
def create_milestone(self, name, description = None):
milestone = Milestone(self.env)
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/index_with_whoosh.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/index_with_whoosh.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/index_with_whoosh.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/index_with_whoosh.py Wed Feb 27 12:52:42 2013
@@ -17,7 +17,6 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-from contextlib import closing
import unittest
import shutil
@@ -25,10 +24,7 @@ from bhsearch.api import BloodhoundSearc
from bhsearch.search_resources.milestone_search import MilestoneIndexer
from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.search_resources.ticket_search import TicketIndexer
-
from bhsearch.whoosh_backend import WhooshBackend
-from trac.test import MockPerm
-from trac.web import Href
class IndexWhooshTestCase(BaseBloodhoundSearchTest):
def setUp(self):
@@ -116,59 +112,9 @@ class IndexWhooshTestCase(BaseBloodhound
self.print_result(results)
self.assertEqual(2, results.hits)
-class FormattingTestCase(BaseBloodhoundSearchTest):
- def setUp(self):
- super(FormattingTestCase, self).setUp(
- ['trac.*', 'bhsearch.*'],
- create_req=True,
- )
-
- def test_can_format_wiki_to_text(self):
- wiki_content = """= Header #overview
-
- '''bold''', ''italic'', '''''Wikipedia style'''''
-
- {{{
- code
- }}}
-
- [[PageOutline]]
-
- || '''Table''' || sampe ||
-
- - list
- - sample
-
- [[Image(mockup_tickets.png)]] [wiki:SomePage p1] [ticket:1 ticket one]
- http://www.edgewall.com/,
- [http://www.edgewall.com Edgewall Software]
-
- [#point1]
- """
-# wiki_content = """
-#'''''one''''', '''''two''''', '''''three''''', '''''four'''''
-# """
-
- page = self.create_wiki("Dummy wiki", wiki_content)
- from trac.mimeview.api import RenderingContext
- context = RenderingContext(
- page.resource,
- href=Href('/'),
- perm=MockPerm(),
- )
- context.req = None # 1.0 FIXME .req shouldn't be required by formatter
-# result = format_to_oneliner(self.env, context, wiki_content)
-# from trac.wiki.formatter import format_to_oneliner
- from trac.web.chrome import format_to_html
- result = format_to_html(self.env, context, wiki_content)
- print result
-#
-
-
def suite():
test_suite = unittest.TestSuite()
test_suite.addTest(unittest.makeSuite(IndexWhooshTestCase, 'test'))
- test_suite.addTest(unittest.makeSuite(FormattingTestCase, 'test'))
return test_suite
if __name__ == '__main__':
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py Wed Feb 27 12:52:42 2013
@@ -121,6 +121,55 @@ class MilestoneIndexerEventsTestCase(Bas
self.assertEqual(self.DUMMY_MILESTONE_NAME, doc["id"])
self.assertEqual("milestone", doc["type"])
+ def test_that_tickets_updated_after_milestone_renaming(self):
+ #asser
+ INITIAL_MILESTONE = "initial_milestone"
+ RENAMED_MILESTONE = "renamed_name"
+ milestone = self.insert_milestone(INITIAL_MILESTONE)
+ self.insert_ticket("T1", milestone=INITIAL_MILESTONE)
+ self.insert_ticket("T2", milestone=INITIAL_MILESTONE)
+ #act
+ milestone.name = RENAMED_MILESTONE
+ milestone.update()
+ #assert
+ results = self.search_api.query("type:ticket")
+ self.print_result(results)
+ self.assertEqual(2, results.hits)
+ self.assertEqual(RENAMED_MILESTONE, results.docs[0]["milestone"])
+ self.assertEqual(RENAMED_MILESTONE, results.docs[1]["milestone"])
+
+ def test_that_tickets_updated_after_milestone_delete_no_retarget(self):
+ #asser
+ INITIAL_MILESTONE = "initial_milestone"
+ milestone = self.insert_milestone(INITIAL_MILESTONE)
+ self.insert_ticket("T1", milestone=INITIAL_MILESTONE)
+ self.insert_ticket("T2", milestone=INITIAL_MILESTONE)
+ #act
+ milestone.delete()
+ #assert
+ results = self.search_api.query("type:ticket")
+ self.print_result(results)
+ self.assertEqual(2, results.hits)
+ self.assertNotIn("milestone", results.docs[0])
+ self.assertNotIn("milestone", results.docs[1])
+
+ def test_that_tickets_updated_after_milestone_delete_with_retarget(self):
+ #asser
+ INITIAL_MILESTONE = "initial_milestone"
+ RETARGET_MILESTONE = "retarget_milestone"
+ milestone = self.insert_milestone(INITIAL_MILESTONE)
+ self.insert_milestone(RETARGET_MILESTONE)
+ self.insert_ticket("T1", milestone=INITIAL_MILESTONE)
+ self.insert_ticket("T2", milestone=INITIAL_MILESTONE)
+ #act
+ milestone.delete(retarget_to=RETARGET_MILESTONE)
+ #assert
+ results = self.search_api.query("type:ticket")
+ self.print_result(results)
+ self.assertEqual(2, results.hits)
+ self.assertEqual(RETARGET_MILESTONE, results.docs[0]["milestone"])
+ self.assertEqual(RETARGET_MILESTONE, results.docs[1]["milestone"])
+
class MilestoneSearchParticipantTestCase(BaseBloodhoundSearchTest):
def setUp(self):
super(MilestoneSearchParticipantTestCase, self).setUp()
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py Wed Feb 27 12:52:42 2013
@@ -18,20 +18,23 @@
# specific language governing permissions and limitations
# under the License.
import unittest
+from bhsearch.api import BloodhoundSearchApi
from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.search_resources.ticket_search import TicketIndexer
-class TicketIndexerSilenceOnExceptionTestCase(BaseBloodhoundSearchTest):
+class TicketIndexerTestCase(BaseBloodhoundSearchTest):
def setUp(self):
- super(TicketIndexerSilenceOnExceptionTestCase, self).setUp()
- self.env.config.set('bhsearch', 'silence_on_error', "True")
+ super(TicketIndexerTestCase, self).setUp()
self.ticket_indexer = TicketIndexer(self.env)
+ self.search_api = BloodhoundSearchApi(self.env)
+ self.env.config.set('bhsearch', 'silence_on_error', "False")
def tearDown(self):
pass
def test_does_not_raise_exception_by_default(self):
+ self.env.config.set('bhsearch', 'silence_on_error', "True")
self.ticket_indexer.ticket_created(None)
def test_raise_exception_if_configured(self):
@@ -41,9 +44,17 @@ class TicketIndexerSilenceOnExceptionTes
self.ticket_indexer.ticket_created,
None)
+ def test_can_strip_wiki_syntax(self):
+ #act
+ self.insert_ticket("T1", description=" = Header")
+ #assert
+ results = self.search_api.query("*:*")
+ self.print_result(results)
+ self.assertEqual(1, results.hits)
+ self.assertEqual("Header", results.docs[0]["content"])
def suite():
- return unittest.makeSuite(TicketIndexerSilenceOnExceptionTestCase, 'test')
+ return unittest.makeSuite(TicketIndexerTestCase, 'test')
if __name__ == '__main__':
unittest.main()
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/wiki_search.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/wiki_search.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/wiki_search.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/search_resources/wiki_search.py Wed Feb 27 12:52:42 2013
@@ -128,6 +128,16 @@ class WikiIndexerEventsTestCase(BaseBloo
self.assertEqual(1, results.hits)
self.assertEqual("version1", results.docs[0]["content"])
+ def test_can_strip_wiki_formatting(self):
+ #arrange
+ self.insert_wiki(self.DUMMY_PAGE_NAME, " = Header")
+ #act
+ results = self.search_api.query("*:*")
+ #assert
+ self.print_result(results)
+ self.assertEqual(1, results.hits)
+ self.assertEqual("Header", results.docs[0]["content"])
+
def suite():
test_suite = unittest.TestSuite()
test_suite.addTest(unittest.makeSuite(
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/web_ui.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/web_ui.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/web_ui.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/web_ui.py Wed Feb 27 12:52:42 2013
@@ -27,7 +27,6 @@ from bhsearch.web_ui import RequestParam
from bhsearch.whoosh_backend import WhooshBackend
from trac.test import Mock, MockPerm
-from trac.ticket import Ticket
from trac.core import TracError
from trac.util.datefmt import FixedOffset
from trac.util import format_datetime
@@ -40,7 +39,6 @@ DEFAULT_DOCS_PER_PAGE = 10
class WebUiTestCaseWithWhoosh(BaseBloodhoundSearchTest):
def setUp(self):
super(WebUiTestCaseWithWhoosh, self).setUp(
- ['trac.*', 'bhsearch.*'],
create_req=True,
)
self.req.redirect = self.redirect
@@ -84,8 +82,7 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
def test_can_return_utc_time(self):
#arrange
- ticket_id = self.insert_ticket("bla")
- ticket = Ticket(self.env, ticket_id)
+ ticket = self.insert_ticket("bla")
ticket_time = ticket.time_changed
#act
self.req.args[RequestParameters.QUERY] = "*:*"
@@ -101,8 +98,7 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
def test_can_return_user_time(self):
#arrange
- ticket_id = self.insert_ticket("bla")
- ticket = Ticket(self.env, ticket_id)
+ ticket = self.insert_ticket("bla")
ticket_time = ticket.time_changed
#act
self.req.tz = FixedOffset(60, 'GMT +1:00')
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/whoosh_backend.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/whoosh_backend.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/whoosh_backend.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/tests/whoosh_backend.py Wed Feb 27 12:52:42 2013
@@ -451,6 +451,41 @@ class WhooshFunctionalityTestCase(unitte
facets_result[name] = non_paged_results.groups(name)
return facets_result
+ def test_can_auto_commit(self):
+ # pylint: disable=unused-argument
+
+ schema = Schema(
+ unique_id=ID(stored=True, unique=True),
+ type=ID(stored=True),
+ )
+
+ ix = index.create_in(self.index_dir, schema=schema)
+ with ix.writer() as w:
+ w.add_document(unique_id=u"1", type=u"type1")
+ w.add_document(unique_id=u"2", type=u"type2")
+
+ with ix.searcher() as s:
+ results = s.search(query.Every())
+ self.assertEquals(2, len(results))
+
+ def test_can_auto_cancel(self):
+ schema = Schema(
+ unique_id=ID(stored=True, unique=True),
+ type=ID(stored=True),
+ )
+
+ ix = index.create_in(self.index_dir, schema=schema)
+ try:
+ with ix.writer() as w:
+ w.add_document(unique_id=u"1", type=u"type1")
+ w.add_document(unique_id=u"2", type=u"type2")
+ raise Exception("some exception")
+ except Exception:
+ pass
+
+ with ix.searcher() as s:
+ results = s.search(query.Every())
+ self.assertEquals(0, len(results))
class WhooshEmptyFacetErrorWorkaroundTestCase(BaseBloodhoundSearchTest):
def setUp(self):
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/whoosh_backend.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/whoosh_backend.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/whoosh_backend.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/bhsearch/whoosh_backend.py Wed Feb 27 12:52:42 2013
@@ -76,17 +76,18 @@ class WhooshBackend(Component):
#ISearchBackend methods
def start_operation(self):
- return dict(writer = self._create_writer())
+ return self._create_writer()
def _create_writer(self):
return AsyncWriter(self.index)
- def add_doc(self, doc, writer=None):
+ def add_doc(self, doc, operation_context=None):
"""Add any type of document index.
The contents should be a dict with fields matching the search schema.
The only required fields are type and id, everything else is optional.
"""
+ writer = operation_context
is_local_writer = False
if writer is None:
is_local_writer = True
@@ -118,9 +119,10 @@ class WhooshBackend(Component):
else:
doc[key] = self._to_whoosh_format(value)
- def delete_doc(self, doc_type, doc_id, writer=None):
+ def delete_doc(self, doc_type, doc_id, operation_context=None):
unique_id = self._create_unique_id(doc_type, doc_id)
self.log.debug('Removing document from the index: %s', unique_id)
+ writer = operation_context
is_local_writer = False
if writer is None:
is_local_writer = True
@@ -139,15 +141,6 @@ class WhooshBackend(Component):
writer = AsyncWriter(self.index)
writer.commit(optimize=True)
- def commit(self, optimize, writer):
- writer.commit(optimize=optimize)
-
- def cancel(self, writer):
- try:
- writer.cancel()
- except Exception, ex:
- self.env.log.error("Error during writer cancellation: %s", ex)
-
def recreate_index(self):
self.log.info('Creating Whoosh index in %s' % self.index_dir)
self._make_dir_if_not_exists()
@@ -380,7 +373,12 @@ class WhooshEmptyFacetErrorWorkaround(Co
if field == self.NULL_MARKER:
count_dict[None] = count
del count_dict[self.NULL_MARKER]
- #we can fix query_result.docs later if needed
+
+ #fix query_result.docs
+ for doc in query_result.docs:
+ for field, value in doc.items():
+ if value == self.NULL_MARKER:
+ del doc[field]
#IQueryPreprocessor methods
def query_pre_process(self, query_parameters):
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.cfg
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.cfg?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.cfg (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.cfg Wed Feb 27 12:52:42 2013
@@ -16,9 +16,9 @@
# under the License.
[egg_info]
-tag_build =
+tag_build = dev
tag_date = 0
-tag_svn_revision = 0
+tag_svn_revision = true
[sdist]
formats = gztar,bztar,ztar,tar,zip
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_search/setup.py Wed Feb 27 12:52:42 2013
@@ -30,6 +30,7 @@ Add free text search and query functiona
versions = [
(0, 4, 0),
+ (0, 5, 0),
]
latest = '.'.join(str(x) for x in versions[-1])
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/htdocs/bloodhound.css
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/htdocs/bloodhound.css?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/htdocs/bloodhound.css (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/htdocs/bloodhound.css Wed Feb 27 12:52:42 2013
@@ -285,6 +285,8 @@ pre.wiki {
display: none;
}
+#trac-comment-editor textarea { width: 100%; }
+
/* @end */
/* @group Quick Ticket fieldset */
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_components.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_components.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_components.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_components.html Wed Feb 27 12:52:42 2013
@@ -32,19 +32,19 @@
<body>
<h2>Manage Components</h2>
- <py:def function="owner_field(default_owner='')">
- <div class="control-group">
- <label class="control-label" for="owner">Owner: </label>
- <div class="controls" py:choose="">
- <select class="input-medium"
- py:when="owners" size="1" id="owner" name="owner">
+ <py:def function="owner_field(default_owner='', inline=False)">
+ <div py:strip="inline" class="control-group">
+ <label class="control-label" for="owner">Owner:</label>
+ <div class="controls" py:choose="" py:strip="inline">
+ <select py:when="owners" id="owner"
+ class="input-medium" size="1" name="owner">
<option py:for="owner in owners"
selected="${owner==default_owner or None}" value="$owner">$owner</option>
<option py:if="default_owner and default_owner not in owners"
selected="selected" value="$default_owner">$default_owner</option>
</select>
<input py:otherwise="" class="input-medium" type="text" id="owner"
- name="owner" value="$default_owner" />
+ name="owner" value="$default_owner" />
</div>
</div>
</py:def>
@@ -55,9 +55,9 @@
<fieldset>
<legend>Modify Component:</legend>
<div class="control-group">
- <label class="control-label" for="name">Name:</label>
+ <label class="control-label" for="name">Name: </label>
<div class="controls">
- <input type="text" id="name" name="name" value="$component.name"/>
+ <input class="input-medium" type="text" id="name" name="name" value="$component.name"/>
</div>
</div>
${owner_field(component.owner)}
@@ -80,7 +80,7 @@
</fieldset>
</div>
<div class="control-group">
- <input class="btn" type="submit" name="cancel"
+ <input class="btn-link" type="submit" name="cancel"
value="${_('Cancel')}" />
<input class="btn" type="submit" name="save"
value="${_('Save')}" />
@@ -90,9 +90,26 @@
<py:otherwise>
<div class="row">
- <div class="span6">
+ <div class="span9">
+ <form id="addcomponent" class="well form-inline" method="post" action="">
+ <fieldset>
+ <legend>Add Component:</legend>
+ <div class="control-group">
+ <input class="btn" type="submit" name="add"
+ value="${_('Add')}"/>
+ <label class="control-label" for="name">Name:</label>
+ <input id="name" class="input-medium" type="text" name="name" />
+ ${owner_field(inline=True)}
+ </div>
+ </fieldset>
+ </form>
+ </div>
+ </div>
+ <div class="row">
+ <div class="span9">
<py:choose>
- <form py:when="components" id="component_table" method="post" action="">
+ <form py:when="components" id="component_table"
+ method="post" action="">
<table id="complist"
class="table table-striped table-condensed table-bordered">
<thead>
@@ -126,7 +143,7 @@
field from the user interface.
</p>
</form>
-
+
<p py:otherwise="" class="help-block">
<span class="label label-warning">Warning</span>
As long as you don't add any items to the list, this field
@@ -134,18 +151,6 @@
</p>
</py:choose>
</div>
- <div class="span3">
- <form class="well" id="addcomponent" method="post" action="">
- <fieldset>
- <legend>Add Component:</legend>
- <label for="name">Name:</label>
- <input class="input-medium" type="text" id="name" name="name" />
- ${owner_field()}
- <input class="btn" type="submit" name="add"
- value="${_('Add')}"/>
- </fieldset>
- </form>
- </div>
</div>
</py:otherwise>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_enums.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_enums.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_enums.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_enums.html Wed Feb 27 12:52:42 2013
@@ -35,7 +35,7 @@
<py:choose test="view">
<form py:when="'detail'" class="well form-horizontal" id="modenum" method="post" action="">
<fieldset>
- <legend i18n:msg="label_singular">Modify $label_singular</legend>
+ <legend i18n:msg="label_singular">Modify $label_singular:</legend>
<div class="control-group">
<label class="control-label" for="name">Name: </label>
<div class="controls">
@@ -43,7 +43,7 @@
</div>
</div>
<div class="btn-group">
- <input class="btn" type="submit" name="cancel"
+ <input class="btn-link" type="submit" name="cancel"
value="${_('Cancel')}"/>
<input class="btn" type="submit" name="save" value="${_('Save')}"/>
</div>
@@ -52,11 +52,25 @@
<py:otherwise>
<div class="row">
- <div class="span6">
+ <div class="span9">
+ <form id="addenum" class="well form-inline" method="post" action="">
+ <fieldset>
+ <legend i18n:msg="label_singular">Add $label_singular:</legend>
+ <input class="btn" type="submit" name="add"
+ value="${_('Add')}"/>
+ <label class="control-label" for="name">Name:</label>
+ <input class="input-medium" type="text"
+ name="name" id="name"/>
+ </fieldset>
+ </form>
+ </div>
+ </div>
+ <div class="row">
+ <div class="span9">
<py:choose>
- <form py:when="enums" id="enumtable" method="post" action="">
+ <form py:when="enums" id="enumtable" class="form-inline" method="post" action="">
<table id="enumlist"
- class="table table-striped table-condensed table-bordered">
+ class="table table-striped table-condensed table-bordered">
<thead>
<tr><th class="sel"><i class="icon-check"></i></th>
<th>Name</th><th>Default</th><th>Order</th>
@@ -81,12 +95,6 @@
</tr>
</tbody>
</table>
- <p class="help-block" py:if="type=='priority'" i18n:msg="">
- <span class="label label-info">Note:</span>
- The order of priorities determines the
- coloring of entries in the ticket queries and reports.
- </p>
- <br/>
<div class="form-inline">
<input class="btn" type="submit" name="remove"
value="${_('Remove selected items')}" />
@@ -94,8 +102,13 @@
value="${_('Apply changes')}" />
</div>
<br/>
+ <p class="help-block" py:if="type=='priority'" i18n:msg="">
+ <span class="label label-info">Note</span>
+ The order of priorities determines the
+ coloring of entries in the ticket queries and reports.
+ </p>
<p class="help-block">
- <span class="label label-info">Notice</span>
+ <span class="label label-info">Note</span>
You can remove all items from this list to completely hide this
field from the user interface.
</p>
@@ -108,17 +121,6 @@
</p>
</py:choose>
</div>
- <div class="span3">
- <form class="well" id="addenum" method="post" action="">
- <fieldset>
- <legend i18n:msg="label_singular">Add $label_singular:</legend>
- <label class="control-label" for="name">Name:</label>
- <input class="input-medium" type="text" name="name" id="name"/>
- <input class="btn" type="submit" name="add"
- value="${_('Add')}"/>
- </fieldset>
- </form>
- </div>
</div>
</py:otherwise>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_milestones.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_milestones.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_milestones.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_milestones.html Wed Feb 27 12:52:42 2013
@@ -39,7 +39,7 @@
<h2>Milestone Management</h2>
<py:choose test="view">
- <form py:when="'detail'" class="well form-horizontal" method="post"
+ <form py:when="'detail'" class="well form-horizontal" method="post"
id="modifymilestone" action=""
py:with="readonly = 'MILESTONE_MODIFY' not in req.perm or None">
<fieldset>
@@ -70,7 +70,7 @@
<input type="text" id="completeddate" name="completeddate"
size="${len(datetime_hint)}"
value="${format_datetime(milestone.completed)}" readonly="${readonly}"
- placeholder="${_('Format: %(datehint)s', datehint=datetime_hint)}"/>
+ placeholder="${_('Format: %(datehint)s', datehint=datetime_hint)}" />
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
@@ -98,7 +98,7 @@
</fieldset>
</div>
<div class="control-group">
- <input class="btn" type="submit" name="cancel"
+ <input class="btn-link" type="submit" name="cancel"
value="${_('Cancel')}"/>
<input class="btn" type="submit" name="save"
value="${_('Save')}" disabled="${readonly}"/>
@@ -109,7 +109,7 @@
<py:otherwise>
<div py:if="'MILESTONE_CREATE' in req.perm" class="row">
<div class="span9">
- <form class="well form-horizontal" id="addmilestone" method="post" action="">
+ <form id="addmilestone" class="well form-horizontal" method="post" action="">
<fieldset>
<legend>Add Milestone</legend>
<div class="control-group">
@@ -133,11 +133,6 @@
<div class="controls">
<input class="btn" type="submit" name="add" value="${_('Add')}" />
</div>
-
- <p class="help-block">
- <span class="label label-info">Hint</span>
- <i18n:msg params="datehint">Format: $datetime_hint</i18n:msg>
- </p>
</div>
</fieldset>
</form>
@@ -188,7 +183,7 @@
value="${_('Apply changes')}" />
</div>
<p class="help-block">
- <span class="label label-info">Notice</span>
+ <span class="label label-info">Note</span>
You can remove all items from this list to completely hide this
field from the user interface.
</p>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_plugins.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_plugins.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_plugins.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_plugins.html Wed Feb 27 12:52:42 2013
@@ -27,8 +27,6 @@
<xi:include href="bh_admin.html" />
<head>
<title>Plugins</title>
- <script type="text/javascript"
- src="${href.chrome('dashboard/js/bootstrap-collapse.js')}"></script>
<script type="text/javascript">/*<![CDATA[*/
jQuery(document).ready(function($) {
// Sets state of group toggler when component checkboxes are clicked
@@ -72,7 +70,6 @@
enctype="multipart/form-data" action="" py:otherwise="">
<fieldset>
<legend>Install Plugin:</legend>
-
<label i18n:msg="" for="plugin_file">File:</label>
<input class="input-medium" type="file" id="plugin_file" size="10"
name="plugin_file" disabled="${readonly or None}" />
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_products.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_products.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_products.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_products.html Wed Feb 27 12:52:42 2013
@@ -86,7 +86,7 @@
</fieldset>
</div>
<div class="control-group">
- <input class="btn" type="submit" name="cancel"
+ <input class="btn-link" type="submit" name="cancel"
value="${_('Cancel')}" />
<input class="btn" type="submit" name="save"
value="${_('Save')}" />
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_repositories.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_repositories.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_repositories.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_repositories.html Wed Feb 27 12:52:42 2013
@@ -127,7 +127,7 @@
</fieldset>
</div>
<div class="control-group">
- <input class="btn" type="submit" name="cancel" value="${_('Cancel')}"/>
+ <input class="btn-link" type="submit" name="cancel" value="${_('Cancel')}"/>
<input class="btn" py:if="info.editable" type="submit"
name="save" value="${_('Save')}"/>
</div>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_versions.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_versions.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_versions.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_admin_versions.html Wed Feb 27 12:52:42 2013
@@ -74,7 +74,7 @@
</fieldset>
</div>
<div class="control-group">
- <input class="btn" type="submit" name="cancel"
+ <input class="btn-link" type="submit" name="cancel"
value="${_('Cancel')}"/>
<input class="btn" type="submit" name="save"
value="${_('Save')}"/>
@@ -84,7 +84,25 @@
<py:otherwise>
<div class="row">
- <div class="span6">
+ <div class="span9">
+ <form class="well form-inline" id="addversion" method="post" action="">
+ <fieldset>
+ <legend>Add Version:</legend>
+ <input class="btn" type="submit" name="add"
+ value="${_('Add')}" />
+ <label class="control-label" for="name">Name:</label>
+ <input class="input-medium" type="text" name="name"
+ id="name" size="22" />
+ <label class="control-label" for="releaseddate">Released:</label>
+ <input type="text" id="releaseddate"
+ name="time" size="${len(datetime_hint)}"
+ value="${format_datetime()}" />
+ </fieldset>
+ </form>
+ </div>
+ </div>
+ <div class="row">
+ <div class="span9">
<py:choose>
<form py:when="versions" id="version_table" method="post" action="">
<table id="verlist"
@@ -114,7 +132,7 @@
value="${_('Apply changes')}" />
</div>
<p class="help-block">
- <span class="label label-info">Notice</span>
+ <span class="label label-info">Note</span>
You can remove all items from this list to completely hide this
field from the user interface.
</p>
@@ -127,31 +145,7 @@
</p>
</py:choose>
</div>
- <div class="span3">
- <form class="well" id="addversion" method="post" action="">
- <fieldset>
- <legend>Add Version:</legend>
- <label for="name">Name:</label>
- <input class="input-medium" type="text" name="name"
- id="name" size="22" />
- <label for="releaseddate">Released:</label>
- <input class="input-medium" type="text" id="releaseddate"
- name="time" size="${len(datetime_hint)}"
- placeholder="${_('Format: %(datehint)s', datehint=datetime_hint)}"
- value="${format_datetime()}" />
- <p class="help-block">
- <span class="label label-info">Hint</span>
- <i18n:msg params="datehint">Format: $datetime_hint</i18n:msg>
- </p>
- <div class="control-group">
- <input class="btn" type="submit" name="add"
- value="${_('Add')}" />
- </div>
- </fieldset>
- </form>
- </div>
</div>
-
</py:otherwise>
</py:choose>
</body>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_milestone_delete.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_milestone_delete.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_milestone_delete.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_milestone_delete.html Wed Feb 27 12:52:42 2013
@@ -61,7 +61,7 @@
</div>
<div class="buttons">
<input type="submit" name="cancel" value="${_('Cancel')}"
- class="btn" />
+ class="btn-link" />
<input type="submit" value="${_('Delete milestone')}"
class="btn" />
</div>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_milestone_edit.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_milestone_edit.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_milestone_edit.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_milestone_edit.html Wed Feb 27 12:52:42 2013
@@ -148,7 +148,7 @@ ${milestone.description}</textarea></p>
<input py:otherwise="" type="submit" value="${_('Add milestone')}"
class="btn" />
<input type="submit" name="cancel" value="${_('Cancel')}"
- class="btn" />
+ class="btn-link" />
</div>
</form>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_report_delete.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_report_delete.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_report_delete.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_report_delete.html Wed Feb 27 12:52:42 2013
@@ -38,7 +38,7 @@
<div class="buttons">
<input type="hidden" name="id" value="$report.id"/>
<input type="hidden" name="action" value="delete" />
- <input type="submit" class="btn" name="cancel"
+ <input type="submit" class="btn-link" name="cancel"
value="${_('Cancel')}"/>
<input type="submit" class="btn"
value="${_('Delete report')}"/>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_report_edit.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_report_edit.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_report_edit.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_report_edit.html Wed Feb 27 12:52:42 2013
@@ -76,8 +76,8 @@ $report.sql</textarea>
</div>
<div class="buttons control-group">
<input class="btn" type="submit" value="${_('Save report')}"/>
- <input class="btn" type="submit" name="cancel"
- value="${_('Cancel')}"/>
+ <input class="btn-link" type="submit" name="cancel"
+ value="${_('Cancel')}"/>
</div>
</div>
</form>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_ticket_change.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_ticket_change.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_ticket_change.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_ticket_change.html Wed Feb 27 12:52:42 2013
@@ -134,12 +134,14 @@ Arguments:
${edited_comment if edited_comment is not None else change.comment}</textarea>
<input type="hidden" name="cnum_edit" value="${cnum}"/>
</div>
- <div class="buttons">
- <input type="submit" name="preview_comment" value="${_('Preview')}"
- title="${_('Preview changes to comment %(cnum)s', cnum=cnum)}"/>
- <input type="submit" name="edit_comment" value="${_('Submit changes')}"
- title="${_('Submit changes to comment %(cnum)s', cnum=cnum)}"/>
- <input type="submit" name="cancel_comment" value="${_('Cancel')}"
+ <div class="btn-toolbar buttons">
+ <div class="btn-group">
+ <input class="btn" type="submit" name="preview_comment" value="${_('Preview')}"
+ title="${_('Preview changes to comment %(cnum)s', cnum=cnum)}"/>
+ <input class="btn" type="submit" name="edit_comment" value="${_('Submit changes')}"
+ title="${_('Submit changes to comment %(cnum)s', cnum=cnum)}"/>
+ </div>
+ <input class="btn-link" type="submit" name="cancel_comment" value="${_('Cancel')}"
title="Cancel comment edit"/>
</div>
</form>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_delete.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_delete.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_delete.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_delete.html Wed Feb 27 12:52:42 2013
@@ -116,7 +116,7 @@
<strong>This is an irreversible operation.</strong>
</p>
<div class="control-group">
- <input class="btn" type="submit" name="cancel" value="${_('Cancel')}" />
+ <input class="btn-link" type="submit" name="cancel" value="${_('Cancel')}" />
<input class="btn" type="submit" value="${what == 'multiple' and _('Delete those versions')
or what == 'single' and _('Delete this version')
or _('Delete page')}" />
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_edit_form.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_edit_form.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_edit_form.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_edit_form.html Wed Feb 27 12:52:42 2013
@@ -103,7 +103,7 @@ $page.text</textarea>
</py:otherwise>
</div>
<div class="btn-group">
- <input class="btn" type="submit" name="cancel" value="${_('Cancel')}" />
+ <input class="btn-link" type="submit" name="cancel" value="${_('Cancel')}" />
</div>
</div>
</form>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_rename.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_rename.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_rename.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_rename.html Wed Feb 27 12:52:42 2013
@@ -49,7 +49,7 @@
</label>
<br/><br/>
<div class="control-group">
- <input class="btn" type="submit" name="cancel" value="${_('Cancel')}"/>
+ <input class="btn-link" type="submit" name="cancel" value="${_('Cancel')}"/>
<input class="btn" type="submit" name="submit" value="${_('Rename page')}"/>
</div>
</form>
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bloodhound_theme.html
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bloodhound_theme.html?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bloodhound_theme.html (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bloodhound_theme.html Wed Feb 27 12:52:42 2013
@@ -40,20 +40,8 @@
<script src="${href.chrome('theme/js/theme.js')}"
type="text/javascript"></script>
- <script src="${href.chrome('dashboard/js/bootstrap-transition.js')}"
+ <script src="${href.chrome('dashboard/js/bootstrap.js')}"
type="text/javascript"></script>
- <script src="${href.chrome('dashboard/js/bootstrap-alert.js')}"
- type="text/javascript"></script>
- <script src="${href.chrome('dashboard/js/bootstrap-dropdown.js')}"
- type="text/javascript"></script>
- <script src="${href.chrome('dashboard/js/bootstrap-tooltip.js')}"
- type="text/javascript"></script>
- <script src="${href.chrome('dashboard/js/bootstrap-popover.js')}"
- type="text/javascript"></script>
- <script src="${href.chrome('dashboard/js/bootstrap-affix.js')}"
- type="text/javascript"></script>
- <script src="${href.chrome('dashboard/js/bootstrap-button.js')}"
- type="text/javascript"></script>
</head></py:match>
@@ -65,8 +53,10 @@
<!--! logo -->
<div id="logo" class="span4">
<p>
- <img src="${chrome.logo.src or href.chrome('theme/img/bh_logo.png')}"
- alt="Bloodhound Logo" />
+ <a href="${chrome.logo.link or href()}">
+ <img src="${chrome.logo.src or href.chrome('theme/img/bh_logo.png')}"
+ alt="Bloodhound Logo" />
+ </a>
</p>
</div>
<!--! top menu (login, logout...) -->
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py Wed Feb 27 12:52:42 2013
@@ -149,7 +149,7 @@ class BloodhoundTheme(ThemeBase):
footer_left_prefix = self.labels_footer_left_prefix,
footer_left_postfix = self.labels_footer_left_postfix,
footer_right = self.labels_footer_right,
- application_version = ".".join(map(str, application_version)))
+ application_version = application_version)
# ITemplateStreamFilter methods
@@ -307,7 +307,6 @@ class BloodhoundTheme(ThemeBase):
def _modify_ticket(self, req, template, data, content_type, is_active):
"""Ticket modifications
"""
- self._modify_scrollspy(req, template, data, content_type, is_active)
self._modify_resource_breadcrumb(req, template, data, content_type,
is_active)
@@ -323,11 +322,6 @@ class BloodhoundTheme(ThemeBase):
res = Resource(resname, data['ticket'][resname])
data['path_show_' + resname] = permname in req.perm(res)
- def _modify_scrollspy(self, req, template, data, content_type, is_active):
- """Insert Bootstrap scroll spy files.
- """
- add_script(req, 'dashboard/js/bootstrap-scrollspy.js')
-
# INavigationContributor methods
def get_active_navigation_item(self, req):
@@ -446,5 +440,4 @@ class QuickCreateTicketDialog(Component)
"of ticket #%s: %s" % (t.id, e))
return t.id
-application_version = tuple(int(i) for i in get_distribution('BloodhoundTheme')
- .parsed_version if i.startswith('0'))
+application_version = get_distribution('BloodhoundTheme').version
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/setup.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/setup.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/setup.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/setup.py Wed Feb 27 12:52:42 2013
@@ -23,7 +23,7 @@ import sys
setup(
name = 'BloodhoundTheme',
- version = '0.4.0',
+ version = '0.5.0',
description = "Theme for Apache(TM) Bloodhound.",
author = "Apache Bloodhound",
license = "Apache License v2",
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/installer/bloodhound_setup.py Wed Feb 27 12:52:42 2013
@@ -68,7 +68,7 @@ BASE_CONFIG = {'components': {'bhtheme.*
},
'header_logo': {'src': '',},
'mainnav': {'roadmap': 'disabled',
- 'source': 'disabled',
+ 'search': 'disabled',
'timeline': 'disabled',
'browser.label': 'Source',
'tickets.label': 'Tickets',},
Propchange: incubator/bloodhound/branches/bep_0003_multiproduct/trac/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Feb 27 12:52:42 2013
@@ -1 +1,2 @@
*.egg-info
+*.egg
Propchange: incubator/bloodhound/branches/bep_0003_multiproduct/trac/
------------------------------------------------------------------------------
Merged /incubator/bloodhound/trunk/trac:r1446486-1450761
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/api.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/api.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/api.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/api.py Wed Feb 27 12:52:42 2013
@@ -156,6 +156,31 @@ class IMilestoneChangeListener(Interface
def milestone_deleted(milestone):
"""Called when a milestone is deleted."""
+class IResourceChangeListener(Interface):
+ """Extension point interface for components that require notification
+ when resources are created, modified, or deleted.
+
+ 'resource' instance of the a resource e.g. ticket, milestone etc.
+ 'context' action context, may contain author, comment etc. Context
+ content depends on a resource type.
+ """
+
+ def resource_created(resource, context):
+ """
+ Called when a resource is created.
+ """
+
+ def resource_changed(resource, old_values, context):
+ """Called when a resource is modified.
+
+ `old_values` is a dictionary containing the previous values of the
+ resource properties that changed. Properties are specific for resource
+ type.
+ """
+
+ def resource_deleted(resource, context):
+ """Called when a resource is deleted."""
+
class ITicketFieldProvider(Interface):
"""Extension point interface for components that provide fields for the
ticket system."""
@@ -193,6 +218,7 @@ class TicketSystem(Component):
ticket_field_providers = ExtensionPoint(ITicketFieldProvider)
change_listeners = ExtensionPoint(ITicketChangeListener)
milestone_change_listeners = ExtensionPoint(IMilestoneChangeListener)
+ resource_change_listeners = ExtensionPoint(IResourceChangeListener)
ticket_custom_section = ConfigSection('ticket-custom',
"""In this section, you can define additional fields for tickets. See
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py Wed Feb 27 12:52:42 2013
@@ -844,9 +844,12 @@ class Component(object):
with self.env.db_transaction as db:
self.env.log.info("Deleting component %s", self.name)
db("DELETE FROM component WHERE name=%s", (self.name,))
- self.name = self._old_name = None
TicketSystem(self.env).reset_ticket_fields()
+ for listener in TicketSystem(self.env).resource_change_listeners:
+ listener.resource_deleted(self)
+ self.name = self._old_name = None
+
def insert(self, db=None):
"""Insert a new component.
@@ -866,6 +869,9 @@ class Component(object):
self._old_name = self.name
TicketSystem(self.env).reset_ticket_fields()
+ for listener in TicketSystem(self.env).resource_change_listeners:
+ listener.resource_created(self)
+
def update(self, db=None):
"""Update the component.
@@ -877,6 +883,7 @@ class Component(object):
if not self.name:
raise TracError(_("Invalid component name."))
+ old_name = self._old_name
with self.env.db_transaction as db:
self.env.log.info("Updating component '%s'", self.name)
db("""UPDATE component SET name=%s,owner=%s, description=%s
@@ -890,6 +897,10 @@ class Component(object):
self._old_name = self.name
TicketSystem(self.env).reset_ticket_fields()
+ old_values = dict(name=old_name)
+ for listener in TicketSystem(self.env).resource_change_listeners:
+ listener.resource_changed(self, old_values)
+
@classmethod
def select(cls, env, db=None):
"""
Modified: incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py
URL: http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py?rev=1450762&r1=1450761&r2=1450762&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py (original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py Wed Feb 27 12:52:42 2013
@@ -15,7 +15,8 @@ from trac.ticket.model import (
Ticket, Component, Milestone, Priority, Type, Version
)
from trac.ticket.api import (
- IMilestoneChangeListener, ITicketChangeListener, TicketSystem
+ IMilestoneChangeListener, ITicketChangeListener, TicketSystem,
+ IResourceChangeListener,
)
from trac.test import EnvironmentStub
from trac.util.datefmt import from_utimestamp, to_utimestamp, utc
@@ -1005,6 +1006,27 @@ class MilestoneTestCase(unittest.TestCas
self.assertEqual('deleted', listener.action)
self.assertEqual(milestone, listener.milestone)
+class TestResourceChangeListener(core.Component):
+ implements(IResourceChangeListener)
+
+ def callback(self, action, resource, old_values = None):
+ pass
+
+ def resource_created(self, resource):
+ self.action = "created"
+ self.resource = resource
+ self.callback(self.action, self.resource)
+
+ def resource_changed(self, resource, old_values):
+ self.action = "changed"
+ self.resource = resource
+ self.old_values = old_values
+ self.callback(self.action, self.resource, old_values=self.old_values)
+
+ def resource_deleted(self, resource):
+ self.action = "deleted"
+ self.resource = resource
+ self.callback(self.action, self.resource)
class ComponentTestCase(unittest.TestCase):
@@ -1041,6 +1063,49 @@ class ComponentTestCase(unittest.TestCas
self.assertEqual([('Test', 'joe', None)], self.env.db_query(
"SELECT name, owner, description FROM component WHERE name='Test'"))
+ def test_change_listener_created(self):
+ listener = TestResourceChangeListener(self.env)
+ self._create_component(name='Component 1')
+ self.assertEqual('created', listener.action)
+ self.assertIsInstance(listener.resource, Component)
+ self.assertEqual('Component 1', listener.resource.name)
+
+ def test_change_listener_changed(self):
+ listener = TestResourceChangeListener(self.env)
+ component = self._create_component(name='Component 1')
+ component.name = 'Component 2'
+ component.update()
+ self.assertEqual('changed', listener.action)
+ self.assertIsInstance(listener.resource, Component)
+ self.assertEqual('Component 2', listener.resource.name)
+ self.assertEqual("Component 1" ,listener.old_values["name"])
+
+ def test_change_listener_deleted(self):
+ listener = TestResourceChangeListener(self.env)
+
+ #component.name property is set to None during delete operation
+ #We need mechanism to remember component name
+ listener.callback = self.listener_callback
+
+ component = self._create_component(name='Component 1')
+ component.delete()
+ self.assertEqual('deleted', listener.action)
+ self.assertIsInstance(listener.resource, Component)
+ self.assertEqual('Component 1', self.resource_name)
+
+ def listener_callback(self, action, resource, old_values = None):
+ self.resource_name = resource.name
+
+ def _create_component(self, name, description = None, owner=None):
+ component = Component(self.env)
+ component.name = name
+ if description is None:
+ component.description = description
+ if owner is None:
+ component.owner = owner
+ component.insert()
+ return component
+
class VersionTestCase(unittest.TestCase):
def setUp(self):