[CMF-checkins] CVS: CMF/CMFTopic - AbstractCriterion.py:1.4.8.1 DateCriteria.py:1.3.8.1 ListCriterion.py:1.7.8.1 SimpleIntCriterion.py:1.7.8.1 SimpleStringCriterion.py:1.7.8.1 SortCriterion.py:1.3.8.1 Topic.py:1.27.8.1 TopicPermissions.py:1.3.8.1 __init__.py:1.11.8.1

Tres Seaver tseaver@zope.com
Thu, 20 Dec 2001 15:35:12 -0500


Update of /cvs-repository/CMF/CMFTopic
In directory cvs.zope.org:/tmp/cvs-serv25280

Modified Files:
      Tag: tseaver-tracker_439-branch
	AbstractCriterion.py DateCriteria.py ListCriterion.py 
	SimpleIntCriterion.py SimpleStringCriterion.py 
	SortCriterion.py Topic.py TopicPermissions.py __init__.py 
Log Message:


  - Normalize imports (import in standard order).
  
  - Normalize coding standards (copyright, whitespace, docstrings, etc.)
  
  - Normalize unit tests (e.g., use 'assertEquals', import w/in test, etc.)
  
  - Refactor some criterion code for clarity.
  
  - Refactor unit tests to create smaller, more "atomic" tests.
  
  - SimpleIntCriterion:  require/allow two values for "min/max" case 
    (Tracker #439).
    
  - Add unit tests for SortCriterion.
  
  - Topic:  enable adding sub-topics even when 'portal_types' can't be
    found.


=== CMF/CMFTopic/AbstractCriterion.py 1.4 => 1.4.8.1 ===
 ##############################################################################
 """Home of the abstract Criterion base class.
+
 $Id$
 """
-__version__='$Revision$'[11:-2]
+__version__ = '$Revision$'[11:-2]
+
+from Products.CMFTopic.TopicPermissions import ChangeTopics
+
+from Products.CMFCore.CMFCorePermissions import AccessContentsInformation
 
-from OFS.SimpleItem import Item
-from Globals import Persistent, InitializeClass
 from Acquisition import Implicit
 from AccessControl import ClassSecurityInfo
-import string, operator
+from Persistence import Persistent
+from Globals import InitializeClass
+from OFS.SimpleItem import Item
 
-from Products.CMFCore.CMFCorePermissions import AccessContentsInformation
-from TopicPermissions import ChangeTopics
+import string, operator
 
-class AbstractCriterion(Persistent, Item, Implicit):
-    """ Abstract base class for Criterion objects. """
+class AbstractCriterion( Persistent, Item, Implicit ):
+    """
+        Abstract base class for Criterion objects.
+    """
 
     security = ClassSecurityInfo()
 
     security.declareProtected(ChangeTopics, 'apply')
-    def apply(self, command):
-        """\
-        command is expected to be a dictionary.  It gets applied
-        to self.edit, and exists to make using Python Scripts
-        easier.
-        """
-        apply(self.edit, (), command)
-
-    security.declareProtected(ChangeTopics, 'editableAttributes')
-    def editableAttributes(self):
-        """\
-        Return a list of editable attributes, used by topics
-        to build commands to send to the 'edit' command of each
-        criterion, which may vary.
-
-        Requires concrete subclasses to implement the attribute
-        '_editableAttributes' which is a tuple of attributes
-        that can be edited, for example:
+    def apply( self, command ):
+        """
+            Apply 'command', which is expected to be a dictionary,
+            to 'self.edit' (makes using Python Scripts easier).
+        """
+        apply( self.edit, (), command )
 
-          _editableAttributes = ('value', 'direction',)
+    security.declareProtected( ChangeTopics, 'editableAttributes' )
+    def editableAttributes( self ):
+        """
+            Return a list of editable attributes, used by topics
+            to build commands to send to the 'edit' command of each
+            criterion, which may vary.
+
+            Requires concrete subclasses to implement the attribute
+            '_editableAttributes' which is a tuple of attributes
+            that can be edited, for example:
+
+            _editableAttributes = ( 'value', 'direction' )
         """
         return self._editableAttributes
 
-    security.declareProtected(AccessContentsInformation, 'Type')
-    def Type(self):
-        """\
-        Return the Type of Criterion this object is.  This
-        method can be overriden in subclasses, or those
-        concrete subclasses must define the 'meta_type'
-        attribute.
+    security.declareProtected( AccessContentsInformation, 'Type' )
+    def Type( self ):
+        """
+            Return the Type of Criterion this object is.  This
+            method can be overriden in subclasses, or those
+            concrete subclasses must define the 'meta_type'
+            attribute.
         """
         return self.meta_type
     
-    security.declareProtected(AccessContentsInformation, 'Field')
-    def Field(self):
-        """\
-        Return the field that this criterion searches on.  The
-        concrete subclasses can override this method, or have
-        the 'field' attribute.
+    security.declareProtected( AccessContentsInformation, 'Field' )
+    def Field( self ):
+        """
+            Return the field that this criterion searches on.  The
+            concrete subclasses can override this method, or have
+            the 'field' attribute.
         """
         return self.field
 
-    security.declareProtected(AccessContentsInformation, 'Description')
-    def Description(self):
-        """\
-        Return a brief but helpful description of the Criterion type,
-        preferably based on the classes __doc__ string.
+    security.declareProtected( AccessContentsInformation, 'Description' )
+    def Description( self ):
+        """
+            Return a brief but helpful description of the Criterion type,
+            preferably based on the classes __doc__ string.
         """
         strip = string.strip
         split = string.split
@@ -89,6 +94,4 @@
                    )
             )
 
