Moved the indexing to be a catalog wrapper.
svn path=/plone.app.discussion/trunk/; revision=27005
This commit is contained in:
parent
e35f761939
commit
acf00c9de9
@ -115,7 +115,9 @@ class Conversation(Persistent, Explicit):
|
|||||||
if not reply_to in self._children:
|
if not reply_to in self._children:
|
||||||
self._children[reply_to] = LLSet()
|
self._children[reply_to] = LLSet()
|
||||||
self._children[reply_to].insert(id)
|
self._children[reply_to].insert(id)
|
||||||
notify(ObjectAddedEvent(comment, self, id))
|
# Notify that the object is added. The object must here be
|
||||||
|
# acquisition wrapped or the indexing will fail.
|
||||||
|
notify(ObjectAddedEvent(comment.__of__(self), self, id))
|
||||||
notify(ContainerModifiedEvent(self))
|
notify(ContainerModifiedEvent(self))
|
||||||
|
|
||||||
# Dict API
|
# Dict API
|
||||||
@ -137,6 +139,9 @@ class Conversation(Persistent, Explicit):
|
|||||||
def keys(self):
|
def keys(self):
|
||||||
return self._comments.keys()
|
return self._comments.keys()
|
||||||
|
|
||||||
|
def getPhysicalPath(self):
|
||||||
|
return self.aq_parent.getPhysicalPath() + (self.id,)
|
||||||
|
|
||||||
# TODO: Update internal data structures when items added or removed
|
# TODO: Update internal data structures when items added or removed
|
||||||
|
|
||||||
@implementer(IConversation)
|
@implementer(IConversation)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<utilities>
|
<utilities>
|
||||||
<utility
|
<utility
|
||||||
interface="plone.app.discussion.interfaces.ICommentingTool"
|
interface="plone.app.discussion.interfaces.ICommentingTool"
|
||||||
factory="plone.app.discussion.tool.CommentingTool"
|
object="portal_discussion"
|
||||||
/>
|
/>
|
||||||
</utilities>
|
</utilities>
|
||||||
</componentregistry>
|
</componentregistry>
|
||||||
|
5
plone/app/discussion/profiles/default/toolset.xml
Normal file
5
plone/app/discussion/profiles/default/toolset.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<tool-setup>
|
||||||
|
<required tool_id="portal_discussion"
|
||||||
|
class="plone.app.discussion.tool.CommentingTool"/>
|
||||||
|
</tool-setup>
|
@ -29,6 +29,9 @@ class ConversationTest(TestCase):
|
|||||||
# Create a conversation. In this case we doesn't assign it to an
|
# Create a conversation. In this case we doesn't assign it to an
|
||||||
# object, as we just want to check the Conversation object API.
|
# object, as we just want to check the Conversation object API.
|
||||||
conversation = IConversation(self.portal.doc1)
|
conversation = IConversation(self.portal.doc1)
|
||||||
|
# Pretend that we have traversed to the comment by aq wrapping it.
|
||||||
|
# XXX implement traversal to commenting and change this:
|
||||||
|
conversation = conversation.__of__(self.portal.doc1)
|
||||||
|
|
||||||
# Add a comment. reply_to=0 means it's not a reply
|
# Add a comment. reply_to=0 means it's not a reply
|
||||||
comment = Comment(conversation=conversation, reply_to=0)
|
comment = Comment(conversation=conversation, reply_to=0)
|
||||||
|
@ -29,6 +29,9 @@ class ToolTest(TestCase):
|
|||||||
# Create a conversation. In this case we doesn't assign it to an
|
# Create a conversation. In this case we doesn't assign it to an
|
||||||
# object, as we just want to check the Conversation object API.
|
# object, as we just want to check the Conversation object API.
|
||||||
conversation = IConversation(self.portal.doc1)
|
conversation = IConversation(self.portal.doc1)
|
||||||
|
# Pretend that we have traversed to the comment by aq wrapping it.
|
||||||
|
# XXX implement traversal to commenting and change this:
|
||||||
|
conversation = conversation.__of__(self.portal.doc1)
|
||||||
|
|
||||||
# Add a comment. reply_to=0 means it's not a reply
|
# Add a comment. reply_to=0 means it's not a reply
|
||||||
comment = Comment(conversation=conversation, reply_to=0)
|
comment = Comment(conversation=conversation, reply_to=0)
|
||||||
@ -39,8 +42,10 @@ class ToolTest(TestCase):
|
|||||||
|
|
||||||
# Check that the comment got indexed in the tool:
|
# Check that the comment got indexed in the tool:
|
||||||
tool = getUtility(ICommentingTool)
|
tool = getUtility(ICommentingTool)
|
||||||
comment = list(tool.search())[0]
|
comment = list(tool.searchResults())
|
||||||
self.assertEquals(comment['text'], 'Comment text')
|
self.assert_(len(comment) == 1, "There is only one comment, but we got"
|
||||||
|
" %s results in the search" % len(comment))
|
||||||
|
self.assertEquals(comment[0].Title, 'Comment 1')
|
||||||
|
|
||||||
|
|
||||||
def test_suite():
|
def test_suite():
|
||||||
|
@ -2,58 +2,65 @@ import time
|
|||||||
from zope import interface
|
from zope import interface
|
||||||
from zope.component import getUtility
|
from zope.component import getUtility
|
||||||
|
|
||||||
from BTrees.OOBTree import OOBTree, OOSet, intersection
|
from interfaces import ICommentingTool, IComment
|
||||||
|
|
||||||
from interfaces import ICommentingTool
|
|
||||||
# The commenting tool, which is a local utility
|
# The commenting tool, which is a local utility
|
||||||
|
|
||||||
class CommentingTool(object):
|
from Products.CMFCore.utils import UniqueObject, getToolByName
|
||||||
|
from OFS.SimpleItem import SimpleItem
|
||||||
|
|
||||||
|
class CommentingTool(UniqueObject, SimpleItem):
|
||||||
|
|
||||||
interface.implements(ICommentingTool)
|
interface.implements(ICommentingTool)
|
||||||
|
|
||||||
def __init__(self):
|
meta_type = 'plone.app.discussion tool'
|
||||||
self._id2uid = OOBTree() # The comment ID to object UID
|
id = 'portal_discussion'
|
||||||
self._id2text = OOBTree() # The text for a comment
|
|
||||||
self._wfstate2id = OOBTree() # To search on wf states
|
|
||||||
self._creator2id = OOBTree() # To search/order on creator ids
|
|
||||||
|
|
||||||
def index(self, comment):
|
def reindexObject(self, object):
|
||||||
# Store the object in the store:
|
"""Remove from catalog.
|
||||||
id = comment.comment_id
|
"""
|
||||||
self._id2uid[id] = comment.__parent__._parent_uid
|
catalog = getToolByName(self, 'portal_catalog')
|
||||||
self._id2text[id] = comment.text
|
return catalog.reindexObject(object)
|
||||||
|
|
||||||
# TODO
|
indexObject = reindexObject
|
||||||
## Index on workflow state
|
|
||||||
#wfstate = comment.getWorkflowState()
|
|
||||||
#if not wfstate in self._wfstate2id:
|
|
||||||
#self._wfstate2id[wfstate] = OOSet()
|
|
||||||
#self._wfstate2id[wfstate].insert(id)
|
|
||||||
|
|
||||||
# Index on creator
|
def unindexObject(self, object):
|
||||||
creator = comment.creator
|
"""Remove from catalog.
|
||||||
if not creator in self._creator2id:
|
"""
|
||||||
self._creator2id[creator] = OOSet()
|
catalog = getToolByName(self, 'portal_catalog')
|
||||||
self._creator2id[creator].insert(id)
|
return catalog.unindexObject(object)
|
||||||
|
|
||||||
def search(self, creator=None):
|
def uniqueValuesFor(self, name):
|
||||||
if creator is not None:
|
""" return unique values for FieldIndex name """
|
||||||
# Get all replies for a certain object
|
catalog = getToolByName(self, 'portal_catalog')
|
||||||
ids = self._creator2ids.get(creator, None)
|
return catalog.uniqueValuesFor(name)
|
||||||
if ids is None:
|
|
||||||
raise StopIteration
|
|
||||||
else:
|
|
||||||
ids = self._id2uid.keys()
|
|
||||||
|
|
||||||
for id in ids:
|
def searchResults(self, REQUEST=None, **kw):
|
||||||
yield {'id': id,
|
"""
|
||||||
'text': self._id2text[id]
|
Calls ZCatalog.searchResults with extra arguments that
|
||||||
# TODO: More data + maybe brains or something?
|
limit the results to what the user is allowed to see.
|
||||||
}
|
"""
|
||||||
|
catalog = getToolByName(self, 'portal_catalog')
|
||||||
|
object_provides = [IComment.__identifier__]
|
||||||
|
if 'object_provides' in kw:
|
||||||
|
kw_provides = kw['object_provides']
|
||||||
|
if isinstance(str, kw_provides):
|
||||||
|
object_provides.append(kw_provides)
|
||||||
|
else:
|
||||||
|
object_provides.extend(kw_provides)
|
||||||
|
if REQUEST is not None and 'object_provides' in REQUEST.form:
|
||||||
|
rq_provides = REQUEST.form['object_provides']
|
||||||
|
del REQUEST.form['object_provides']
|
||||||
|
if isinstance(str, rq_provides):
|
||||||
|
object_provides.append(rq_provides)
|
||||||
|
else:
|
||||||
|
object_provides.extend(rq_provides)
|
||||||
|
kw['object_provides'] = object_provides
|
||||||
|
return catalog.searchResults(REQUEST, **kw)
|
||||||
|
|
||||||
def object_added_handler(obj, event):
|
def object_added_handler(obj, event):
|
||||||
tool = getUtility(ICommentingTool)
|
tool = getUtility(ICommentingTool)
|
||||||
tool.index(obj)
|
tool.indexObject(obj)
|
||||||
|
|
||||||
def object_removed_handler(obj, event):
|
def object_removed_handler(obj, event):
|
||||||
tool = getUtility(ICommentingTool)
|
tool = getUtility(ICommentingTool)
|
||||||
tool.unindex(obj)
|
tool.unindexObject(obj)
|
||||||
|
Loading…
Reference in New Issue
Block a user