From: Nikolay K. <faf...@us...> - 2004-09-01 10:16:39
|
Update of /cvsroot/collective/CMFBoard In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13542 Modified Files: Forum.py ForumCatalog.py ForumTopic.py ForumWorkflow.py ListSupport.py Log Message: removed forum catalog, instead use custom catalog Index: ForumTopic.py =================================================================== RCS file: /cvsroot/collective/CMFBoard/ForumTopic.py,v retrieving revision 1.81 retrieving revision 1.82 diff -u -d -r1.81 -r1.82 --- ForumTopic.py 25 Aug 2004 19:13:40 -0000 1.81 +++ ForumTopic.py 1 Sep 2004 10:16:17 -0000 1.82 @@ -82,6 +82,8 @@ content_icon = 'fcTopic_icon_noans.gif' default_page = 'forum_topic' + sticky_flag = 0 + _topic_initialized = 0 def __init__(self, id, **kwargs): Index: ForumWorkflow.py =================================================================== RCS file: /cvsroot/collective/CMFBoard/ForumWorkflow.py,v retrieving revision 1.33 retrieving revision 1.34 diff -u -d -r1.33 -r1.34 --- ForumWorkflow.py 23 Aug 2004 11:51:08 -0000 1.33 +++ ForumWorkflow.py 1 Sep 2004 10:16:28 -0000 1.34 @@ -249,12 +249,9 @@ def setupTopicWorkflow(wf): wf.setProperties(title='Topic Workflow [CMFBoard]') - for s in ('admin', 'announce', 'waitreview', 'published', 'visible', - 'locked', 'rejected', 'private', 'retired'): + for s in ('admin', 'announce', 'visible', 'locked'): wf.states.addState(s) - for t in ('reject', 'lock', 'submit', 'publish', 'visible', - 'private', 'announce', 'retire', - 'wm_publish', 'wm_visible', 'wm_admin', 'wm_announce'): + for t in ('lock', 'visible', 'wm_admin', 'wm_announce'): wf.transitions.addTransition(t) for v in ('action', 'actor', 'comments', 'review_history', 'time'): wf.variables.addVariable(v) @@ -267,7 +264,7 @@ sdef = wf.states['admin'] sdef.setProperties( title='Topic for Administrator', - transitions=('publish','visible')) + transitions=('visible',)) sdef.setPermission(p_access, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) sdef.setPermission(p_view, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) sdef.setPermission(p_areply, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) @@ -278,7 +275,7 @@ sdef = wf.states['announce'] sdef.setProperties( title='', - transitions=('retire',)) + transitions=()) sdef.setPermission(p_access, 1, ()) sdef.setPermission(p_view, 1, ()) sdef.setPermission(p_areply, 0, ()) @@ -286,32 +283,10 @@ sdef.setPermission(DeleteTopic, 0, (r_manager, r_fmanager, r_reviewer)) sdef.setPermission(p_modify, 0, ()) - sdef = wf.states['rejected'] - sdef.setProperties( - title='Visible and editable only by forum administrators and reviewers', - transitions=('submit','publish', 'private', 'visible')) - sdef.setPermission(p_access, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) - sdef.setPermission(p_view, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) - sdef.setPermission(p_areply, 0, (r_manager, r_fmanager, r_reviewer)) - sdef.setPermission(ModifyTopic, 0, (r_manager, r_fmanager, topicOwner)) - sdef.setPermission(DeleteTopic, 0, (r_manager, r_fmanager, topicOwner)) - sdef.setPermission(p_modify, 0, ()) - - sdef = wf.states['private'] - sdef.setProperties( - title='', - transitions=('submit','publish', 'visible')) - sdef.setPermission(p_access, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) - sdef.setPermission(p_view, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) - sdef.setPermission(p_areply, 0, (r_manager, r_fmanager, r_reviewer)) - sdef.setPermission(ModifyTopic, 0, (r_manager, r_fmanager, topicOwner)) - sdef.setPermission(DeleteTopic, 0, (r_manager, r_fmanager, topicOwner)) - sdef.setPermission(p_modify, 0, ()) - sdef = wf.states['locked'] sdef.setProperties( title='Visible but replies only administrators and reviewers', - transitions=('publish', 'visible', 'reject')) + transitions=('visible',)) sdef.setPermission(p_access, 1, ()) sdef.setPermission(p_view, 1, ()) sdef.setPermission(p_areply, 0, (r_manager, r_fmanager, r_reviewer)) @@ -319,21 +294,10 @@ sdef.setPermission(DeleteTopic, 0, (r_manager, r_fmanager)) sdef.setPermission(p_modify, 0, ()) - sdef = wf.states['published'] - sdef.setProperties( - title='Visible topic', - transitions=('lock','reject', 'private', 'visible')) - #sdef.setPermission(p_access, 1, ()) - #sdef.setPermission(p_view, 1, ()) - #sdef.setPermission(p_areply, 1, ()) - #sdef.setPermission(ModifyTopic, 1, (r_manager, r_fmanager)) - #sdef.setPermission(DeleteTopic, 0, (r_manager, r_fmanager)) - sdef.setPermission(p_modify, 0, (r_manager, r_fmanager, r_reviewer, r_owner)) - sdef = wf.states['visible'] sdef.setProperties( title='Visible for all, editable by owner', - transitions=('lock','publish','reject','private')) + transitions=('lock',)) sdef.setPermission(p_access, 1,()) sdef.setPermission(p_view, 1,()) sdef.setPermission(p_areply, 1, ()) @@ -341,47 +305,7 @@ sdef.setPermission(DeleteTopic, 0,(r_manager, r_fmanager)) sdef.setPermission(p_modify, 0,()) - sdef = wf.states['waitreview'] - sdef.setProperties( - title='Waiting for reviewer', - transitions=('publish', 'reject', 'private', 'visible')) - sdef.setPermission(p_access, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) - sdef.setPermission(p_view, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) - sdef.setPermission(p_areply, 0, ()) - sdef.setPermission(ModifyTopic, 0, (r_manager, r_fmanager, topicOwner)) - sdef.setPermission(DeleteTopic, 0, (r_manager, r_fmanager, topicOwner)) - sdef.setPermission(p_modify, 0, ()) - - sdef = wf.states['retired'] - sdef.setProperties( - title='Retired Announcement', - transitions=('announce',), - description='retired announcement. Still view/editable by Manager, Reviewer. Same as "private" state.') - sdef.setPermission(p_access, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) - sdef.setPermission(p_view, 0, (r_manager, r_fmanager, r_reviewer, topicOwner)) - sdef.setPermission(p_areply, 0, (r_manager, r_fmanager, r_reviewer)) - sdef.setPermission(ModifyTopic, 0, (r_manager, r_fmanager, topicOwner)) - sdef.setPermission(DeleteTopic, 0, (r_manager, r_fmanager, topicOwner)) - sdef.setPermission(p_modify, 0, ()) - - # transitions - tdef = wf.transitions['wm_publish'] - tdef.setProperties( - title='Publish', - new_state_id='published', - actbox_name='Publish', - trigger_type=TRIGGER_WORKFLOW_METHOD,) - - tdef = wf.transitions['publish'] - tdef.setProperties( - title='Reviewer publishes content', - new_state_id='published', - actbox_name='Publish', - actbox_url='%(content_url)s/content_publish_form', - after_script_name='stateChanged', - props={'guard_permissions': p_review}) - tdef = wf.transitions['visible'] tdef.setProperties( title='', @@ -390,60 +314,14 @@ after_script_name='stateChanged', props={'guard_permissions': p_review}) - tdef = wf.transitions['reject'] - tdef.setProperties( - title='Reject topic', - new_state_id='rejected', - actbox_name='Reject', - actbox_url='%(content_url)s/forum_content_disable', - after_script_name='stateChanged', - props={'guard_permissions':p_review}) - - tdef = wf.transitions['private'] - tdef.setProperties( - title='Private topic', - new_state_id='private', - actbox_name='Private', - actbox_url='%(content_url)s/forum_content_disable', - after_script_name='stateChanged', - props={'guard_permissions':p_request}) - tdef = wf.transitions['lock'] tdef.setProperties( title='Lock topic', new_state_id='locked', actbox_name='Lock', - actbox_url='%(content_url)s/forum_content_lock', - after_script_name='stateChanged', - props={'guard_permissions':p_review}) - - tdef = wf.transitions['submit'] - tdef.setProperties( - title='Submit state', - new_state_id='waitreview', - actbox_name='Submit', - after_script_name='stateChanged', - props={'guard_permissions':p_request}) - - tdef = wf.transitions['announce'] - tdef.setProperties( - title='', - description='re-announce a retired announcement', - new_state_id='announce', - actbox_name='Announce', after_script_name='stateChanged', props={'guard_permissions': p_review}) - tdef = wf.transitions['retire'] - tdef.setProperties( - title='', - description='Retire an announcement', - new_state_id='retired', - actbox_name='Retire', - after_script_name='stateChanged', - props={'guard_permissions': p_review}) - - # variables wf.variables.setStateVar('review_state') Index: ForumCatalog.py =================================================================== RCS file: /cvsroot/collective/CMFBoard/ForumCatalog.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- ForumCatalog.py 25 Aug 2004 19:13:40 -0000 1.7 +++ ForumCatalog.py 1 Sep 2004 10:16:17 -0000 1.8 @@ -5,78 +5,195 @@ $Id$ """ -from DateTime import DateTime -from Acquisition import aq_base -from ExtensionClass import Base +from types import StringType from Globals import InitializeClass from AccessControl import ClassSecurityInfo -from AccessControl.PermissionRole import rolesForPermissionOn -from BTrees.IOBTree import IOBTree -from BTrees.OOBTree import OOBTree, OOSet, OOTreeSet, union, intersection -from Products.CMFCore.utils import _mergedLocalRoles, _getAuthenticatedUser from Products.Archetypes.CatalogMultiplex import CatalogMultiplex -from Products.CMFCore.CatalogTool import CatalogTool +from Products.CMFCore.utils import getToolByName from Products.CMFCore.CMFCorePermissions import \ View, ManagePortal, ModifyPortalContent +from BTrees.OOBTree import OOBTree +from BTrees.IOBTree import IOBTree +from BTrees.IIBTree import IIBTree, IISet, IITreeSet, union, intersection +from ListSupport import ListSupport, allowedRolesAndUsers -class ForumCatalog(CatalogTool): - """ """ - meta_type = 'ForumCatalog' - - id = 'forum_catalog' +class ForumCatalogSupport(ListSupport): security = ClassSecurityInfo() - security.declarePublic( 'enumerateIndexes' ) - def enumerateIndexes( self ): - return ( ('modified', 'DateIndex'), - ('allowedRolesAndUsers', 'KeywordIndex'), - ('review_state', 'FieldIndex'), - ('sticky_flag', 'FieldIndex'), - ) - - security.declarePublic( 'enumerateColumns' ) - def enumerateColumns( self ): - return ( ) + security.declarePublic(View, 'dump_catalog') + def dump_catalog(self): + """ """ + print list(self._review_index.items()) - def _listAllowedRolesAndUsers( self, user ): - # Makes sure the list includes the user's groups - result = list( user.getRoles() ) - if hasattr(aq_base(user), 'getGroups'): - result = result + ['user:%s' % x for x in user.getGroups()] - result.append( 'Anonymous' ) - result.append( 'user:%s' % user.getId() ) - return result + def __init__(self): + ListSupport.__init__(self) + + # review_state index + review_index = OOBTree() + review_index['admin'] = IITreeSet() + review_index['announce'] = IITreeSet() + review_index['visible'] = IITreeSet() + review_index['locked'] = IITreeSet() + self._review_index = review_index + + # sticky index + self._sticky_on = IITreeSet() + self._sticky_off = IITreeSet() -InitializeClass(ForumCatalog) + def _get_time_key(self, obj): + return self._convert(obj.modified()) + def _get_object_roles(self, obj): + try: + return [hash(r) for r in allowedRolesAndUsers( + obj._getOb(obj.getFirstMessage()))] + except: + return ListSupport._get_object_roles(self, obj) -def addForumCatalog(self): - ob = ForumCatalog() - self._setObject(ob.getId(), ob) + def _insert(self, id, mtime, object): + ListSupport._insert(self, id, mtime, object) + + #============================= + # add to review_state index + #============================= + wtool = getToolByName(self, 'portal_workflow') + review_state = wtool.getInfoFor(object, 'review_state', '') + self._review_index[review_state].insert(id) - return ob + #============================= + # add to sticky index + #============================= + sticky_flag = object.sticky_flag + if sticky_flag: + index = self._sticky_on + else: + index = self._sticky_off + index.insert(id) -class ForumCatalogSupport(Base): + def _remove(self, id, mtime, object): + ListSupport._remove(self, id, mtime, object) - def __init__(self): - # modified index - self._modified_index = IOBTree() + # remove from review_state index + for key, set in self._review_index.items(): + try: + set.remove(id) + except: + pass - # allowedRolesAndUsers index - self._forum_access_index = IOBTree() - self._forum_access_unindex = OOBTree() + # remove from sticky index + for index in (self._sticky_on, self._sticky_off): + try: + index.remove(id) + except: + pass - # review_state index - self._review_index = IOBTree() + security.declarePrivate('getTopicsList') + def getTopicsList(self): + allowed = None + index = self._list_access_index + for role in self._get_user_roles(): + set = index.get(role, None) + if set is not None: + allowed = union(allowed, set) - # sticky index - self._sticky_index = OOTreeSet() - self._unsticky_index = OOTreeSet() + topics = IISet(self._list_index.values()) + + review_index = self._review_index + reviews = union(review_index['visible'], + review_index['locked']) + reviews = union(reviews, review_index['announce']) + + topics_list = intersection(topics, reviews) + + topics1 = intersection(topics, review_index['admin']) + print 'admin', list(topics1) + + topics2 = intersection(topics_list, self._sticky_on) + print 'on', list(topics2) + + topics3 = intersection(topics_list, self._sticky_off) + print 'off', list(topics3) + + return LazyList(self, topics1, topics2, topics3) + +class LazyList: + + def __init__(self, list, topics1, topics2, topics3): + self._list = list + self._topics1 = topics1 + self._topics2 = topics2 + self._topics3 = topics3 + + topics1_len = len(topics1) + topics2_len = len(topics2) + topics3_len = len(topics3) + + self._total_len = topics1_len + topics2_len + topics3_len + + self._topics1_start = 0 + self._topics2_start = topics1_len + self._topics3_start = topics1_len + topics2_len + + def __len__(self): + return self._total_len + + def __getitem__(self, key): + if key < self._topics2_start: + hashId = self._topics1[key] + return self._list._hash_map[hashId] + + if key < self._topics3_start: + hashId = self._topics2[key - self._topics2_start] + return self._list._hash_map[hashId] + if key < self._total_len+1: + hashId = self._topics3[key - self._topics3_start] + return self._list._hash_map[hashId] + + raise KeyError, key + + def getNext(self, id): + id = hash(id) + + if self._topics1.has_key(id): + idx = self._topics1.keys().index(id) + 1 + + elif self._topics2.has_key(id): + idx = self._topics2.keys().index(id) + self._topics2_start + 1 + + elif self._topics3.has_key(id): + idx = self._topics3.keys().index(id) + self._topics3_start + 1 + try: + val = self[idx] + return val + except: + return None + + def getPrev(self, id): + id = hash(id) + + if self._topics1.has_key(id): + idx = self._topics1.keys().index(id) - 1 + + if self._topics2.has_key(id): + idx = self._topics2.keys().index(id) - 1 + self._topics2_start + + if self._topics3.has_key(id): + idx = self._topics3.keys().index(id) - 1 + self._topics3_start + + if idx >= 0: + try: + val = self[idx] + return val + except: + pass + + return None + class ForumCatalogAware(CatalogMultiplex): @@ -86,17 +203,17 @@ def indexObject(self): """ """ CatalogMultiplex.indexObject(self) - self.forum_catalog.indexObject(self) + self.getForum().insertMessageIntoList(self) security.declareProtected(ModifyPortalContent, 'unindexObject') def unindexObject(self): """ """ CatalogMultiplex.unindexObject(self) - self.forum_catalog.unindexObject(self) + self.getForum().removeMessageFromList(self) security.declareProtected(ModifyPortalContent, 'reindexObject') def reindexObject(self, idxs=[]): """ """ CatalogMultiplex.reindexObject(self, idxs) - self.forum_catalog.reindexObject(self, idxs=idxs) + self.getForum().insertMessageIntoList(self) Index: Forum.py =================================================================== RCS file: /cvsroot/collective/CMFBoard/Forum.py,v retrieving revision 1.91 retrieving revision 1.92 diff -u -d -r1.91 -r1.92 --- Forum.py 23 Aug 2004 11:51:06 -0000 1.91 +++ Forum.py 1 Sep 2004 10:16:17 -0000 1.92 @@ -23,13 +23,13 @@ from config import * from uihelpers import UIHelpers, ForumView from utils import isPortalMember -from ForumCatalog import * from ForumPermissions import * from UserPreferences import UserPreferences from PermissionsManagement import PermissionsManagement from CacheHooks import CacheHooks from ForumSchema import forumSchema from ForumExtensibleSchema import ForumExtensibleSchema +from ForumCatalog import ForumCatalogSupport from HitsCounter import HitsCounterForum try: @@ -48,7 +48,7 @@ class ForumNB(ForumExtensibleSchema, BaseBTreeFolder, Subscribeable, CacheHooks, UserPreferences, PermissionsManagement, - MailReceiver, HitsCounterForum, UIHelpers, ForumView): + MailReceiver, HitsCounterForum, UIHelpers, ForumView, ForumCatalogSupport): """ Forum """ meta_type = 'ForumNB' archetype_name = 'ForumNB' @@ -101,7 +101,8 @@ def __init__(self, oid, **kw): BaseBTreeFolder.__init__(self, oid, **kw) - + ForumCatalogSupport.__init__(self) + self.replies = Length() self._internal_version = INTERNAL_VERSION @@ -184,9 +185,6 @@ BaseBTreeFolder.initializeArchetype(self, **kwargs) - if not hasattr(aq_base(self), ForumCatalog.id): - addForumCatalog(self) - security.declareProtected(View, 'getForum') def getForum(self): """ """ Index: ListSupport.py =================================================================== RCS file: /cvsroot/collective/CMFBoard/ListSupport.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- ListSupport.py 25 Aug 2004 19:13:40 -0000 1.4 +++ ListSupport.py 1 Sep 2004 10:16:29 -0000 1.5 @@ -12,7 +12,7 @@ from AccessControl import ClassSecurityInfo from AccessControl.PermissionRole import rolesForPermissionOn from BTrees.IOBTree import IOBTree -from BTrees.OOBTree import OOBTree, OOSet, OOTreeSet, union, intersection +from BTrees.IIBTree import IIBTree, IISet, IITreeSet, union, intersection from Products.CMFCore.utils import _mergedLocalRoles, _getAuthenticatedUser @@ -39,63 +39,102 @@ security = ClassSecurityInfo() def __init__(self): - self._list_index = IOBTree() + self._hash_map = IOBTree() + + # mtime index + self._list_index = IIBTree() + self._list_unindex = IIBTree() + + # allowRolesAndUsers index self._list_access_index = IOBTree() - self._list_access_unindex = OOBTree() + self._list_access_unindex = IOBTree() - security.declarePrivate('insertMessageIntoList') - def insertMessageIntoList(self, msg): - """ insert message into list """ - self.removeMessageFromList(msg) + def _get_time_key(self, obj): + return self._convert(obj.created()) - msgId = msg.getId() + def _get_object_roles(self, obj): + return [hash(r) for r in allowedRolesAndUsers(obj)] - created = self._convert(msg.created()) + def _get_user_roles(self): + user = _getAuthenticatedUser(self) + + roles = list( user.getRoles() ) + if hasattr(aq_base(user), 'getGroups'): + roles = roles + ['user:%s' % x for x in user.getGroups()] + roles.append( 'Anonymous' ) + roles.append( 'user:%s' % user.getId() ) + return [hash(r) for r in roles] - self._list_index[created] = msgId + def _insert(self, id, mtime, object): + self._list_index[mtime] = id + self._list_unindex[id] = mtime index = self._list_access_index - roles = [hash(r) for r in allowedRolesAndUsers(msg)] + roles = self._get_object_roles(object) for r in roles: row = index.get(r, None) if row is None: - row = OOTreeSet((msgId,)) + row = IITreeSet((id,)) else: - row.insert(msgId) + row.insert(id) index[r] = row - self._list_access_unindex[msgId] = roles - - security.declarePrivate('removeMessage') - def removeMessageFromList(self, msg): - """ remove message from list """ - msgId = msg.getId() - - created = self._convert(msg.created()) + self._list_access_unindex[id] = roles + def _remove(self, id, mtime, object): try: - del self._list_index[created] + t = self._list_unindex[id] + self._list_index.remove(t) + self._list_unindex.remove(id) except: pass index = self._list_access_index unindex = self._list_access_unindex - if unindex.has_key(msgId): - for r in unindex[msgId]: + if unindex.has_key(id): + for r in unindex[id]: row = index.get(hash(r), None) if row is not None: try: - row.remove(msgId) + row.remove(id) except KeyError: pass + security.declarePrivate('insertMessageIntoList') + def insertMessageIntoList(self, object): + """ insert message into list """ + self.removeMessageFromList(object) + + obId = object.getId() + hashId = hash(obId) + mtime = self._get_time_key(object) + + self._hash_map[hashId] = obId + self._insert(hashId, mtime, object) + + security.declarePrivate('removeMessage') + def removeMessageFromList(self, object): + """ remove message from list """ + + id = object.getId() + hashId = hash(id) + mtime = self._get_time_key(object) + + try: + self._hash_map.remove(hashId) + except: + pass + + self._remove(hashId, mtime, object) + security.declareProtected('View', 'getFirstMessage') def getFirstMessage(self): """ returns first message """ try: index = self._list_index - return index[index.minKey()] + print index.minKey(), index[index.minKey()] + return self._hash_map[index[index.minKey()]] except: return None @@ -104,10 +143,10 @@ """ returns first message """ try: index = self._list_index - return index[index.maxKey()] + return self._hash_map[index[index.maxKey()]] except: return None - + security.declarePrivate('getMessagesList') def getMessagesList(self, order='direct'): """ return list topics sortet by creation time @@ -118,28 +157,20 @@ # otherwise select all (speed optimization) r = None if self.getForum().isModerated(): - user = _getAuthenticatedUser(self) - - roles = list( user.getRoles() ) - if hasattr(aq_base(user), 'getGroups'): - roles = roles + ['user:%s' % x for x in user.getGroups()] - roles.append( 'Anonymous' ) - roles.append( 'user:%s' % user.getId() ) - index = self._list_access_index - for role in roles: - set = index.get(hash(role), None) + for role in self._get_user_roles(): + set = index.get(role, None) if set is not None: r = union(r, set) results = self._list_index.values() if r is not None: - results = intersection(OOSet(results), r) + results = intersection(IISet(results), r) if order == 'reverse': - return LazyListReverse(results) + return LazyListReverse(self, results) else: - return results + return LazyList(self, results) def _convert(self, value): @@ -181,9 +212,9 @@ return t_val -class LazyListReverse: - - def __init__(self, seq): +class LazyList: + def __init__(self, list, seq): + self._list = list self._seq = seq self._len = len(seq) @@ -191,4 +222,12 @@ return self._len def __getitem__(self, key): - return self._seq[self._len - key - 1] + hashId = self._seq[key] + return self._list._hash_map[hashId] + + +class LazyListReverse(LazyList): + + def __getitem__(self, key): + hashId = self._seq[self._len - key - 1] + return self._list._hash_map[hashId] |