-InitializeClass(AbstractCriterion)
-
-        
+InitializeClass( AbstractCriterion )


=== CMF/CMFTopic/DateCriteria.py 1.3 => 1.3.8.1 ===
 ##############################################################################
 """Various date criteria
+
 $Id$
 """
-__version__='$Revision$'[11:-2]
+__version__ = '$Revision$'[11:-2]
+
+from Products.CMFTopic.AbstractCriterion import AbstractCriterion
+from Products.CMFTopic.interfaces import Criterion
+from Products.CMFTopic.Topic import Topic
+from Products.CMFTopic.Topic import TopicPermissions
+
+from Products.CMFCore import CMFCorePermissions
 
 from AccessControl import ClassSecurityInfo
-from Topic import Topic
-from AbstractCriterion import AbstractCriterion
 from DateTime.DateTime import DateTime
-import Globals, string, interfaces, operator
+import Globals
 
-from Products.CMFCore import CMFCorePermissions
-import TopicPermissions
+import string, operator
 
-class FriendlyDateCriterion(AbstractCriterion):
-    """\
-    Put a friendly interface on date range searches, like
-    'where effective date is less than 5 days old'.
+class FriendlyDateCriterion( AbstractCriterion ):
+    """
+        Put a friendly interface on date range searches, like
+        'where effective date is less than 5 days old'.
     """
-    __implements__ = (interfaces.Criterion,)
+    __implements__ = ( Criterion, )
+
     meta_type = 'Friendly Date Criterion'
+
     security = ClassSecurityInfo()
 
-    _editableAttributes = ('value', 'operation', 'daterange')
+    _editableAttributes = ( 'value', 'operation', 'daterange' )
+
+    _defaultDateOptions = ( (     1, '1 Day'    )
+                          , (     2, '2 Days'   )
+                          , (     5, '5 Days'   )
+                          , (     7, '1 Week'   )
+                          , (    14, '2 Weeks'  )
+                          , (    31, '1 Month'  )
+                          , (  31*3, '3 Months' )
+                          , (  31*6, '6 Months' )
+                          , (   365, '1 Year'   )
+                          , ( 365*2, '2 years'  )
+                          )
+
+    def __init__( self, id, field ):
 
-    _defaultDateOptions = (
-        (1, '1 Day'),
-        (2, '2 Days'),
-        (5, '5 Days'),
-        (7, '1 Week'),
-        (14, '2 Weeks'),
-        (31, '1 Month'),
-        (31*3, '3 Months'),
-        (31*6, '6 Months'),
-        (365, '1 Year'),
-        (365*2, '2 years'),
-        )
-    def __init__(self, id, field):
-        self.id, self.field = id, field
+        self.id = id
+        self.field = field
         self.value = None
         self.operation = 'min'
         self.daterange = 'old'
 
-    security.declarePublic('defaultDateOptions')
-    def defaultDateOptions(self):
-        """ List of default values and labels for date options """
+    security.declarePublic( 'defaultDateOptions' )
+    def defaultDateOptions( self ):
+        """
+            Return a list of default values and labels for date options.
+        """
         return self._defaultDateOptions
 
-    security.declareProtected(TopicPermissions.ChangeTopics, 'getEditForm')
-    def getEditForm(self):
+    security.declareProtected( TopicPermissions.ChangeTopics, 'getEditForm' )
+    def getEditForm( self ):
+        """
+            Return the name of the skin method used by Topic to edit
+            criteria of this type.
+        """
         return 'friendlydatec_editform'
 
-    security.declareProtected(TopicPermissions.ChangeTopics, 'edit')
-    def edit(self, value=None, operation='min', daterange='old'):
-        """ Update the values to match against """
-        if value in (None, ''):
+    security.declareProtected( TopicPermissions.ChangeTopics, 'edit' )
+    def edit( self
+            , value=None
+            , operation='min'
+            , daterange='old'
+            ):
+        """
+            Update the values to match against.
+        """
+        if value in ( None, '' ):
             self.value = None
         else:
-            try: self.value = int(value)
-            except: raise ValueError, 'Supplied value should be an int'
+            try:
+                self.value = int( value )
+            except:
+                raise ValueError, 'Supplied value should be an int'
 
-        if operation in ('min','max'):
+        if operation in ( 'min','max' ):
             self.operation = operation
         else:
             raise ValueError, 'Operation type not in set {min,max}'
 
-        if daterange in ('old', 'ahead'):
+        if daterange in ( 'old', 'ahead' ):
             self.daterange = daterange
         else:
             raise ValueError, 'Date range not in set {old,ahead}'
 
-    security.declareProtected(CMFCorePermissions.View, 'getCriteriaItems')
-    def getCriteriaItems(self):
-        """ Return items to be used to build the catalog query """
-        if self.value is None: return ()
-        field = self.Field()
-        value = self.value
+    security.declareProtected( CMFCorePermissions.View, 'getCriteriaItems' )
+    def getCriteriaItems( self ):
+        """
+            Return a sequence of items to be used to build the catalog query.
+        """
+        result = []
+
+        if self.value is not None:
+
+            field = self.Field()
+            value = self.value
+
+            # Negate the value for 'old' days
+            if self.daterange == 'old':
+                value = -value
 
-        # Negate the value for 'old' days
-        if self.daterange == 'old': value = -value
+            date = DateTime() + value
 
-        date = DateTime() + value
+            result.append( ( field, date ) )
 
-        result = ((field, date),
-                  ('%s_usage' % field, 'range:%s' % self.operation),)
+            result.append( ( '%s_usage' % field
+                           , 'range:%s' % self.operation
+                           ) )
 
         return result
 
-Globals.InitializeClass(FriendlyDateCriterion)
+Globals.InitializeClass( FriendlyDateCriterion )
 
 # Register as a criteria type with the Topic class
-Topic._criteriaTypes.append(FriendlyDateCriterion)
+Topic._criteriaTypes.append( FriendlyDateCriterion )


=== CMF/CMFTopic/ListCriterion.py 1.7 => 1.7.8.1 ===
 ##############################################################################
 """List Criterion: A criterion that is a list
+
 $Id$
 """
-__version__='$Revision$'[11:-2]
+__version__ = '$Revision$'[11:-2]
 
-from AccessControl import ClassSecurityInfo
-from Topic import Topic
-from AbstractCriterion import AbstractCriterion
-import Globals, string, interfaces, operator
+from Products.CMFTopic.AbstractCriterion import AbstractCriterion
+from Products.CMFTopic.interfaces import Criterion
+from Products.CMFTopic.Topic import Topic
+from Products.CMFTopic import TopicPermissions
 
 from Products.CMFCore import CMFCorePermissions
-import TopicPermissions
 
-class ListCriterion(AbstractCriterion):
-    """\
-    Represent a criterion which is a list of values (for an
-    'OR' search).
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+
+import string, operator
+
+class ListCriterion( AbstractCriterion ):
+    """
+        Represent a criterion which is a list of values (for an
+        'OR' search).
     """
-    __implements__ = (interfaces.Criterion,)
+    __implements__ = ( Criterion, )
 
     meta_type = 'List Criterion'
 
     security = ClassSecurityInfo()
 
-    _editableAttributes = ('value',)
+    _editableAttributes = ( 'value', )
 
-    def __init__( self, id, field):
+    def __init__( self, id, field ):
         self.id = id
         self.field = field
-        
-        self.value = ('',)
+        self._clear()
 
-    security.declareProtected(TopicPermissions.ChangeTopics, 'getEditForm')
-    def getEditForm(self):
+    security.declarePrivate( '_clear' )
+    def _clear( self ):
+        """
+            Restore to original value.
+        """
+        self.value = ( '', )    # *Not* '()', which won't do at all!
+
+    security.declareProtected( TopicPermissions.ChangeTopics, 'getEditForm' )
+    def getEditForm( self ):
+        """
+            Return the name of skin method which renders the form
+            used to edit this kind of criterion.
+        """
         return "listc_edit"
 
-    security.declareProtected(TopicPermissions.ChangeTopics, 'edit')
-    def edit(self, value=None, REQUEST=None):
-        """ Update the value we match against. """
-        if value is not None:
-            if type(value) == type(''):
-                value = string.split(value, '\n')
-            self.value = tuple(value)
+    security.declareProtected( TopicPermissions.ChangeTopics, 'edit' )
+    def edit( self, value=None ):
+        """
+            Update the value we match against.
+        """
+        if value is None:
+            self._clear()
         else:
-            self.value = ('',)
-
-    security.declareProtected(CMFCorePermissions.View, 'getCriteriaItems')
-    def getCriteriaItems(self):
-        """ Used by Topic.buildQuery to construct catalog queries """
+            if type( value ) == type( '' ):
+                value = string.split( value, '\n' )
+            self.value = tuple( value )
+
+    security.declareProtected( CMFCorePermissions.View, 'getCriteriaItems' )
+    def getCriteriaItems( self ):
+        """
+            Return a tuple of query elements to be passed to the catalog
+            (used by 'Topic.buildQuery()').
+        """
         # filter out empty strings
-        value = tuple(filter(operator.truth, self.value)) 
-        return operator.truth(value) and ((self.field, self.value),) or ()
+        value = tuple( filter( operator.truth, self.value ) ) 
+        return operator.truth( value ) and ( ( self.field, self.value ), ) or ()
 
 
 
-Globals.InitializeClass(ListCriterion)
+InitializeClass( ListCriterion )
 
 # Register as a criteria type with the Topic class
-Topic._criteriaTypes.append(ListCriterion)
+Topic._criteriaTypes.append( ListCriterion )


=== CMF/CMFTopic/SimpleIntCriterion.py 1.7 => 1.7.8.1 ===
 ##############################################################################
 """Simple int-matching criterion
+
 $Id$
 """
 __version__='$Revision$'[11:-2]
 
-from AbstractCriterion import AbstractCriterion
-from AccessControl import ClassSecurityInfo
-from Topic import Topic
-import Globals, interfaces, string
+from Products.CMFTopic import TopicPermissions
+from Products.CMFTopic.AbstractCriterion import AbstractCriterion
+from Products.CMFTopic.Topic import Topic
+from Products.CMFTopic.interfaces import Criterion
 
 from Products.CMFCore import CMFCorePermissions
-import TopicPermissions
 
-class SimpleIntCriterion(AbstractCriterion):
-    """\
-    Represent a simple field-match for an integer value, including
-    catalog range searches.    
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+
+class SimpleIntCriterion( AbstractCriterion ):
+    """
+        Represent a simple field-match for an integer value, including
+        catalog range searches.    
     """
-    __implements__ = (interfaces.Criterion,)
+    __implements__ = ( Criterion, )
+
     meta_type = 'Integer Criterion'
 
     security = ClassSecurityInfo()
-    _editableAttributes = ('value', 'direction',)
+    _editableAttributes = ( 'value', 'direction' )
 
     MINIMUM = 'min'
     MAXIMUM = 'max'
@@ -43,40 +47,89 @@
         self.field = field
         self.value = self.direction = None
 
-    security.declareProtected(TopicPermissions.ChangeTopics, 'getEditForm')
-    def getEditForm(self):
-        """ Used to build sequences of editable criteria """
+    security.declareProtected( TopicPermissions.ChangeTopics, 'getEditForm' )
+    def getEditForm( self ):
+        """
+            Return the name of skin method which renders the form
+            used to edit this kind of criterion.
+        """
         return 'sic_edit'
 
-    security.declareProtected(TopicPermissions.ChangeTopics, 'edit')
-    def edit(self, value, direction=None):
-        """ Update the value we match against. """
-        if type(value) == type('') and (not string.strip(value)):
+    security.declareProtected( TopicPermissions.ChangeTopics, 'getValueString' )
+    def getValueString( self ):
+        """
+            Return a string representation of the value for which this
+            criterion filters.
+        """
+        if self.value is None:
+            return ''
+
+        if self.direction == self.MINMAX:
+
+            value = self.value
+
+            if type( value ) is not type( () ):
+                value = ( value, value )
+
+            return '%s %s' % value
+
+        return str( self.value )
+
+    security.declareProtected( TopicPermissions.ChangeTopics, 'edit' )
+    def edit( self, value, direction=None ):
+        """
+            Update the value to be filtered, and the "direction" qualifier.
+        """
+        from string import strip, split # XXX: WAAAA! 2.3 compatibility
+
+        if type( value ) == type( '' ):
+           value = strip( value )
+
+        if not value:
             # An empty string was passed in, which evals to None
             self.value = self.direction = None
+
         elif direction:
-            self.value = int(value)
+
+            if direction == self.MINMAX:
+
+                if type( value ) == type( '' ):
+                    minimum, maximum = split( value, ' ' )
+                else:
+                    minimum, maximum = value
+
+                self.value = ( int( minimum ), int( maximum ) )
+
+            else:
+                self.value = int( value )
+
             self.direction = direction
+
         else:
-            self.value = int(value)
+            self.value = int( value )
             self.direction = None
 
-    security.declareProtected(CMFCorePermissions.View, 'getCriteriaItems')
-    def getCriteriaItems(self):
-        """ Used by Topic.buildQuery() """
+    security.declareProtected( CMFCorePermissions.View, 'getCriteriaItems' )
+    def getCriteriaItems( self ):
+        """
+            Return a tuple of query elements to be passed to the catalog
+            (used by 'Topic.buildQuery()').
+        """
         if self.value is None:
             return ()
 
-        result = ((self.Field(), self.value),)
+        result = [ ( self.Field(), self.value ) ]
 
         if self.direction is not None:
-            result = result + (('%s_usage' % self.Field(), 
-                                'range:%s' % self.direction ),)
-        return result
+            result.append( ( '%s_usage' % self.Field()
+                           , 'range:%s' % self.direction
+                           ) )
+
+        return tuple( result )
 
 
 
-Globals.InitializeClass(SimpleIntCriterion)
+InitializeClass( SimpleIntCriterion )
 
 # Register as a criteria type with the Topic class
-Topic._criteriaTypes.append(SimpleIntCriterion)
+Topic._criteriaTypes.append( SimpleIntCriterion )


=== CMF/CMFTopic/SimpleStringCriterion.py 1.7 => 1.7.8.1 ===
 ##############################################################################
 """Simple string-matching criterion class
+
 $Id$
 """
 __version__='$Revision$'[11:-2]
 
-from AbstractCriterion import AbstractCriterion
-from AccessControl import ClassSecurityInfo
-from Topic import Topic
-import Globals, interfaces
+from Products.CMFTopic import TopicPermissions
+from Products.CMFTopic.AbstractCriterion import AbstractCriterion
+from Products.CMFTopic.Topic import Topic
+from Products.CMFTopic.interfaces import Criterion
 
 from Products.CMFCore import CMFCorePermissions
-import TopicPermissions
 
-class SimpleStringCriterion(AbstractCriterion):
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+
+class SimpleStringCriterion( AbstractCriterion ):
     """
-    Represent a simple field-match for a string value.
+        Represent a simple field-match for a string value.
     """
-    __implements__ = (interfaces.Criterion,)
+    __implements__ = ( Criterion, )
 
     meta_type = 'String Criterion'
+
     security = ClassSecurityInfo()
 
-    _editableAttributes = ('value',)
+    _editableAttributes = ( 'value', )
 
     def __init__(self, id, field):
         self.id = id
         self.field = field
         self.value = ''
         
-    security.declareProtected(TopicPermissions.ChangeTopics, 'getEditForm')
-    def getEditForm(self):
-        " Return the skinned name of the edit form "
+    security.declareProtected( TopicPermissions.ChangeTopics, 'getEditForm' )
+    def getEditForm( self ):
+        """
+            Return the skinned name of the edit form.
+        """
         return 'ssc_edit'
     
-    security.declareProtected(TopicPermissions.ChangeTopics, 'edit')
-    def edit(self, value):
-        """ Update the value we are to match up against """
-        self.value = str(value)
+    security.declareProtected( TopicPermissions.ChangeTopics, 'edit' )
+    def edit( self, value ):
+        """
+            Update the value we are to match up against.
+        """
+        self.value = str( value )
     
-    security.declareProtected(CMFCorePermissions.View, 'getCriteriaItems')
+    security.declareProtected( CMFCorePermissions.View, 'getCriteriaItems' )
     def getCriteriaItems( self ):
-        """ Return a sequence of criteria items, used by Topic.buildQuery """
-        return self.value is not '' and ((self.field, self.value),) or ()
+        """
+            Return a sequence of criteria items, used by Topic.buildQuery.
+        """
+        result = []
+
+        if self.value is not '':
+            result.append( ( self.field, self.value ) )
+
+        return tuple( result )
 
 
-Globals.InitializeClass(SimpleStringCriterion)
+InitializeClass( SimpleStringCriterion )
 
 # Register as a criteria type with the Topic class
-Topic._criteriaTypes.append(SimpleStringCriterion)
+Topic._criteriaTypes.append( SimpleStringCriterion )


=== CMF/CMFTopic/SortCriterion.py 1.3 => 1.3.8.1 ===
 ##############################################################################
 """ Allow topic to specify sorting.
+
 $Id$
 """
-__version__='$Revision$'[11:-2]
-from AbstractCriterion import AbstractCriterion
-from AccessControl import ClassSecurityInfo
-from Topic import Topic
-import Globals, interfaces
+__version__ = '$Revision$'[11:-2]
+
+from Products.CMFTopic.AbstractCriterion import AbstractCriterion
+from Products.CMFTopic.Topic import Topic
+from Products.CMFTopic.interfaces import Criterion
+from Products.CMFTopic import TopicPermissions
 
 from Products.CMFCore import CMFCorePermissions
-import TopicPermissions
 
-class SortCriterion(AbstractCriterion):
+from Globals import InitializeClass
+from AccessControl import ClassSecurityInfo
+
+class SortCriterion( AbstractCriterion ):
     """
         Represent a mock criterion, to allow spelling the sort order
         and reversal items in a catalog query.
     """
-    __implements__ = (interfaces.Criterion,)
+    __implements__ = ( Criterion, )
 
     meta_type = 'Sort Criterion'
+
     security = ClassSecurityInfo()
+
     field = None # Don't prevent use of field in other criteria
 
-    _editableAttributes = ('reversed',)
+    _editableAttributes = ( 'reversed', )
 
-    def __init__(self, id, index):
+    def __init__( self, id, index ):
         self.id = id
         self.index = index
         self.reversed = 0
@@ -47,26 +53,35 @@
         """
         return self.index
 
-    security.declareProtected(TopicPermissions.ChangeTopics, 'getEditForm')
-    def getEditForm(self):
-        " Return the skinned name of the edit form "
+    security.declareProtected( TopicPermissions.ChangeTopics, 'getEditForm' )
+    def getEditForm( self ):
+        """
+            Return the name of skin method which renders the form
+            used to edit this kind of criterion.
+        """
         return 'sort_edit'
     
-    security.declareProtected(TopicPermissions.ChangeTopics, 'edit')
-    def edit(self, reversed):
-        """ Update the value we are to match up against """
+    security.declareProtected( TopicPermissions.ChangeTopics, 'edit' )
+    def edit( self, reversed ):
+        """
+            Update the value we are to match up against.
+        """
         self.reversed = not not reversed
     
-    security.declareProtected(CMFCorePermissions.View, 'getCriteriaItems')
+    security.declareProtected( CMFCorePermissions.View, 'getCriteriaItems' )
     def getCriteriaItems( self ):
-        """ Return a sequence of criteria items, used by Topic.buildQuery """
+        """
+            Return a tuple of query elements to be passed to the catalog
+            (used by 'Topic.buildQuery()').
+        """
         result = [ ( 'sort_on', self.index ) ]
+
         if self.reversed:
             result.append( ( 'sort_order', 'reverse' ) )
-        return tuple( result )
 
+        return tuple( result )
 
-Globals.InitializeClass(SortCriterion)
+InitializeClass( SortCriterion )
 
 # Register as a criteria type with the Topic class
-Topic._criteriaTypes.append(SortCriterion)
+Topic._criteriaTypes.append( SortCriterion )


=== CMF/CMFTopic/Topic.py 1.27 => 1.27.8.1 ===
 ##############################################################################
 """Topic: Canned catalog queries
+
 $Id$
 """
-__version__='$Revision$'[11:-2]
+__version__ = '$Revision$'[11:-2]
 
+from Products.CMFTopic import TopicPermissions
 
-import os, urllib
-from Globals import HTMLFile, package_home, InitializeClass
+from Products.CMFCore import CMFCorePermissions
+from Products.CMFCore.utils import _checkPermission, _getViewFor,getToolByName
 from Products.CMFCore.PortalFolder import PortalFolder
-from Products.CMFCore import utils
+
+from Globals import HTMLFile, package_home, InitializeClass
 from AccessControl import ClassSecurityInfo
 from Acquisition import aq_parent, aq_inner, aq_base
 from ComputedAttribute import ComputedAttribute
 
-# Import permission names
-from Products.CMFCore import CMFCorePermissions
-import TopicPermissions
+import os
 
 # Factory type information -- makes Topic objects play nicely
-# with the Types Tool (portal_types)
-factory_type_information = (
-    {'id': 'Topic',
-     'content_icon': 'topic_icon.gif',
-     'meta_type': 'Portal Topic',
-     'description': ('Topics are canned queries for organizing content '
-                     'with up to date queries into the catalog.'),
-     'product': 'CMFTopic',
-     'factory': 'addTopic',
-     'immediate_view': 'topic_edit_form',
-     'actions': ({'id': 'view',
-                  'name': 'View',
-                  'action': 'topic_view',
-                  'permissions': (CMFCorePermissions.View,)},
-                 {'id': 'edit',
-                  'name': 'Edit',
-                  'action': 'topic_edit_form',
-                  'permissions': (TopicPermissions.ChangeTopics,)},
-                 {'id': 'criteria',
-                  'name': 'Criteria',
-                  'action': 'topic_criteria_form',
-                  'permissions': (TopicPermissions.ChangeTopics,)},
-                 {'id': 'subtopics',
-                  'name': 'Subtopics',
-                  'action': 'topic_subtopics_form',
-                  'permissions': (TopicPermissions.ChangeTopics,)},
-                 ),                     # End Actions
-     },
+# with the Types Tool (portal_types )
+factory_type_information = \
+( { 'id'                : 'Topic'
+  , 'content_icon'      : 'topic_icon.gif'
+  , 'meta_type'         : 'Portal Topic'
+  , 'description'       : 'Topics are canned queries for organizing content '
+                          'with up to date queries into the catalog.'
+  , 'product'           : 'CMFTopic'
+  , 'factory'           : 'addTopic'
+  , 'immediate_view'    : 'topic_edit_form'
+  , 'actions'           :
+    ( { 'id'            : 'view'
+      , 'name'          : 'View'
+      , 'action'        : 'topic_view'
+      , 'permissions'   : (CMFCorePermissions.View, )
+      }
+    , { 'id'            : 'edit'
+      , 'name'          : 'Edit'
+      , 'action'        : 'topic_edit_form'
+      , 'permissions'   : (TopicPermissions.ChangeTopics, )
+      }
+    , { 'id'            : 'criteria'
+      , 'name'          : 'Criteria'
+      , 'action'        : 'topic_criteria_form'
+      , 'permissions'   : (TopicPermissions.ChangeTopics, )
+      }
+    , { 'id'            : 'subtopics'
+      , 'name'          : 'Subtopics'
+      , 'action'        : 'topic_subtopics_form'
+      , 'permissions'   : (TopicPermissions.ChangeTopics, )
+      }
     )
+  }
+,
+)
 
-def addTopic(self, id, title='', REQUEST=None):
+def addTopic( self, id, title='', REQUEST=None ):
     """
-    Create an empty topic.
+        Create an empty topic.
     """
-    topic = Topic(id)
+    topic = Topic( id )
     topic.id = id
     topic.title = title
-    self._setObject(id, topic)
+    self._setObject( id, topic )
 
     if REQUEST is not None:
         REQUEST['RESPONSE'].redirect( 'manage_main' )
 
 
-class Topic(PortalFolder):
+class Topic( PortalFolder ):
     """
-    Topics are a 'canned query'.  You construct catalog queries out
-    of Criteria objects.
+        Topics are 'canned queries', which hold a set of zero or more
+        Criteria objects specifying the query.
     """
+
     meta_type='Portal Topic'
 
-    # Use Zope 2.3 declarative security
     security = ClassSecurityInfo()
-    security.declareObjectProtected(CMFCorePermissions.View)
+
+    security.declareObjectProtected( CMFCorePermissions.View )
 
     acquireCriteria = 1
     _criteriaTypes = []
@@ -89,167 +97,190 @@
     # Contentish interface methods
     # ----------------------------
 
-    security.declareProtected(CMFCorePermissions.View, 'icon')
-    def icon(self):
-        """ For the ZMI """
+    security.declareProtected( CMFCorePermissions.View, 'icon' )
+    def icon( self ):
+        """
+            For the ZMI.
+        """
         return self.getIcon()
 
-    def _verifyActionPermissions(self, action):
-        pp = action.get('permissions', ())
+    security.declarePrivate( '_verifyActionPermissions' )
+    def _verifyActionPermissions( self, action ):
+        pp = action.get( 'permissions', () )
         if not pp:
             return 1
         for p in pp:
-            if utils._checkPermission(p, self):
+            if _checkPermission( p, self ):
                 return 1
         return 0
 
-    def __call__(self):
-        '''
-        Invokes the default view.
-        '''
-        view = utils._getViewFor(self)
-        if getattr(aq_base(view), 'isDocTemp', 0):
-            return apply(view, (self, self.REQUEST))
+    def __call__( self ):
+        """
+            Invoke the default action.
+        """
+        view = _getViewFor( self )
+        if getattr( aq_base( view ), 'isDocTemp', 0 ):
+            return apply( view, ( self, self.REQUEST ) )
         else:
             return view()
 
     index_html = None  # This special value informs ZPublisher to use __call__
 
-    security.declareProtected(CMFCorePermissions.View, 'view')
-    def view(self):
-        '''
-        Returns the default view even if index_html is overridden.
-        '''
+    security.declareProtected( CMFCorePermissions.View, 'view' )
+    def view( self ):
+        """
+            Return the default view even if index_html is overridden.
+        """
         return self()
 
-    def _criteria_metatype_ids(self):
+    security.declarePrivate( '_criteria_metatype_ids' )
+    def _criteria_metatype_ids( self ):
         result = []
         for mt in self._criteriaTypes:
-            result.append(mt.meta_type)
-        return tuple(result)
+            result.append( mt.meta_type )
+        return tuple( result )
  
-    security.declareProtected(TopicPermissions.ChangeTopics, 'listCriteria')
-    def listCriteria(self):
-        """ Return a list of our criteria objects """
-        return self.objectValues(self._criteria_metatype_ids())
+    security.declareProtected( TopicPermissions.ChangeTopics, 'listCriteria' )
+    def listCriteria( self ):
+        """
+            Return a list of our criteria objects.
+        """
+        return self.objectValues( self._criteria_metatype_ids() )
 
 
-    security.declareProtected(TopicPermissions.ChangeTopics,
-                              'listCriteriaTypes')
-    def listCriteriaTypes(self):
+    security.declareProtected( TopicPermissions.ChangeTopics
+                             , 'listCriteriaTypes' )
+    def listCriteriaTypes( self ):
         out = []
         for ct in self._criteriaTypes:
-            out.append({
+            out.append( {
                 'name': ct.meta_type,
-                })
+                } )
         return out
     
-    security.declareProtected(TopicPermissions.ChangeTopics,
-                              'listAvailableFields')
-    def listAvailableFields(self):
-        """ Return a list of available fields for new criteria """
-        portal_catalog = utils.getToolByName(self, 'portal_catalog')
-        currentfields = map(lambda x: x.field, self.listCriteria())
+    security.declareProtected( TopicPermissions.ChangeTopics
+                             , 'listAvailableFields' )
+    def listAvailableFields( self ):
+        """
+            Return a list of available fields for new criteria.
+        """
+        portal_catalog = getToolByName( self, 'portal_catalog' )
+        currentfields = map( lambda x: x.Field(), self.listCriteria() )
         availfields = filter(
             lambda field, cf=currentfields: field not in cf,
             portal_catalog.indexes()
             )
         return availfields
 
-    security.declareProtected(TopicPermissions.ChangeTopics, 'listSubtopics')
-    def listSubtopics(self):
-        """ Return a list of our subtopics """
-        return self.objectValues(self.meta_type)
-
-    security.declareProtected(TopicPermissions.ChangeTopics, 'edit')
-    def edit(self, acquireCriteria, title=None, description=None):
-        """\
-        Enable the acquisition of criteria from parent topics, and update
-        other meta data about the Topic.
+    security.declareProtected( TopicPermissions.ChangeTopics, 'listSubtopics' )
+    def listSubtopics( self ):
+        """
+            Return a list of our subtopics.
+        """
+        return self.objectValues( self.meta_type )
+
+    security.declareProtected( TopicPermissions.ChangeTopics, 'edit' )
+    def edit( self, acquireCriteria, title=None, description=None ):
+        """
+            Set the flag which indicates whether to acquire criteria
+            from parent topics; update other meta data about the Topic.
         """
         self.acquireCriteria = acquireCriteria
-        if title is not None: self.title = title
+        if title is not None:
+            self.title = title
         self.description = description
         
-
-    security.declareProtected(CMFCorePermissions.View, 'buildQuery')
-    def buildQuery(self):
-        """ Uses the criteria objects to construct a catalog query. """
+    security.declareProtected( CMFCorePermissions.View, 'buildQuery' )
+    def buildQuery( self ):
+        """
+            Construct a catalog query using our criterion objects.
+        """
         result = {}
 
         if self.acquireCriteria:
             try:
                 # Tracker 290 asks to allow combinations, like this:
-                # parent = aq_parent(self)
-                parent = aq_parent(aq_inner(self))
-                result.update(parent.buildQuery())
+                # parent = aq_parent( self )
+                parent = aq_parent( aq_inner( self ) )
+                result.update( parent.buildQuery() )
             except: # oh well, can't find parent, or it isn't a Topic.
                 pass
 
         for criterion in self.listCriteria():
             for key, value in criterion.getCriteriaItems():
-                result[key] = value
+                result[ key ] = value
         
         return result
     
-    security.declareProtected(CMFCorePermissions.View, 'queryCatalog')
-    def queryCatalog(self, REQUEST=None, **kw):
-        """\
-        Call self.buildQuery and augment any passed in query
-        before calling the catalog.
-        """
-        kw.update(self.buildQuery())
-        portal_catalog = utils.getToolByName(self, 'portal_catalog')
-        return apply(portal_catalog.searchResults, (REQUEST,), kw)
+    security.declareProtected( CMFCorePermissions.View, 'queryCatalog' )
+    def queryCatalog( self, REQUEST=None, **kw ):
+        """
+            Invoke the catalog using our criteria to augment any passed
+            in query before calling the catalog.
+        """
+        kw.update( self.buildQuery() )
+        portal_catalog = getToolByName( self, 'portal_catalog' )
+        return apply( portal_catalog.searchResults, ( REQUEST, ), kw )
 
 
     ### Criteria adding/editing/deleting
-    security.declareProtected(TopicPermissions.ChangeTopics, 'addCriterion')
-    def addCriterion(self, field, criterion_type):
-        """ Create a new search criteria in this topic """
+    security.declareProtected( TopicPermissions.ChangeTopics, 'addCriterion' )
+    def addCriterion( self, field, criterion_type ):
+        """
+            Add a new search criterion.
+        """
         crit = None
         newid = 'crit__%s' % field
         for ct in self._criteriaTypes:
             if criterion_type == ct.meta_type:
-                crit = ct(newid, field)
+                crit = ct( newid, field )
 
         if crit is None:
             # No criteria type matched passed in value
             raise NameError, 'Unknown Criterion Type: %s' % criterion_type
         
-        self._setObject(newid, crit)
+        self._setObject( newid, crit )
 
     # Backwards compatibility (deprecated)
-    security.declareProtected(TopicPermissions.ChangeTopics, 'addCriteria')
+    security.declareProtected( TopicPermissions.ChangeTopics, 'addCriteria' )
     addCriteria = addCriterion
 
-    security.declareProtected(TopicPermissions.ChangeTopics, 'deleteCriterion')
-    def deleteCriterion(self, criterion_id):
-        """ Delete selected criteria """
-        if type(criterion_id) is type(''):
-            self._delObject(criterion_id)
-        elif type(criterion_id) in (type(()), type([])):
+    security.declareProtected( TopicPermissions.ChangeTopics
+                             , 'deleteCriterion' )
+    def deleteCriterion( self, criterion_id ):
+        """
+            Delete selected criterion.
+        """
+        if type( criterion_id ) is type( '' ):
+            self._delObject( criterion_id )
+        elif type( criterion_id ) in ( type( () ), type( [] ) ):
             for cid in criterion_id:
-                self._delObject(cid)
+                self._delObject( cid )
 
-    security.declarePublic(CMFCorePermissions.View, 'getCriterion')
-    def getCriterion(self, criterion_id):
-        """ Get the criterion object """
+    security.declarePublic( CMFCorePermissions.View, 'getCriterion' )
+    def getCriterion( self, criterion_id ):
+        """
+            Get the criterion object.
+        """
         try:
             return self._getOb( 'crit__%s' % criterion_id )
         except AttributeError:
-            return self._getOb(criterion_id)
+            return self._getOb( criterion_id )
 
-    security.declareProtected(TopicPermissions.AddTopics, 'addSubtopic')
-    def addSubtopic(self, id):
-        """ Add a new subtopic """
-        tool = utils.getToolByName( self, 'portal_types' )
-        topictype = tool.getTypeInfo(self)
-        topictype.constructInstance(self, id)
-
-        return self._getOb(id)
+    security.declareProtected( TopicPermissions.AddTopics, 'addSubtopic' )
+    def addSubtopic( self, id ):
+        """
+            Add a new subtopic.
+        """
+        try:
+            tool = getToolByName( self, 'portal_types' )
+        except:
+            self._setOb( id, Topic( id ) )
+        else:
+            topictype = tool.getTypeInfo( self )
+            topictype.constructInstance( self, id )
 
+        return self._getOb( id )
 
 # Intialize the Topic class, setting up security.
-InitializeClass(Topic)
-
+InitializeClass( Topic )


=== CMF/CMFTopic/TopicPermissions.py 1.3 => 1.3.8.1 ===
 ##############################################################################
 """TopicPermissions: Permissions used throughout CMFTopic.
+
 $Id$
 """
 __version__='$Revision$'[11:-2]


=== CMF/CMFTopic/__init__.py 1.11 => 1.11.8.1 ===
 ##############################################################################
 """Topic: Canned catalog queries
+
 $Id$
 """
 __version__='$Revision$'[11:-2]
 
  
+import TopicPermissions
 import Topic
 import SimpleStringCriterion
 import SimpleIntCriterion
 import ListCriterion
 import DateCriteria
 import SortCriterion
-import Products.CMFCore
 
-from ZClasses import createZClassForBase
-from Products.CMFCore import utils
+from Products.CMFCore.utils import ContentInit
 from Products.CMFCore.DirectoryView import registerDirectory
-import TopicPermissions
 
-bases = (Topic.Topic,)
+from ZClasses import createZClassForBase
 
+bases = ( Topic.Topic, )
 
 import sys
 this_module = sys.modules[ __name__ ]
@@ -40,21 +40,21 @@
 
 # This is used by a script (external method) that can be run
 # to set up Topics in an existing CMF Site instance.
-topic_globals=globals()
+topic_globals  =globals()
 
 # Make the skins available as DirectoryViews
-registerDirectory('skins', globals())
-registerDirectory('skins/topic', globals())
+registerDirectory( 'skins', globals() )
+registerDirectory( 'skins/topic', globals() )
 
 def initialize( context ):
-    context.registerHelpTitle('CMF Topic Help')
-    context.registerHelp(directory='help')
+
+    context.registerHelpTitle( 'CMF Topic Help' )
+    context.registerHelp( directory='help' )
 
     # CMF Initializers
-    utils.ContentInit(
-        'CMF Topic Objects',
-        content_types = (Topic.Topic,),
-        permission = TopicPermissions.AddTopics,
-        extra_constructors = (Topic.addTopic,),
-        fti = Topic.factory_type_information,
-        ).initialize(context)
+    ContentInit( 'CMF Topic Objects'
+               , content_types = (Topic.Topic,)
+               , permission = TopicPermissions.AddTopics
+               , extra_constructors = (Topic.addTopic,)
+               , fti = Topic.factory_type_information
+               ).initialize( context )