Code

documentation cleanup
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 11 Feb 2004 23:55:10 +0000 (23:55 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 11 Feb 2004 23:55:10 +0000 (23:55 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@2073 57a73879-2fb5-44c3-a270-3262357dd7e2

60 files changed:
TODO.txt
doc/.cvsignore
doc/admin_guide.txt
roundup/__init__.py
roundup/admin.py
roundup/backends/__init__.py
roundup/backends/back_anydbm.py
roundup/backends/back_bsddb.py
roundup/backends/back_bsddb3.py
roundup/backends/back_metakit.py
roundup/backends/back_mysql.py
roundup/backends/back_postgresql.py
roundup/backends/back_sqlite.py
roundup/backends/blobfiles.py
roundup/backends/locking.py
roundup/backends/portalocker.py
roundup/backends/rdbms_common.py
roundup/backends/sessions.py
roundup/cgi/PageTemplates/Expressions.py
roundup/cgi/PageTemplates/PageTemplate.py
roundup/cgi/PageTemplates/PathIterator.py
roundup/cgi/PageTemplates/PythonExpr.py
roundup/cgi/PageTemplates/TALES.py
roundup/cgi/PageTemplates/__init__.py
roundup/cgi/TAL/HTMLParser.py
roundup/cgi/TAL/HTMLTALParser.py
roundup/cgi/TAL/TALDefs.py
roundup/cgi/TAL/TALGenerator.py
roundup/cgi/TAL/TALInterpreter.py
roundup/cgi/TAL/TALParser.py
roundup/cgi/TAL/XMLParser.py
roundup/cgi/TAL/__init__.py
roundup/cgi/TAL/markupbase.py
roundup/cgi/ZTUtils/Batch.py
roundup/cgi/ZTUtils/Iterator.py
roundup/cgi/ZTUtils/__init__.py
roundup/cgi/__init__.py
roundup/cgi/cgitb.py
roundup/cgi/client.py
roundup/cgi/templating.py
roundup/date.py
roundup/hyperdb.py
roundup/i18n.py
roundup/indexer.py
roundup/init.py
roundup/install_util.py
roundup/instance.py
roundup/mailer.py
roundup/mailgw.py
roundup/password.py
roundup/rcsv.py
roundup/rfc2822.py
roundup/roundupdb.py
roundup/scripts/__init__.py
roundup/scripts/roundup_admin.py
roundup/scripts/roundup_mailgw.py
roundup/scripts/roundup_server.py
roundup/security.py
roundup/token.py
roundup/version_check.py

index cf79d7fedd3d13c057d9ec1aa5fbd9f6cebf3187..f300d4fa255a5a968b02b91d475cca0eab3f54d3 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,7 +1,10 @@
 This file has been re-purposed to contain specifically the items that need
 doing before the next release:
 
+- sessions, otks and indexing in RDBMSes
 - add tests for group-by-multilink so I finally implement it for the RDBMSes
 - full coverage analysis for unit tests
-- migrate to numeric ID values (fixes bug 817217)
+- s/getnode/getitem in backends (and s/Node/Item)
+- activity_by meta-property
 
+- migrate to numeric ID values (fixes bug 817217)
index 77efb766792327e50aa76dfaa5aba3f08d922edd..1a1a62a7822785436b0be535781cc388af37e4a4 100644 (file)
@@ -11,7 +11,7 @@ features.html
 upgrading.html
 glossary.html
 design.html
-maintenance.html
+admin_guide.html
 overview.html
 mysql.html
 postgresql.html
index a48678aa6d9554de567e1e5daa054a875cd6507f..558ea388d33f2ece1d1a42b85b68e6f3bee630d6 100644 (file)
@@ -2,7 +2,7 @@
 Administration Guide
 ====================
 
-:Version: $Revision: 1.1 $
+:Version: $Revision: 1.2 $
 
 .. contents::
 
@@ -23,7 +23,7 @@ There's two "installations" that we talk about when using Roundup:
    Support files
      <python dir>\share\roundup\...
 
-   and on *nix (eg. Linux):
+   and on Unix-like systems (eg. Linux):
 
    Scripts
      <python root>/bin/...
@@ -84,7 +84,7 @@ Maintenance of Roundup can involve one of the following:
 1. `tracker backup`_ 
 2. `software upgrade`_
 3. `migrating backends`_
-3. `moving a tracker`_
+4. `moving a tracker`_
 
 
 Tracker Backup
index 24f50c4a03b72ceb5a4502e9ddc0ddf7ced823bc..f2abcc02765aca39c31fae680e2071ee0a42bed4 100644 (file)
@@ -15,9 +15,9 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: __init__.py,v 1.26 2004-01-20 00:05:07 richard Exp $
+# $Id: __init__.py,v 1.27 2004-02-11 23:55:08 richard Exp $
 
-''' Roundup - issue tracking for knowledge workers.
+'''Roundup - issue tracking for knowledge workers.
 
 This is a simple-to-use and -install issue-tracking system with
 command-line, web and e-mail interfaces.
@@ -43,11 +43,11 @@ Roundup's structure is that of a cake::
  |                             Storage Layer                               |
   -------------------------------------------------------------------------
 
-The first layer represents the users (chocolate).
-The second layer is the Roundup interface to the users (vanilla).
-The third and fourth layers are the internal Roundup database storage
-  mechanisms (strawberry).
-The final, lowest layer is the underlying database storage (rum).
+1. The first layer represents the users (chocolate).
+2. The second layer is the Roundup interface to the users (vanilla).
+3. The third and fourth layers are the internal Roundup database storage
+   mechanisms (strawberry).
+4. The final, lowest layer is the underlying database storage (rum).
 
 These are implemented in the code in the following manner::
 
@@ -66,6 +66,7 @@ For more information, see the original overview and specification documents
 written by Ka-Ping Yee in the "doc" directory. If nothing else, it has a
 much prettier cake :)
 '''
+__docformat__ = 'restructuredtext'
 
 __version__ = '0.7.0b1'
 
index 9ae6ba3eb5cb04ea625aeb7076ef262c14e95f81..c08f0e8bf8c12a94cc8b7c33976bccb5a87a3391 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: admin.py,v 1.61 2003-11-13 04:12:10 richard Exp $
+# $Id: admin.py,v 1.62 2004-02-11 23:55:08 richard Exp $
 
 '''Administration commands for maintaining Roundup trackers.
 '''
+__docformat__ = 'restructuredtext'
 
 import sys, os, getpass, getopt, re, UserDict, shutil, rfc822
 from roundup import date, hyperdb, roundupdb, init, password, token, rcsv
@@ -826,6 +827,7 @@ Command help:
         specified, all properties are displayed. By default, the column widths
         are the width of the largest value. The width may be explicitly defined
         by defining the property as "name:width". For example::
+
           roundup> table priority id,name:10
           Id Name
           1  fatal-bug 
@@ -834,7 +836,8 @@ Command help:
           4  feature   
 
         Also to make the width of the column the width of the label,
-        leave a trailing : without a width on the property. E.G.
+        leave a trailing : without a width on the property. For example::
+
           roundup> table priority id,name:
           Id Name
           1  fata
index 15ae2ac9248784b897072630bf46903bd50ff09e..ecacacb8dfb3f6fed392c9990de41268a94c1cf9 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: __init__.py,v 1.25 2003-10-25 22:53:26 richard Exp $
+# $Id: __init__.py,v 1.26 2004-02-11 23:55:08 richard Exp $
 
-''' Container for the hyperdb storage backend implementations.
+'''Container for the hyperdb storage backend implementations.
 
 The __all__ variable is constructed containing only the backends which are
 available.
 '''
+__docformat__ = 'restructuredtext'
 
 __all__ = []
 
index 6450b26101d756f8c939cd71251dd8de5d4c2147..6ea53c0e0d639ba188c7c9143db6c4f52ca44796 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: back_anydbm.py,v 1.134 2003-12-10 01:40:51 richard Exp $
-'''
-This module defines a backend that saves the hyperdatabase in a database
-chosen by anydbm. It is guaranteed to always be available in python
+#$Id: back_anydbm.py,v 1.135 2004-02-11 23:55:08 richard Exp $
+'''This module defines a backend that saves the hyperdatabase in a
+database chosen by anydbm. It is guaranteed to always be available in python
 versions >2.1.1 (the dumbdbm fallback in 2.1.1 and earlier has several
 serious bugs, and is not available)
 '''
+__docformat__ = 'restructuredtext'
 
 try:
     import anydbm, sys
@@ -50,10 +50,10 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database):
     '''A database for storing records containing flexible data types.
 
     Transaction stuff TODO:
-        . check the timestamp of the class file and nuke the cache if it's
-          modified. Do some sort of conflict checking on the dirty stuff.
-        . perhaps detect write collisions (related to above)?
-
+    
+    - check the timestamp of the class file and nuke the cache if it's
+      modified. Do some sort of conflict checking on the dirty stuff.
+    - perhaps detect write collisions (related to above)?
     '''
     def __init__(self, config, journaltag=None):
         '''Open a hyperdatabase given a specifier to some storage.
@@ -92,14 +92,15 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database):
         self.lockfile.flush()
 
     def post_init(self):
-        ''' Called once the schema initialisation has finished.
+        '''Called once the schema initialisation has finished.
         '''
         # reindex the db if necessary
         if self.indexer.should_reindex():
             self.reindex()
 
     def refresh_database(self):
-        "Rebuild the database"
+        """Rebuild the database
+        """
         self.reindex()
 
     def reindex(self):
@@ -1366,8 +1367,11 @@ class Class(hyperdb.Class):
         WARNING: this method should never be used except in extremely rare
                  situations where there could never be links to the node being
                  deleted
+
         WARNING: use retire() instead
+
         WARNING: the properties of this node will not be available ever again
+
         WARNING: really, use retire() instead
 
         Well, I think that's enough warnings. This method exists mostly to
@@ -1418,14 +1422,15 @@ class Class(hyperdb.Class):
         return self.key
 
     def labelprop(self, default_to_id=0):
-        ''' Return the property name for a label for the given node.
+        '''Return the property name for a label for the given node.
 
         This method attempts to generate a consistent label for the node.
         It tries the following in order:
-            1. key property
-            2. "name" property
-            3. "title" property
-            4. first property from the sorted property name list
+
+        1. key property
+        2. "name" property
+        3. "title" property
+        4. first property from the sorted property name list
         '''
         k = self.getkey()
         if  k:
@@ -1597,21 +1602,23 @@ class Class(hyperdb.Class):
 
     def filter(self, search_matches, filterspec, sort=(None,None),
             group=(None,None), num_re = re.compile('^\d+$')):
-        ''' Return a list of the ids of the active nodes in this class that
-            match the 'filter' spec, sorted by the group spec and then the
-            sort spec.
-
-            "filterspec" is {propname: value(s)}
-            "sort" and "group" are (dir, prop) where dir is '+', '-' or None
-                               and prop is a prop name or None
-            "search_matches" is {nodeid: marker}
-
-            The filter must match all properties specificed - but if the
-            property value to match is a list, any one of the values in the
-            list may match for that property to match. Unless the property
-            is a Multilink, in which case the item's property list must
-            match the filterspec list.
-        '''
+        """Return a list of the ids of the active nodes in this class that
+        match the 'filter' spec, sorted by the group spec and then the
+        sort spec.
+
+        "filterspec" is {propname: value(s)}
+
+        "sort" and "group" are (dir, prop) where dir is '+', '-' or None
+        and prop is a prop name or None
+
+        "search_matches" is {nodeid: marker}
+
+        The filter must match all properties specificed - but if the
+        property value to match is a list, any one of the values in the
+        list may match for that property to match. Unless the property
+        is a Multilink, in which case the item's property list must
+        match the filterspec list.
+        """
         cn = self.classname
 
         # optimise filterspec
index 37abdd88cb838a753c1c484ba9f9c96254e67c1f..0251da8c3128f4f3dfdb8b90d45363c52338e5be 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: back_bsddb.py,v 1.28 2003-11-14 00:11:18 richard Exp $
-'''
-This module defines a backend that saves the hyperdatabase in BSDDB.
+#$Id: back_bsddb.py,v 1.29 2004-02-11 23:55:08 richard Exp $
+'''This module defines a backend that saves the hyperdatabase in BSDDB.
 '''
+__docformat__ = 'restructuredtext'
 
 import bsddb, os, marshal
 from roundup import hyperdb, date
index 444fe65d1f5d38504fe8751cd0f4d08faffd8593..dbf8675e42b8e5684f6afa249de3021d07c50ed3 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: back_bsddb3.py,v 1.21 2003-11-14 00:11:18 richard Exp $
-'''
-This module defines a backend that saves the hyperdatabase in BSDDB3.
+#$Id: back_bsddb3.py,v 1.22 2004-02-11 23:55:08 richard Exp $
+'''This module defines a backend that saves the hyperdatabase in BSDDB3.
 '''
+__docformat__ = 'restructuredtext'
 
 import bsddb3, os, marshal
 from roundup import hyperdb, date
index 201dd4e3acac59b84529a0876c241ad40503b56f..1d2a111726a0ca522331027725e116459c1db56d 100755 (executable)
-# $Id: back_metakit.py,v 1.57 2004-01-27 18:10:48 wc2so1 Exp $
+# $Id: back_metakit.py,v 1.58 2004-02-11 23:55:08 richard Exp $
+'''Metakit backend for Roundup, originally by Gordon McMillan.
+
+Known Current Bugs:
+
+- You can't change a class' key properly. This shouldn't be too hard to fix.
+- Some unit tests are overridden.
+
+Notes by Richard:
+
+This backend has some behaviour specific to metakit:
+
+- there's no concept of an explicit "unset" in metakit, so all types
+  have some "unset" value:
+
+  ========= ===== ======================================================
+  Type      Value Action when fetching from mk
+  ========= ===== ======================================================
+  Strings   ''    convert to None
+  Date      0     (seconds since 1970-01-01.00:00:00) convert to None
+  Interval  ''    convert to None
+  Number    0     ambiguious :( - do nothing (see BACKWARDS_COMPATIBLE)
+  Boolean   0     ambiguious :( - do nothing (see BACKWARDS_COMPATABILE)
+  Link      0     convert to None
+  Multilink []    actually, mk can handle this one ;)
+  Password  ''    convert to None
+  ========= ===== ======================================================
+
+  The get/set routines handle these values accordingly by converting
+  to/from None where they can. The Number/Boolean types are not able
+  to handle an "unset" at all, so they default the "unset" to 0.
+- Metakit relies in reference counting to close the database, there is
+  no explicit close call.  This can cause issues if a metakit
+  database is referenced multiple times, one might not actually be
+  closing the db.                                    
+- probably a bunch of stuff that I'm not aware of yet because I haven't
+  fully read through the source. One of these days....
 '''
-   Metakit backend for Roundup, originally by Gordon McMillan.
-
-   Notes by Richard:
-
-   This backend has some behaviour specific to metakit:
-
-    - there's no concept of an explicit "unset" in metakit, so all types
-      have some "unset" value:
-
-      ========= ===== ====================================================
-      Type      Value Action when fetching from mk
-      ========= ===== ====================================================
-      Strings   ''    convert to None
-      Date      0     (seconds since 1970-01-01.00:00:00) convert to None
-      Interval  ''    convert to None
-      Number    0     ambiguious :( - do nothing (see BACKWARDS_COMPATIBLE)
-      Boolean   0     ambiguious :( - do nothing (see BACKWARDS_COMPATABILE)
-      Link      0     convert to None
-      Multilink []    actually, mk can handle this one ;)
-      Password  ''    convert to None
-      ========= ===== ====================================================
-
-      The get/set routines handle these values accordingly by converting
-      to/from None where they can. The Number/Boolean types are not able
-      to handle an "unset" at all, so they default the "unset" to 0.
-
-    Metakit relies in reference counting to close the database, there is
-    no explicit close call.  This can cause issues if a metakit
-    database is referenced multiple times, one might not actually be
-    closing the db.                                    
-    
-    - probably a bunch of stuff that I'm not aware of yet because I haven't
-      fully read through the source. One of these days....
-'''
-# Enable this flag to break backwards compatibility (i.e. can't read old databases)
-#  but comply with more roundup features, like adding NULL support.
+__docformat__ = 'restructuredtext'
+# Enable this flag to break backwards compatibility (i.e. can't read old
+# databases) but comply with more roundup features, like adding NULL support.
 BACKWARDS_COMPATIBLE = True
 
-# Changes to version 1.55:
-# 1 Added an explicit close to the Indexer class.  This was handled
-#   by garbage collection before.
-#
-# 2  Added an MKBackendError exception that gets thrown on some metakit errors.
-#   Should there be a general rdbms exception?
-#      
-# 3 Added a sanity check when creating metakit tables in __getview
-#   There are some test cases that create columns of the same name
-#   with different metakit types.  This can cause crashing issues with
-#   older version of metakit.  We catch these before hand and raise
-#   an exception.
-#
-# 4 metakit db's cannot be weakref'd so this was removed
-#
-# 5 fixed a metakit.append, metakit must append lists, objects or
-#   dictionaries, it can't handle scalars.
-#   sv.append(int(entry))
-#    became
-#   sv.append((int(entry),))
-#
-# 6 To make it easier to compare to the other backends
-#  Class.keyname is changed to Class.key
-#
-# 7 Fixed Class.lookup, sometimes it would claim that a valid
-#  row was not valid (an _isdel row _property of 0 would
-#  be reported as 1) This is because metakit's view.find
-#  operation was returning bad results.  This should be
-#  view.select or view.find on a single property.
-#
-# 8 calling create with no parameters raises a value error
-#  I'm not sure if this is appropriate, but it fixes
-#  a regression test :)
-#
-# 9 The get method was only converting results for commited
-#   values.  uncommited values were not being converted
-#   using the metakit conversion table
-#
-# 10 Added a check to the Class.__init__ to raise a ValueError
-#    if the database already has a class of the same name.
-#
-# 11 Boolean and Number types can now have null values.  This
-#    is a backwards incompatible fix in that old databases
-#    won't work correctly.
-#
-#    The fix is simple.  For a boolean column, 0 is now None
-#                                              1 is False (returns 0)
-#                                              2 is True (returns 1)
-#                        For a numeric column, 0 is now None
-#                                              values 0 get returned as value-1
-#                                              values < 0 get returned as value
-#   Set the BACKWARDS_COMPATIBLE flag to False to enable this fix.
-#
-# 12 Enumerated READ and READWRITE for the getview and getindexedview
-#    These will probably be removed because they are not used
-#
-# Changed to 1.56
-#
-# 13 worked-around a current metakit bug, so retiring properties now
-#    works correctly.
-#    metakit 2.9.2 has a bug when using "find" on ordered views,
-#     using multiple arguments for find doesn't work.
-#
-# Known Current Bugs:
-#    You can't change a class' key properly.
-#    This shouldn't be too hard to fix.
-#
-
 from roundup import hyperdb, date, password, roundupdb, security
 import metakit
 from sessions import Sessions, OneTimeKeys
@@ -940,18 +875,19 @@ class Class(hyperdb.Class):
     def find(self, **propspec):
         """Get the ids of nodes in this class which link to the given nodes.
 
-        'propspec' consists of keyword args propname={nodeid:1,}   
-        'propname' must be the name of a property in this class, or a
-                   KeyError is raised.  That property must be a Link or
-                   Multilink property, or a TypeError is raised.
+        'propspec'
+             consists of keyword args propname={nodeid:1,}   
+        'propname'
+             must be the name of a property in this class, or a
+             KeyError is raised.  That property must be a Link or
+             Multilink property, or a TypeError is raised.
 
         Any node in this class whose propname property links to any of the
         nodeids will be returned. Used by the full text indexing, which knows
         that "foo" occurs in msg1, msg3 and file7; so we have hits on these
-        issues:
+        issues::
 
             db.issue.find(messages={'1':1,'3':1}, files={'7':1})
-
         """
         propspec = propspec.items()
         for propname, nodeid in propspec:
@@ -1249,14 +1185,15 @@ class Class(hyperdb.Class):
         return int(nodeid) < self.maxid
     
     def labelprop(self, default_to_id=0):
-        ''' Return the property name for a label for the given node.
+        '''Return the property name for a label for the given node.
 
         This method attempts to generate a consistent label for the node.
         It tries the following in order:
-            1. key property
-            2. "name" property
-            3. "title" property
-            4. first property from the sorted property name list
+
+        1. key property
+        2. "name" property
+        3. "title" property
+        4. first property from the sorted property name list
         '''
         k = self.getkey()
         if  k:
index fa3c6d4ccb97f50d947083bd5159e05066885105..8d8ea34af8fee75838dc0653f9365d0902db6740 100644 (file)
@@ -5,8 +5,9 @@
 # under the same terms as Python, so long as this copyright message and
 # disclaimer are retained in their original form.
 #
-# Mysql backend for roundup
-#
+
+'''This module defines a backend implementation for MySQL.'''
+__docformat__ = 'restructuredtext'
 
 from roundup.backends.rdbms_common import *
 from roundup.backends import rdbms_common
@@ -208,18 +209,20 @@ class MysqlClass:
     # look for "I can't believe it's not a toy RDBMS" below
     def filter(self, search_matches, filterspec, sort=(None,None),
             group=(None,None)):
-        ''' Return a list of the ids of the active nodes in this class that
-            match the 'filter' spec, sorted by the group spec and then the
-            sort spec
-
-            "filterspec" is {propname: value(s)}
-            "sort" and "group" are (dir, prop) where dir is '+', '-' or None
-                               and prop is a prop name or None
-            "search_matches" is {nodeid: marker}
-
-            The filter must match all properties specificed - but if the
-            property value to match is a list, any one of the values in the
-            list may match for that property to match.
+        '''Return a list of the ids of the active nodes in this class that
+        match the 'filter' spec, sorted by the group spec and then the
+        sort spec
+
+        "filterspec" is {propname: value(s)}
+
+        "sort" and "group" are (dir, prop) where dir is '+', '-' or None
+        and prop is a prop name or None
+
+        "search_matches" is {nodeid: marker}
+
+        The filter must match all properties specificed - but if the
+        property value to match is a list, any one of the values in the
+        list may match for that property to match.
         '''
         # just don't bother if the full-text search matched diddly
         if search_matches == {}:
index 5a28fa7c0010a4906d98cd305c84018f79ada76a..13f2e2f04c1c38c0a0eda7e55b380956772b05ce 100644 (file)
@@ -5,8 +5,9 @@
 # under the same terms as Python, so long as this copyright message and
 # disclaimer are retained in their original form.
 #
-# psycopg backend for roundup
-#
+'''Postgresql backend via psycopg for Roundup.'''
+__docformat__ = 'restructuredtext'
+
 
 from roundup import hyperdb, date
 from roundup.backends import rdbms_common
index 6315fc86ffb7934533a7bd5cef3c0b29a4bf1106..c17235dc75bf2a720b5eaf96b9887c186b0696ff 100644 (file)
@@ -1,7 +1,10 @@
-# $Id: back_sqlite.py,v 1.12 2003-11-12 01:00:58 richard Exp $
-__doc__ = '''
+# $Id: back_sqlite.py,v 1.13 2004-02-11 23:55:09 richard Exp $
+'''Implements a backend for SQLite.
+
 See https://pysqlite.sourceforge.net/ for pysqlite info
 '''
+__docformat__ = 'restructuredtext'
+
 import os, base64, marshal
 
 from roundup import hyperdb
index 1a04aae5b3b41e0e6d8a557f23e083578de8b107..673bd938557ebe1579e2eed45c7f999ad4cea7e1 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: blobfiles.py,v 1.10 2003-12-05 03:28:38 richard Exp $
-'''
-This module exports file storage for roundup backends.
+#$Id: blobfiles.py,v 1.11 2004-02-11 23:55:09 richard Exp $
+'''This module exports file storage for roundup backends.
 Files are stored into a directory hierarchy.
 '''
+__docformat__ = 'restructuredtext'
 
 import os
 
index 36833d0e1a2914d7ab7e29abe1be91b509b83b2b..4fe955f2e169031ec7cb439f3bd70cea36af6169 100644 (file)
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 # SOFTWARE.
 
-# $Id: locking.py,v 1.7 2003-07-03 23:43:46 richard Exp $
+# $Id: locking.py,v 1.8 2004-02-11 23:55:09 richard Exp $
 
 '''This module provides a generic interface to acquire and release
 exclusive access to a file.
 
 It should work on Unix and Windows.
 '''
+__docformat__ = 'restructuredtext'
 
 import portalocker
 
index 9c8389e7a87bfd37231d0d99ba62117a5c68ad97..538529baa268f390e5a77d598519cfcb046264fa 100644 (file)
@@ -2,11 +2,11 @@
 #                  Requires python 1.5.2 or better.
 
 # ID line added by richard for Roundup file tracking
-# $Id: portalocker.py,v 1.7 2003-08-26 00:29:20 richard Exp $
+# $Id: portalocker.py,v 1.8 2004-02-11 23:55:09 richard Exp $
 
-""" Cross-platform (posix/nt) API for flock-style file locking.
+"""Cross-platform (posix/nt) API for flock-style file locking.
 
-Synopsis:
+Synopsis::
 
    import portalocker
    file = open("somefile", "r+")
@@ -15,18 +15,18 @@ Synopsis:
    file.write("foo")
    file.close()
 
-If you know what you're doing, you may choose to
+If you know what you're doing, you may choose to::
 
    portalocker.unlock(file)
 
 before closing the file, but why?
 
-Methods:
+Methods::
 
    lock( file, flags )
    unlock( file )
 
-Constants:
+Constants::
 
    LOCK_EX
    LOCK_SH
@@ -36,10 +36,12 @@ I learned the win32 technique for locking files from sample code
 provided by John Nielsen <nielsenjf@my-deja.com> in the documentation
 that accompanies the win32 modules.
 
-Author: Jonathan Feinberg <jdf@pobox.com>
-Version: Id: portalocker.py,v 1.3 2001/05/29 18:47:55 Administrator Exp 
-         **un-cvsified by richard so the version doesn't change**
+:Author: Jonathan Feinberg <jdf@pobox.com>
+:Version: Id: portalocker.py,v 1.3 2001/05/29 18:47:55 Administrator Exp 
+          **un-cvsified by richard so the version doesn't change**
 """
+__docformat__ = 'restructuredtext'
+
 import os
 
 if os.name == 'nt':
index aebd2594fcde4a48d6f10051b35eae18346d73e4..e7d141c64c516dbfb1b49cb5c05b374140bdbf57 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: rdbms_common.py,v 1.74 2004-01-20 05:55:51 richard Exp $
+# $Id: rdbms_common.py,v 1.75 2004-02-11 23:55:09 richard Exp $
 ''' Relational database (SQL) backend common code.
 
 Basics:
@@ -20,6 +20,7 @@ probably a bit of work to be done if a database is used that actually
 honors column typing, since the initial databases don't (sqlite stores
 everything as a string.)
 '''
+__docformat__ = 'restructuredtext'
 
 # standard python modules
 import sys, os, time, re, errno, weakref, copy
@@ -490,10 +491,10 @@ class Database(FileStorage, hyperdb.Database, roundupdb.Database):
             raise KeyError, 'There is no class called "%s"'%classname
 
     def clear(self):
-        ''' Delete all database contents.
+        '''Delete all database contents.
 
-            Note: I don't commit here, which is different behaviour to the
-            "nuke from orbit" behaviour in the *dbms.
+        Note: I don't commit here, which is different behaviour to the
+              "nuke from orbit" behaviour in the dbs.
         '''
         if __debug__:
             print >>hyperdb.DEBUG, 'clear', (self,)
@@ -1649,8 +1650,11 @@ class Class(hyperdb.Class):
         WARNING: this method should never be used except in extremely rare
                  situations where there could never be links to the node being
                  deleted
+
         WARNING: use retire() instead
+
         WARNING: the properties of this node will not be available ever again
+
         WARNING: really, use retire() instead
 
         Well, I think that's enough warnings. This method exists mostly to
@@ -1706,14 +1710,15 @@ class Class(hyperdb.Class):
         return self.key
 
     def labelprop(self, default_to_id=0):
-        ''' Return the property name for a label for the given node.
+        '''Return the property name for a label for the given node.
 
         This method attempts to generate a consistent label for the node.
         It tries the following in order:
-            1. key property
-            2. "name" property
-            3. "title" property
-            4. first property from the sorted property name list
+
+        1. key property
+        2. "name" property
+        3. "title" property
+        4. first property from the sorted property name list
         '''
         k = self.getkey()
         if  k:
@@ -1897,18 +1902,20 @@ class Class(hyperdb.Class):
 
     def filter(self, search_matches, filterspec, sort=(None,None),
             group=(None,None)):
-        ''' Return a list of the ids of the active nodes in this class that
-            match the 'filter' spec, sorted by the group spec and then the
-            sort spec
-
-            "filterspec" is {propname: value(s)}
-            "sort" and "group" are (dir, prop) where dir is '+', '-' or None
-                               and prop is a prop name or None
-            "search_matches" is {nodeid: marker}
-
-            The filter must match all properties specificed - but if the
-            property value to match is a list, any one of the values in the
-            list may match for that property to match.
+        '''Return a list of the ids of the active nodes in this class that
+        match the 'filter' spec, sorted by the group spec and then the
+        sort spec
+
+        "filterspec" is {propname: value(s)}
+
+        "sort" and "group" are (dir, prop) where dir is '+', '-' or None
+        and prop is a prop name or None
+
+        "search_matches" is {nodeid: marker}
+
+        The filter must match all properties specificed - but if the
+        property value to match is a list, any one of the values in the
+        list may match for that property to match.
         '''
         # just don't bother if the full-text search matched diddly
         if search_matches == {}:
index 99b4655312cc4369b9fb3a4bb2a2010fafab4e47..addeb903a1d9ba7085707aef42451da304ea8469 100644 (file)
@@ -1,12 +1,11 @@
-#$Id: sessions.py,v 1.6 2003-09-05 21:05:18 jlgijsbers Exp $
-"""
-This module defines a very basic store that's used by the CGI interface
+#$Id: sessions.py,v 1.7 2004-02-11 23:55:09 richard Exp $
+"""This module defines a very basic store that's used by the CGI interface
 to store session and one-time-key information.
 
 Yes, it's called "sessions" - because originally it only defined a session
 class. It's now also used for One Time Key handling too.
-
 """
+__docformat__ = 'restructuredtext'
 
 import anydbm, whichdb, os, marshal
 
index 8a391b6df09fbd000e2c03ee434c25e48b47c189..ba315d3319aa8e4defb847e1aca78a94e04089f5 100644 (file)
@@ -24,8 +24,9 @@ Modified for Roundup 0.5 release:
 - Made traceback info more informative
 
 """
+__docformat__ = 'restructuredtext'
 
-__version__='$Revision: 1.8 $'[11:-2]
+__version__='$Revision: 1.9 $'[11:-2]
 
 import re, sys
 from TALES import Engine, CompilerError, _valid_name, NAME_RE, \
index 91d66d76297d14c794c62b34ed635cd8125015d2..ddb097ca2b87435c7eb66b46e9911cfb3d46ada7 100755 (executable)
@@ -20,8 +20,9 @@ Modified for Roundup 0.5 release:
 - changed imports to import from roundup.cgi
 
 """
+__docformat__ = 'restructuredtext'
 
-__version__='$Revision: 1.3 $'[11:-2]
+__version__='$Revision: 1.4 $'[11:-2]
 
 import sys
 
index ded1d29ef46fe2f5f5d976b391ae682aca21d429..4e6bd76d0a20983118d3ab701377009ce5ba9948 100644 (file)
@@ -16,8 +16,9 @@
 A TALES Iterator with the ability to use first() and last() on
 subpaths of elements.
 """
+__docformat__ = 'restructuredtext'
 
-__version__='$Revision: 1.1 $'[11:-2]
+__version__='$Revision: 1.2 $'[11:-2]
 
 import TALES
 from Expressions import restrictedTraverse, Undefs, getSecurityManager
index 0bfe40034b35e3525a70bf8c4084bb54d8b79560..44a0491f8ddf82bea39cbed87b7dcfa3f992c456 100644 (file)
@@ -18,8 +18,9 @@ Modified for Roundup 0.5 release:
 - more informative traceback info
 
 """
+__docformat__ = 'restructuredtext'
 
-__version__='$Revision: 1.4 $'[11:-2]
+__version__='$Revision: 1.5 $'[11:-2]
 
 from TALES import CompilerError
 from string import strip, split, join, replace, lstrip
index ef1343663370d77eea8fe4e6c8c67659bd432635..ac8aec9e638160a6c2bc998c4775b8a997f3e5f8 100644 (file)
@@ -18,8 +18,9 @@ Modified for Roundup 0.5 release:
 
 - changed imports to import from roundup.cgi
 """
+__docformat__ = 'restructuredtext'
 
-__version__='$Revision: 1.5 $'[11:-2]
+__version__='$Revision: 1.6 $'[11:-2]
 
 import re, sys
 from roundup.cgi import ZTUtils
index 3d58de06ee667eed3e519feb92e5d1f03539e597..c0677c9677d217958dc0c2daa19e5baf30e37a6e 100644 (file)
@@ -15,7 +15,8 @@ __doc__='''Package wrapper for Page Templates
 This wrapper allows the Page Template modules to be segregated in a
 separate package.
 
-$Id: __init__.py,v 1.1 2002-09-05 00:37:09 richard Exp $'''
+$Id: __init__.py,v 1.2 2004-02-11 23:55:09 richard Exp $'''
+__docformat__ = 'restructuredtext'
 __version__='$$'[11:-2]
 
 
index 5ab076baa18ea3fd38c6f1bbe7b241476728c5ca..e8ae444ed0e98098f56db3c41b963f03e2a400e9 100644 (file)
@@ -1,4 +1,5 @@
 """A parser for HTML and XHTML."""
+__docformat__ = 'restructuredtext'
 
 # This file is based on sgmllib.py, but the API is slightly different.
 
index 8d7f0db2cfdc00f3bb9f539f1ec622b2da3e7ea3..f1582f2f39cb46b12bedc1c3ca4e521f67a93b54 100644 (file)
@@ -11,9 +11,9 @@
 # FOR A PARTICULAR PURPOSE
 # 
 ##############################################################################
+"""Parse HTML and compile to TALInterpreter intermediate code.
 """
-Parse HTML and compile to TALInterpreter intermediate code.
-"""
+__docformat__ = 'restructuredtext'
 
 import sys
 import string
index dbc0443f90720f0eac11f9f01621264a720ee33b..f49622fe6b0e9a742a33bb7854829e32c4f4d1c5 100644 (file)
@@ -11,9 +11,9 @@
 # FOR A PARTICULAR PURPOSE
 # 
 ##############################################################################
+"""Common definitions used by TAL and METAL compilation an transformation.
 """
-Common definitions used by TAL and METAL compilation an transformation.
-"""
+__docformat__ = 'restructuredtext'
 
 from types import ListType, TupleType
 
index 53172554eb55383d9ded870b313f411da35074d8..8a4f55becd251344e3506f06c03d16a7ebca47c1 100644 (file)
@@ -11,9 +11,9 @@
 # FOR A PARTICULAR PURPOSE
 # 
 ##############################################################################
+"""Code generator for TALInterpreter intermediate code.
 """
-Code generator for TALInterpreter intermediate code.
-"""
+__docformat__ = 'restructuredtext'
 
 import string
 import re
index 341b8612b378899ed47a02ad34662eb7ff8b1a7a..5f9c67fa78f134121ae958bc6d3c82a58810821f 100644 (file)
@@ -11,9 +11,9 @@
 # FOR A PARTICULAR PURPOSE
 # 
 ##############################################################################
+"""Interpreter for a pre-compiled TAL program.
 """
-Interpreter for a pre-compiled TAL program.
-"""
+__docformat__ = 'restructuredtext'
 
 import sys
 import getopt
index f75414e594563e3277b23b9cd9d4c8dc653c55bc..c0c0b9f16524f93da3dad7705393a4d38cf66b39 100644 (file)
@@ -11,9 +11,9 @@
 # FOR A PARTICULAR PURPOSE
 # 
 ##############################################################################
+"""Parse XML and compile to TALInterpreter intermediate code.
 """
-Parse XML and compile to TALInterpreter intermediate code.
-"""
+__docformat__ = 'restructuredtext'
 
 import string
 from XMLParser import XMLParser
index e16869de1629ea8d25c1a32cb5b9a32a4d648910..00ffdc87d37748027c44ac8a0a4ff6fe95734252 100644 (file)
 # FOR A PARTICULAR PURPOSE
 # 
 ##############################################################################
-"""
-Generic expat-based XML parser base class.
+"""Generic expat-based XML parser base class.
 
 Modified for Roundup 0.5 release:
 
 - removed dependency on zLOG
 
 """
+__docformat__ = 'restructuredtext'
 
 class XMLParser:
 
index 080ed5d63dfe8faadc2eaf5f4dbee5ff15da67b7..4f2a609e46e60e615382bfd22e16b32051e21b9c 100644 (file)
@@ -11,4 +11,5 @@
 # FOR A PARTICULAR PURPOSE
 # 
 ##############################################################################
-""" Template Attribute Language package """
+"""Template Attribute Language package """
+__docformat__ = 'restructuredtext'
index eab134c32ec897920e5affc687274a6f6014d9ab..2bcf6a7bbd1fb3adc4cbb943df4ce1ccdffed290 100644 (file)
@@ -1,4 +1,6 @@
-"""Shared support for scanning document type declarations in HTML and XHTML."""
+"""Shared support for scanning document type declarations in HTML and XHTML.
+"""
+__docformat__ = 'restructuredtext'
 
 import re
 import string
index 3dfa9b1a1bd4d1709d683513a1d91ac0659deb2e..66dde6861ac3bd3a0606ce9d586bec39fa3ef1e1 100644 (file)
@@ -12,8 +12,9 @@
 ##############################################################################
 __doc__='''Batch class, for iterating over a sequence in batches
 
-$Id: Batch.py,v 1.2 2002-09-11 23:54:26 richard Exp $'''
-__version__='$Revision: 1.2 $'[11:-2]
+$Id: Batch.py,v 1.3 2004-02-11 23:55:09 richard Exp $'''
+__docformat__ = 'restructuredtext'
+__version__='$Revision: 1.3 $'[11:-2]
 
 class LazyPrevBatch:
     def __of__(self, parent):
index b6c7a6fe441050b227e7dc1152ea5c9067830e80..96a64ba31caab501ac6b39f53f09c759dd100064 100644 (file)
@@ -18,8 +18,9 @@ The Iterator() function accepts either a sequence or a Python
 iterator.  The next() method fetches the next item, and returns
 true if it succeeds.
 
-$Id: Iterator.py,v 1.2 2002-09-26 21:54:17 richard Exp $'''
-__version__='$Revision: 1.2 $'[11:-2]
+$Id: Iterator.py,v 1.3 2004-02-11 23:55:09 richard Exp $'''
+__docformat__ = 'restructuredtext'
+__version__='$Revision: 1.3 $'[11:-2]
 
 import string
 
index 6ee1ca4a1c5c49810a96fdc80e8e3279fae86521..64737330e239fe6433b6dcf3cff78794e8b7c0b1 100644 (file)
@@ -16,8 +16,9 @@ Modified for Roundup 0.5 release:
 
 - removed Zope imports
 
-$Id: __init__.py,v 1.2 2002-09-07 22:42:47 richard Exp $'''
-__version__='$Revision: 1.2 $'[11:-2]
+$Id: __init__.py,v 1.3 2004-02-11 23:55:09 richard Exp $'''
+__docformat__ = 'restructuredtext'
+__version__='$Revision: 1.3 $'[11:-2]
 
 from Batch import Batch
 from Iterator import Iterator
index bfcbcfcf8895c108176972d5338f48f1a1fb31fd..87081fed54ff460dabc39056e3078161bd2d6cb2 100644 (file)
@@ -1 +1,2 @@
-' CGI interface modules '
+''' CGI interface modules '''
+__docformat__ = 'restructuredtext'
index 7435eea40ed5a1acdb3ebff78eb343dcb58436ea..a78188a4f11d86c514c7aed90e06345708bdd96a 100644 (file)
@@ -1,11 +1,11 @@
 #
 # This module was written by Ka-Ping Yee, <ping@lfw.org>.
 # 
-# $Id: cgitb.py,v 1.9 2003-12-05 03:36:34 richard Exp $
+# $Id: cgitb.py,v 1.10 2004-02-11 23:55:09 richard Exp $
 
-__doc__ = """
-Extended CGI traceback handler by Ka-Ping Yee, <ping@lfw.org>.
+"""Extended CGI traceback handler by Ka-Ping Yee, <ping@lfw.org>.
 """
+__docformat__ = 'restructuredtext'
 
 import sys, os, types, string, keyword, linecache, tokenize, inspect, cgi
 import pydoc, traceback
index ace158e16abd92625c7a77f817ebb7987e8a11ef..f02e62f7d531a282345171d884fda739a9372f39 100644 (file)
@@ -1,8 +1,8 @@
-# $Id: client.py,v 1.155 2004-02-11 21:34:31 jlgijsbers Exp $
+# $Id: client.py,v 1.156 2004-02-11 23:55:09 richard Exp $
 
-__doc__ = """
-WWW request handler (also used in the stand-alone server).
+"""WWW request handler (also used in the stand-alone server).
 """
+__docformat__ = 'restructuredtext'
 
 import os, os.path, cgi, StringIO, urlparse, re, traceback, mimetypes, urllib
 import binascii, Cookie, time, random, stat, rfc822
@@ -16,10 +16,10 @@ from roundup.cgi.form_parser import FormParser
 from roundup.mailer import Mailer, MessageSendError
 
 def initialiseSecurity(security):
-    ''' Create some Permissions and Roles on the security object
+    '''Create some Permissions and Roles on the security object
 
-        This function is directly invoked by security.Security.__init__()
-        as a part of the Security object instantiation.
+    This function is directly invoked by security.Security.__init__()
+    as a part of the Security object instantiation.
     '''
     security.addPermission(name="Web Registration",
         description="User may register through the web")
@@ -46,28 +46,30 @@ def clean_message_callback(match, ok={'a':1,'i':1,'b':1,'br':1}):
     return '&lt;%s&gt;'%match.group(2)
 
 class Client:
-    ''' Instantiate to handle one CGI request.
+    '''Instantiate to handle one CGI request.
 
     See inner_main for request processing.
 
     Client attributes at instantiation:
-        "path" is the PATH_INFO inside the instance (with no leading '/')
-        "base" is the base URL for the instance
-        "form" is the cgi form, an instance of FieldStorage from the standard
-               cgi module
-        "additional_headers" is a dictionary of additional HTTP headers that
-               should be sent to the client
-        "response_code" is the HTTP response code to send to the client
+
+    - "path" is the PATH_INFO inside the instance (with no leading '/')
+    - "base" is the base URL for the instance
+    - "form" is the cgi form, an instance of FieldStorage from the standard
+      cgi module
+    - "additional_headers" is a dictionary of additional HTTP headers that
+      should be sent to the client
+    - "response_code" is the HTTP response code to send to the client
 
     During the processing of a request, the following attributes are used:
-        "error_message" holds a list of error messages
-        "ok_message" holds a list of OK messages
-        "session" is the current user session id
-        "user" is the current user's name
-        "userid" is the current user's id
-        "template" is the current :template context
-        "classname" is the current class context name
-        "nodeid" is the current context item id
+
+    - "error_message" holds a list of error messages
+    - "ok_message" holds a list of OK messages
+    - "session" is the current user session id
+    - "user" is the current user's name
+    - "userid" is the current user's id
+    - "template" is the current :template context
+    - "classname" is the current class context name
+    - "nodeid" is the current context item id
 
     User Identification:
      If the user has no login cookie, then they are anonymous and are logged
@@ -77,7 +79,6 @@ class Client:
      Once a user logs in, they are assigned a session. The Client instance
      keeps the nodeid of the session as the "session" attribute.
 
-
     Special form variables:
      Note that in various places throughout this code, special form
      variables of the form :<name> are used. The colon (":") part may
@@ -146,32 +147,34 @@ class Client:
                 self.db.close()
 
     def inner_main(self):
-        ''' Process a request.
-
-            The most common requests are handled like so:
-            1. figure out who we are, defaulting to the "anonymous" user
-               see determine_user
-            2. figure out what the request is for - the context
-               see determine_context
-            3. handle any requested action (item edit, search, ...)
-               see handle_action
-            4. render a template, resulting in HTML output
-
-            In some situations, exceptions occur:
-            - HTTP Redirect  (generally raised by an action)
-            - SendFile       (generally raised by determine_context)
-              serve up a FileClass "content" property
-            - SendStaticFile (generally raised by determine_context)
-              serve up a file from the tracker "html" directory
-            - Unauthorised   (generally raised by an action)
-              the action is cancelled, the request is rendered and an error
-              message is displayed indicating that permission was not
-              granted for the action to take place
-            - templating.Unauthorised   (templating action not permitted)
-              raised by an attempted rendering of a template when the user
-              doesn't have permission
-            - NotFound       (raised wherever it needs to be)
-              percolates up to the CGI interface that called the client
+        '''Process a request.
+
+        The most common requests are handled like so:
+
+        1. figure out who we are, defaulting to the "anonymous" user
+           see determine_user
+        2. figure out what the request is for - the context
+           see determine_context
+        3. handle any requested action (item edit, search, ...)
+           see handle_action
+        4. render a template, resulting in HTML output
+
+        In some situations, exceptions occur:
+
+        - HTTP Redirect  (generally raised by an action)
+        - SendFile       (generally raised by determine_context)
+          serve up a FileClass "content" property
+        - SendStaticFile (generally raised by determine_context)
+          serve up a file from the tracker "html" directory
+        - Unauthorised   (generally raised by an action)
+          the action is cancelled, the request is rendered and an error
+          message is displayed indicating that permission was not
+          granted for the action to take place
+        - templating.Unauthorised   (templating action not permitted)
+          raised by an attempted rendering of a template when the user
+          doesn't have permission
+        - NotFound       (raised wherever it needs to be)
+          percolates up to the CGI interface that called the client
         '''
         self.ok_message = []
         self.error_message = []
@@ -262,22 +265,25 @@ class Client:
             sessions.set('last_clean', last_use=time.time())
 
     def determine_user(self):
-        '''Determine who the user is.
+        ''' Determine who the user is
         '''
-        # open the database as admin
+        # determine the uid to use
         self.opendb('admin')
 
-        # clean age sessions
-        self.clean_sessions()
-
         # make sure we have the session Class
+        self.clean_sessions()
         sessions = self.db.sessions
 
-        # look up the user session cookie
-        cookie = Cookie.SimpleCookie(self.env.get('HTTP_COOKIE', ''))
-        user = 'anonymous'
+        # first up, try the REMOTE_USER var (from HTTP Basic Auth handled
+        # by a front-end HTTP server)
+        try:
+            user = os.getenv('REMOTE_USER')
+        except KeyError:
+            pass
 
-        # bump the "revision" of the cookie since the format changed
+        # look up the user session cookie (may override the REMOTE_USER)
+        cookie = Cookie.Cookie(self.env.get('HTTP_COOKIE', ''))
+        user = 'anonymous'
         if (cookie.has_key(self.cookie_name) and
                 cookie[self.cookie_name].value != 'deleted'):
 
@@ -290,7 +296,8 @@ class Client:
                 sessions.commit()
                 user = sessions.get(self.session, 'user')
             except KeyError:
-                user = 'anonymous'
+                # not valid, ignore id
+                pass
 
         # sanity check on the user still being valid, getting the userid
         # at the same time
@@ -309,40 +316,43 @@ class Client:
         self.opendb(self.user)
 
     def determine_context(self, dre=re.compile(r'([^\d]+)(\d+)')):
-        """ Determine the context of this page from the URL:
-
-            The URL path after the instance identifier is examined. The path
-            is generally only one entry long.
-
-            - if there is no path, then we are in the "home" context.
-            * if the path is "_file", then the additional path entry
-              specifies the filename of a static file we're to serve up
-              from the instance "html" directory. Raises a SendStaticFile
-              exception.
-            - if there is something in the path (eg "issue"), it identifies
-              the tracker class we're to display.
-            - if the path is an item designator (eg "issue123"), then we're
-              to display a specific item.
-            * if the path starts with an item designator and is longer than
-              one entry, then we're assumed to be handling an item of a
-              FileClass, and the extra path information gives the filename
-              that the client is going to label the download with (ie
-              "file123/image.png" is nicer to download than "file123"). This
-              raises a SendFile exception.
-
-            Both of the "*" types of contexts stop before we bother to
-            determine the template we're going to use. That's because they
-            don't actually use templates.
-
-            The template used is specified by the :template CGI variable,
-            which defaults to:
-
-             only classname suplied:          "index"
-             full item designator supplied:   "item"
-
-            We set:
+        """Determine the context of this page from the URL:
+
+        The URL path after the instance identifier is examined. The path
+        is generally only one entry long.
+
+        - if there is no path, then we are in the "home" context.
+        - if the path is "_file", then the additional path entry
+          specifies the filename of a static file we're to serve up
+          from the instance "html" directory. Raises a SendStaticFile
+          exception.(*)
+        - if there is something in the path (eg "issue"), it identifies
+          the tracker class we're to display.
+        - if the path is an item designator (eg "issue123"), then we're
+          to display a specific item.
+        - if the path starts with an item designator and is longer than
+          one entry, then we're assumed to be handling an item of a
+          FileClass, and the extra path information gives the filename
+          that the client is going to label the download with (ie
+          "file123/image.png" is nicer to download than "file123"). This
+          raises a SendFile exception.(*)
+
+        Both of the "*" types of contexts stop before we bother to
+        determine the template we're going to use. That's because they
+        don't actually use templates.
+
+        The template used is specified by the :template CGI variable,
+        which defaults to:
+
+        - only classname suplied:          "index"
+        - full item designator supplied:   "item"
+
+        We set:
+
              self.classname  - the class to display, can be None
+
              self.template   - the template to render the current context with
+
              self.nodeid     - the nodeid of the class we're displaying
         """
         # default the optional variables
index 1305cd946d1dfab2823ac21b974769e3ac23bec4..aab6a95fb5ac30883d44bb54689a3d0eddeeee42 100644 (file)
@@ -1,3 +1,7 @@
+"""Implements the API used in the HTML templating for the web interface.
+"""
+__docformat__ = 'restructuredtext'
+
 from __future__ import nested_scopes
 
 import sys, cgi, urllib, os, re, os.path, time, errno, mimetypes
@@ -143,35 +147,37 @@ class Templates:
             raise KeyError, message
 
 class RoundupPageTemplate(PageTemplate.PageTemplate):
-    ''' A Roundup-specific PageTemplate.
-
-        Interrogate the client to set up the various template variables to
-        be available:
-
-        *context*
-         this is one of three things:
-         1. None - we're viewing a "home" page
-         2. The current class of item being displayed. This is an HTMLClass
-            instance.
-         3. The current item from the database, if we're viewing a specific
-            item, as an HTMLItem instance.
-        *request*
-          Includes information about the current request, including:
-           - the url
-           - the current index information (``filterspec``, ``filter`` args,
-             ``properties``, etc) parsed out of the form. 
-           - methods for easy filterspec link generation
-           - *user*, the current user node as an HTMLItem instance
-           - *form*, the current CGI form information as a FieldStorage
-        *config*
-          The current tracker config.
-        *db*
-          The current database, used to access arbitrary database items.
-        *utils*
-          This is a special class that has its base in the TemplatingUtils
-          class in this file. If the tracker interfaces module defines a
-          TemplatingUtils class then it is mixed in, overriding the methods
-          in the base class.
+    '''A Roundup-specific PageTemplate.
+
+    Interrogate the client to set up the various template variables to
+    be available:
+
+    *context*
+     this is one of three things:
+
+     1. None - we're viewing a "home" page
+     2. The current class of item being displayed. This is an HTMLClass
+        instance.
+     3. The current item from the database, if we're viewing a specific
+        item, as an HTMLItem instance.
+    *request*
+      Includes information about the current request, including:
+
+       - the url
+       - the current index information (``filterspec``, ``filter`` args,
+         ``properties``, etc) parsed out of the form. 
+       - methods for easy filterspec link generation
+       - *user*, the current user node as an HTMLItem instance
+       - *form*, the current CGI form information as a FieldStorage
+    *config*
+      The current tracker config.
+    *db*
+      The current database, used to access arbitrary database items.
+    *utils*
+      This is a special class that has its base in the TemplatingUtils
+      class in this file. If the tracker interfaces module defines a
+      TemplatingUtils class then it is mixed in, overriding the methods
+      in the base class.
     '''
     def getContext(self, client, classname, request):
         # construct the TemplatingUtils class
@@ -962,11 +968,11 @@ class StringHTMLProperty(HTMLProperty):
         return self.plain(hyperlink=1)
 
     def plain(self, escape=0, hyperlink=0):
-        ''' Render a "plain" representation of the property
+        '''Render a "plain" representation of the property
             
-            "escape" turns on/off HTML quoting
-            "hyperlink" turns on/off in-text hyperlinking of URLs, email
-                addresses and designators
+        - "escape" turns on/off HTML quoting
+        - "hyperlink" turns on/off in-text hyperlinking of URLs, email
+          addresses and designators
         '''
         self.view_check()
 
@@ -1441,7 +1447,7 @@ class MultilinkHTMLProperty(HTMLProperty):
 
     def __contains__(self, value):
         ''' Support the "in" operator. We have to make sure the passed-in
-            value is a string first, not a *HTMLProperty.
+            value is a string first, not a HTMLProperty.
         '''
         return str(value) in self._value
 
@@ -1601,25 +1607,25 @@ class ShowDict:
         return self.columns.has_key(name)
 
 class HTMLRequest(HTMLInputMixin):
-    ''' The *request*, holding the CGI form and environment.
-
-        "form" the CGI form as a cgi.FieldStorage
-        "env" the CGI environment variables
-        "base" the base URL for this instance
-        "user" a HTMLUser instance for this user
-        "classname" the current classname (possibly None)
-        "template" the current template (suffix, also possibly None)
-
-        Index args:
-        "columns" dictionary of the columns to display in an index page
-        "show" a convenience access to columns - request/show/colname will
-               be true if the columns should be displayed, false otherwise
-        "sort" index sort column (direction, column name)
-        "group" index grouping property (direction, column name)
-        "filter" properties to filter the index on
-        "filterspec" values to filter the index on
-        "search_text" text to perform a full-text search on for an index
-
+    '''The *request*, holding the CGI form and environment.
+
+    - "form" the CGI form as a cgi.FieldStorage
+    - "env" the CGI environment variables
+    - "base" the base URL for this instance
+    - "user" a HTMLUser instance for this user
+    - "classname" the current classname (possibly None)
+    - "template" the current template (suffix, also possibly None)
+
+    Index args:
+
+    - "columns" dictionary of the columns to display in an index page
+    - "show" a convenience access to columns - request/show/colname will
+      be true if the columns should be displayed, false otherwise
+    - "sort" index sort column (direction, column name)
+    - "group" index grouping property (direction, column name)
+    - "filter" properties to filter the index on
+    - "filterspec" values to filter the index on
+    - "search_text" text to perform a full-text search on for an index
     '''
     def __init__(self, client):
         # _client is needed by HTMLInputMixin
index 49151768aedaf563b78e76c689702609803b671d..8f60a725e7eddfb56e73bea99a234b59931f6eda 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: date.py,v 1.59 2003-12-05 03:28:38 richard Exp $
+# $Id: date.py,v 1.60 2004-02-11 23:55:08 richard Exp $
 
-__doc__ = """
-Date, time and time interval handling.
+"""Date, time and time interval handling.
 """
+__docformat__ = 'restructuredtext'
 
 import time, re, calendar, types
 from i18n import _
@@ -51,6 +51,7 @@ class Date:
     care of these conversions. In the following examples, suppose that yyyy
     is the current year, mm is the current month, and dd is the current day
     of the month; and suppose that the user is on Eastern Standard Time.
+    Examples::
 
       "2000-04-17" means <Date 2000-04-17.00:00:00>
       "01-25" means <Date yyyy-01-25.00:00:00>
@@ -69,9 +70,8 @@ class Date:
     separately. For example, when evaluating "2000-06-25 + 1m 10d", we
     first add one month to get 2000-07-25, then add 10 days to get
     2000-08-04 (rather than trying to decide whether 1m 10d means 38 or 40
-    or 41 days).
+    or 41 days).  Example usage::
 
-    Example usage:
         >>> Date(".")
         <Date 2000-06-26.00:34:02>
         >>> _.local(-5)
@@ -95,9 +95,11 @@ class Date:
     def __init__(self, spec='.', offset=0, add_granularity=0):
         """Construct a date given a specification and a time zone offset.
 
-          'spec' is a full date or a partial form, with an optional
-                 added or subtracted interval. Or a date 9-tuple.
-        'offset' is the local time zone offset from GMT in hours.
+        'spec'
+           is a full date or a partial form, with an optional added or
+           subtracted interval. Or a date 9-tuple.
+        'offset'
+           is the local time zone offset from GMT in hours.
         """
         if type(spec) == type(''):
             self.set(spec, offset=offset, add_granularity=add_granularity)
@@ -660,20 +662,24 @@ def fixTimeOverflow(time):
     return (sign, y, m, d, H, M, S)
 
 class Range:
-    """
-    Represents range between two values
+    """Represents range between two values
     Ranges can be created using one of theese two alternative syntaxes:
         
-        1. Native english syntax: 
+    1. Native english syntax::
+
             [[From] <value>][ To <value>]
-           Keywords "From" and "To" are case insensitive. Keyword "From" is optional.
 
-        2. "Geek" syntax:
-            [<value>][; <value>]
+       Keywords "From" and "To" are case insensitive. Keyword "From" is
+       optional.
+
+    2. "Geek" syntax::
+
+          [<value>][; <value>]
 
     Either first or second <value> can be omitted in both syntaxes.
 
-    Examples (consider local time is Sat Mar  8 22:07:48 EET 2003):
+    Examples (consider local time is Sat Mar  8 22:07:48 EET 2003)::
+
         >>> Range("from 2-12 to 4-2")
         <Range from 2003-02-12.00:00:00 to 2003-04-02.00:00:00>
         
index c8ca0a57ff593596bf02f5b1e125f3e93e8ab15f..4bac87fc63039f2f258e2a26737990063e101f3b 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: hyperdb.py,v 1.95 2003-11-16 22:56:46 jlgijsbers Exp $
+# $Id: hyperdb.py,v 1.96 2004-02-11 23:55:08 richard Exp $
 
+"""Hyperdatabase implementation, especially field types.
 """
-Hyperdatabase implementation, especially field types.
-"""
+__docformat__ = 'restructuredtext'
 
 # standard python modules
 import sys, os, time, re
@@ -250,19 +250,19 @@ All methods except __repr__ must be implemented by a concrete backend Database.
         '''
         return node
 
-    def getnode(self, classname, nodeid, db=None, cache=1):
+    def getnode(self, classname, nodeid):
         '''Get a node from the database.
 
         'cache' exists for backwards compatibility, and is not used.
         '''
         raise NotImplementedError
 
-    def hasnode(self, classname, nodeid, db=None):
+    def hasnode(self, classname, nodeid):
         '''Determine if the database has a given node.
         '''
         raise NotImplementedError
 
-    def countnodes(self, classname, db=None):
+    def countnodes(self, classname):
         '''Count the number of nodes that exist for a particular Class.
         '''
         raise NotImplementedError
@@ -374,7 +374,7 @@ class Class:
         raise NotImplementedError
 
     # not in spec
-    def getnode(self, nodeid, cache=1):
+    def getnode(self, nodeid):
         ''' Return a convenience wrapper for the node.
 
         'nodeid' must be the id of an existing node of this class or an
@@ -384,7 +384,7 @@ class Class:
         '''
         return Node(self, nodeid)
 
-    def getnodeids(self, db=None):
+    def getnodeids(self, retired=None):
         '''Retrieve all the ids of the nodes for a particular Class.
         '''
         raise NotImplementedError
@@ -438,8 +438,11 @@ class Class:
         WARNING: this method should never be used except in extremely rare
                  situations where there could never be links to the node being
                  deleted
+
         WARNING: use retire() instead
+
         WARNING: the properties of this node will not be available ever again
+
         WARNING: really, use retire() instead
 
         Well, I think that's enough warnings. This method exists mostly to
@@ -485,15 +488,16 @@ class Class:
         raise NotImplementedError
 
     def labelprop(self, default_to_id=0):
-        ''' Return the property name for a label for the given node.
+        """Return the property name for a label for the given node.
 
         This method attempts to generate a consistent label for the node.
         It tries the following in order:
-            1. key property
-            2. "name" property
-            3. "title" property
-            4. first property from the sorted property name list
-        '''
+
+        1. key property
+        2. "name" property
+        3. "title" property
+        4. first property from the sorted property name list
+        """
         raise NotImplementedError
 
     def lookup(self, keyvalue):
@@ -525,19 +529,21 @@ class Class:
 
     def filter(self, search_matches, filterspec, sort=(None,None),
             group=(None,None)):
-        ''' Return a list of the ids of the active nodes in this class that
-            match the 'filter' spec, sorted by the group spec and then the
-            sort spec.
-
-            "filterspec" is {propname: value(s)}
-            "sort" and "group" are (dir, prop) where dir is '+', '-' or None
-                               and prop is a prop name or None
-            "search_matches" is {nodeid: marker}
-
-            The filter must match all properties specificed - but if the
-            property value to match is a list, any one of the values in the
-            list may match for that property to match.
-        '''
+        """Return a list of the ids of the active nodes in this class that
+        match the 'filter' spec, sorted by the group spec and then the
+        sort spec.
+
+        "filterspec" is {propname: value(s)}
+
+        "sort" and "group" are (dir, prop) where dir is '+', '-' or None
+        and prop is a prop name or None
+
+        "search_matches" is {nodeid: marker}
+
+        The filter must match all properties specificed - but if the
+        property value to match is a list, any one of the values in the
+        list may match for that property to match.
+        """
         raise NotImplementedError
 
     def count(self):
index 8203d956b86bde4a8e16f2879a50674a4d65c282..378d593e58cf20c7925b3cc102eb5b809aa47dc5 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: i18n.py,v 1.3 2002-09-10 00:18:20 richard Exp $
+# $Id: i18n.py,v 1.4 2004-02-11 23:55:08 richard Exp $
 
-__doc__ = """
+"""
 RoundUp Internationalization (I18N)
 
-To use this module, the following code should be used:
+To use this module, the following code should be used::
 
     from roundup.i18n import _
     ...
@@ -28,14 +28,14 @@ To use this module, the following code should be used:
 
 Note that to enable re-ordering of inserted texts in formatting strings
 (which can easily happen if a sentence has to be re-ordered due to
-grammatical changes), translatable formats should use named format specs:
+grammatical changes), translatable formats should use named format specs::
 
     ... _('Index of %(classname)s') % {'classname': cn} ...
 
 Also, this eases the job of translators since they have some context what
 the dynamic portion of a message really means.
-
 """
+__docformat__ = 'restructuredtext'
 
 # first, we try to import gettext; this probably never fails, but we make
 # sure we survive this anyway
index 9bee8bd19e19b54d5ddb4495ae522be4302a11e7..4cd5d24ad1b763e5571f1d4bc25233a22715594d 100644 (file)
 #     that promote freedom, but obviously am giving up any rights
 #     to compel such.
 # 
-#$Id: indexer.py,v 1.17 2004-01-20 03:58:38 richard Exp $
-'''
-This module provides an indexer class, RoundupIndexer, that stores text
+#$Id: indexer.py,v 1.18 2004-02-11 23:55:08 richard Exp $
+'''This module provides an indexer class, RoundupIndexer, that stores text
 indices in a roundup instance.  This class makes searching the content of
 messages, string properties and text files possible.
 '''
+__docformat__ = 'restructuredtext'
+
 import os, shutil, re, mimetypes, marshal, zlib, errno
 from hyperdb import Link, Multilink
 
 class Indexer:
-    ''' Indexes information from roundup's hyperdb to allow efficient
-        searching.
+    '''Indexes information from roundup's hyperdb to allow efficient
+    searching.
+
+    Three structures are created by the indexer::
 
-        Three structures are created by the indexer:
           files   {identifier: (fileid, wordcount)}
           words   {word: {fileid: count}}
           fileids {fileid: identifier}
-        where identifier is (classname, nodeid, propertyname)
+
+    where identifier is (classname, nodeid, propertyname)
     '''
     def __init__(self, db_path):
         self.indexdb_path = os.path.join(db_path, 'indexes')
@@ -69,8 +72,8 @@ class Indexer:
         return self.reindex
 
     def add_text(self, identifier, text, mime_type='text/plain'):
-        ''' Add some text associated with the (classname, nodeid, property)
-            identifier.
+        '''Add some text associated with the (classname, nodeid, property)
+        identifier.
         '''
         # make sure the index is loaded
         self.load_index()
@@ -114,7 +117,7 @@ class Indexer:
         self.changed = 1
 
     def splitter(self, text, ftype):
-        ''' Split the contents of a text string into a list of 'words'
+        '''Split the contents of a text string into a list of 'words'
         '''
         if ftype == 'text/plain':
             words = self.text_splitter(text)
@@ -136,10 +139,10 @@ class Indexer:
 
     def search(self, search_terms, klass, ignore={},
             dre=re.compile(r'([^\d]+)(\d+)')):
-        ''' Display search results looking for [search, terms] associated
-            with the hyperdb Class "klass". Ignore hits on {class: property}.
+        '''Display search results looking for [search, terms] associated
+        with the hyperdb Class "klass". Ignore hits on {class: property}.
 
-            "dre" is a helper, not an argument.
+        "dre" is a helper, not an argument.
         '''
         # do the index lookup
         hits = self.find(search_terms)
@@ -201,7 +204,7 @@ class Indexer:
     # we override this to ignore not 2 < word < 25 and also to fix a bug -
     # the (fail) case.
     def find(self, wordlist):
-        ''' Locate files that match ALL the words in wordlist
+        '''Locate files that match ALL the words in wordlist
         '''
         if not hasattr(self, 'words'):
             self.load_index()
@@ -315,7 +318,7 @@ class Indexer:
         self.changed = 0
 
     def purge_entry(self, identifier):
-        ''' Remove a file from file index and word index
+        '''Remove a file from file index and word index
         '''
         self.load_index()
 
index 25668c5a49ab6b80164ee9e3228a368ad6f5d2d6..b334c087faf3d7e1a80e2ca713cc62019a14f799 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: init.py,v 1.28 2003-11-13 04:12:10 richard Exp $
+# $Id: init.py,v 1.29 2004-02-11 23:55:08 richard Exp $
 
-__doc__ = """
-Init (create) a roundup instance.
+"""Init (create) a roundup instance.
 """
+__docformat__ = 'restructuredtext'
 
 import os, sys, errno, rfc822
 
@@ -57,31 +57,32 @@ def copytree(src, dst, symlinks=0):
 def install(instance_home, template):
     '''Install an instance using the named template and backend.
 
-    instance_home - the directory to place the instance data in
-    template      - the directory holding the template to use in creating
-                    the instance data
+    'instance_home'
+       the directory to place the instance data in
+    'template'
+       the directory holding the template to use in creating the instance data
 
     The instance_home directory will be created using the files found in
     the named template (roundup.templates.<name>). A standard instance_home
     contains:
-        . config.py
-          - simple configuration of things like the email address for the
-            mail gateway, the mail domain, the mail host, ...
-        . dbinit.py and select_db.py
-          - defines the schema for the hyperdatabase and indicates which
-            backend to use.
-        . interfaces.py
-          - defines the CGI Client and mail gateway MailGW classes that are
-            used by roundup.cgi, roundup-server and roundup-mailgw.
-        . __init__.py
-          - ties together all the instance information into one interface
-        . db/
-          - the actual database that stores the instance's data
-        . html/
-          - the html templates that are used by the CGI Client
-        . detectors/
-          - the auditor and reactor modules for this instance
 
+    config.py
+      simple configuration of things like the email address for the
+      mail gateway, the mail domain, the mail host, ...
+    dbinit.py and select_db.py
+      defines the schema for the hyperdatabase and indicates which
+      backend to use.
+    interfaces.py
+      defines the CGI Client and mail gateway MailGW classes that are
+      used by roundup.cgi, roundup-server and roundup-mailgw.
+    __init__.py
+      ties together all the instance information into one interface
+    db/
+      the actual database that stores the instance's data
+    html/
+      the html templates that are used by the CGI Client
+    detectors/
+      the auditor and reactor modules for this instance
     '''
     # At the moment, it's just a copy
     copytree(template, instance_home)
index 4e07a5b464b801442204ab72bdceb976bef34460..97c16f410ba78c34270424e467c2a66661a0dd26 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: install_util.py,v 1.9 2003-11-11 22:37:25 richard Exp $
+# $Id: install_util.py,v 1.10 2004-02-11 23:55:08 richard Exp $
 
-__doc__ = """
-Support module to generate and check fingerprints of installed files.
+"""Support module to generate and check fingerprints of installed files.
 """
+__docformat__ = 'restructuredtext'
 
 import os, sha, shutil
 
index 3c85b6d2c5338d205ddfbdf6d3e35094537726bd..81c946167c6e7a8c0c6815ff2f10a35d288aaf0c 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: instance.py,v 1.11 2003-12-06 02:46:34 richard Exp $
+# $Id: instance.py,v 1.12 2004-02-11 23:55:08 richard Exp $
 
-__doc__ = '''
-Tracker handling (open tracker).
+'''Tracker handling (open tracker).
 
 Backwards compatibility for the old-style "imported" trackers.
 '''
+__docformat__ = 'restructuredtext'
 
 import os
 
index ddfc109978f6f032774dbec99ae2067b94d28e4a..ec5951ed87b12c8bd88289da049dbc51ce81cd7a 100644 (file)
@@ -1,5 +1,7 @@
-"""Sending Roundup-specific mail over SMTP."""
-# $Id: mailer.py,v 1.4 2004-01-20 00:05:46 richard Exp $
+"""Sending Roundup-specific mail over SMTP.
+"""
+__docformat__ = 'restructuredtext'
+# $Id: mailer.py,v 1.5 2004-02-11 23:55:08 richard Exp $
 
 import time, quopri, os, socket, smtplib, re
 
index 208cbb86ae85a4a21d46f6191ddd0ac20e6c89f3..f45eedc9d51af4e3e6e0a88259c054676215dcdb 100644 (file)
@@ -16,8 +16,7 @@
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 #
 
-"""
-An e-mail gateway for Roundup.
+"""An e-mail gateway for Roundup.
 
 Incoming messages are examined for multiple parts:
  . In a multipart/mixed message or part, each subpart is extracted and
@@ -73,8 +72,9 @@ are calling the create() method to create a new node). If an auditor raises
 an exception, the original message is bounced back to the sender with the
 explanatory message given in the exception. 
 
-$Id: mailgw.py,v 1.142 2004-01-20 00:06:09 richard Exp $
+$Id: mailgw.py,v 1.143 2004-02-11 23:55:08 richard Exp $
 """
+__docformat__ = 'restructuredtext'
 
 import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri
 import time, random, sys
index 97de75d08be5cd4a4d2ca7dfbd9eaedb726c4f73..a267e4223a211dc54d7fca773943cf3d519d76f1 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: password.py,v 1.10 2003-11-11 00:35:13 richard Exp $
+# $Id: password.py,v 1.11 2004-02-11 23:55:08 richard Exp $
 
-__doc__ = """
-Password handling (encoding, decoding).
+"""Password handling (encoding, decoding).
 """
+__docformat__ = 'restructuredtext'
 
 import sha, re, string, random
 try:
index 8957e3540619afc2a6020865c938cd3f7742b5e4..91a8125dc7a2482ee75871823307945ea470cef7 100644 (file)
@@ -1,8 +1,7 @@
-"""
-Supplies a Python-2.3 Object Craft csv module work-alike to the extent
+"""Supplies a Python-2.3 Object Craft csv module work-alike to the extent
 needed by Roundup using the Python 2.3 csv module.
-
 """
+__docformat__ = 'restructuredtext'
 
 from roundup.i18n import _
 from cStringIO import StringIO
index 0faa833f2e34d047af431c34fdcb16a96acb7a29..a54d34f3371ac1ac3b201b31a23f9425e3337af7 100644 (file)
@@ -1,3 +1,7 @@
+"""Some rfc822 functions taken from the new (python2.3) "email" module.
+"""
+__docformat__ = 'restructuredtext'
+
 import re
 from string import letters, digits
 from binascii import b2a_base64, a2b_base64
@@ -37,7 +41,8 @@ def base64_decode(s, convert_eols=None):
     return dec
 
 def unquote_match(match):
-    """Turn a match in the form =AB to the ASCII character with value 0xab
+    """Turn a match in the form ``=AB`` to the ASCII character with value
+    0xab.
 
     Taken from 'email' module
     """
@@ -45,7 +50,7 @@ def unquote_match(match):
     return chr(int(s[1:3], 16))
 
 def qp_decode(s):
-    """Decode a string encoded with RFC 2045 MIME header `Q' encoding.
+    """Decode a string encoded with RFC 2045 MIME header 'Q' encoding.
 
     This function does not parse a full MIME header value encoded with
     quoted-printable (like =?iso-8895-1?q?Hello_World?=) -- please use
index 178552f5a83707b99e190f2014b0024ba23f0567..761f1ae4f8a5da4e93a1316737bd63e149373e5f 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: roundupdb.py,v 1.96 2003-12-05 04:43:30 richard Exp $
+# $Id: roundupdb.py,v 1.97 2004-02-11 23:55:08 richard Exp $
 
-__doc__ = """
-Extending hyperdb with types specific to issue-tracking.
+"""Extending hyperdb with types specific to issue-tracking.
 """
+__docformat__ = 'restructuredtext'
+
 from __future__ import nested_scopes
 
 import re, os, smtplib, socket, time, random
@@ -95,15 +96,16 @@ class DetectorError(RuntimeError):
 
 # deviation from spec - was called IssueClass
 class IssueClass:
-    """ This class is intended to be mixed-in with a hyperdb backend
-        implementation. The backend should provide a mechanism that
-        enforces the title, messages, files, nosy and superseder
-        properties:
-            properties['title'] = hyperdb.String(indexme='yes')
-            properties['messages'] = hyperdb.Multilink("msg")
-            properties['files'] = hyperdb.Multilink("file")
-            properties['nosy'] = hyperdb.Multilink("user")
-            properties['superseder'] = hyperdb.Multilink(classname)
+    """This class is intended to be mixed-in with a hyperdb backend
+    implementation. The backend should provide a mechanism that
+    enforces the title, messages, files, nosy and superseder
+    properties:
+
+    - title = hyperdb.String(indexme='yes')
+    - messages = hyperdb.Multilink("msg")
+    - files = hyperdb.Multilink("file")
+    - nosy = hyperdb.Multilink("user")
+    - superseder = hyperdb.Multilink(classname)
     """
 
     # New methods:
index a64069f211be454dbcb205d068ba8e5cba47f582..f791def7ebcba8617e484b86b902045fa465eb8b 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: __init__.py,v 1.2 2002-09-10 01:07:05 richard Exp $
+# $Id: __init__.py,v 1.3 2004-02-11 23:55:10 richard Exp $
+
+'''Subpackage containing the modules that implement the command
+line tools.
 
-__doc__ = '''
-Subpackage containing the modules that implement the command line tools.
 Note that these are imported by script stubs generated by "setup.py".
 '''
+__docformat__ = 'restructuredtext'
 # vim: set filetype=python ts=4 sw=4 et si
index d4866f8d1c59b17f83c55d538a94903a49aa37fc..47db75e4cf0dae2c9e52d8e28f4311e606092296 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: roundup_admin.py,v 1.5 2003-04-24 04:27:32 richard Exp $
+# $Id: roundup_admin.py,v 1.6 2004-02-11 23:55:10 richard Exp $
+
+"""Command-line script stub that calls the roundup.admin functions.
+"""
+__docformat__ = 'restructuredtext'
 
 # python version check
 from roundup import version_check
index 65163d83905fa0045a2d55b984ff1416ef840737..5b6905c503e8b4d2f71973ada512f5721f8cee97 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: roundup_mailgw.py,v 1.10 2003-04-24 04:27:32 richard Exp $
+# $Id: roundup_mailgw.py,v 1.11 2004-02-11 23:55:10 richard Exp $
+
+"""Command-line script stub that calls the roundup.mailgw.
+"""
+__docformat__ = 'restructuredtext'
 
 # python version check
 from roundup import version_check
index 2039e96804ff651c8ee6d222d14dddb8e2f0f778..6f58a60ca3dd2fd71f6710b451de0aa2a613ad07 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-""" HTTP Server that serves roundup.
 
-$Id: roundup_server.py,v 1.36 2003-12-06 02:46:34 richard Exp $
+"""Command-line script that runs a server over roundup.cgi.client.
+
+$Id: roundup_server.py,v 1.37 2004-02-11 23:55:10 richard Exp $
 """
+__docformat__ = 'restructuredtext'
 
 # python version check
 from roundup import version_check
index 241715d80b356d64ac2ff4ddd17bcdc1213f6a4f..58496f452a18d35648ecb9886c4dfbaa986cce83 100644 (file)
@@ -1,3 +1,7 @@
+"""Handle the security declarations used in Roundup trackers.
+"""
+__docformat__ = 'restructuredtext'
+
 import weakref
 
 from roundup import hyperdb
index 4ba510368ca0182dba166edb21bbc3cb907be635..cdebffc8a2a031bb164249e24932980c00178b0c 100644 (file)
@@ -8,23 +8,25 @@
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 # 
-# $Id: token.py,v 1.3 2002-09-10 00:18:20 richard Exp $
+# $Id: token.py,v 1.4 2004-02-11 23:55:08 richard Exp $
 #
 
-__doc__ = """
-This module provides the tokeniser used by roundup-admin.
+"""This module provides the tokeniser used by roundup-admin.
 """
+__docformat__ = 'restructuredtext'
 
 def token_split(s, whitespace=' \r\n\t', quotes='\'"',
         escaped={'r':'\r', 'n':'\n', 't':'\t'}):
-    '''Split the string up into tokens. An occurence of a ' or " in the
-       input will cause the splitter to ignore whitespace until a matching
-       quote char is found. Embedded non-matching quote chars are also
-       skipped.
-       Whitespace and quoting characters may be escaped using a backslash.
-       \r, \n and \t are converted to carriage-return, newline and tab.
-       All other backslashed characters are left as-is.
-       Valid:
+    '''Split the string up into tokens. An occurence of a ``'`` or ``"`` in
+    the input will cause the splitter to ignore whitespace until a matching
+    quote char is found. Embedded non-matching quote chars are also skipped.
+
+    Whitespace and quoting characters may be escaped using a backslash.
+    ``\r``, ``\n`` and ``\t`` are converted to carriage-return, newline and
+    tab.  All other backslashed characters are left as-is.
+
+    Valid examples::
+
            hello world      (2 tokens: hello, world)
            "hello world"    (1 token: hello world)
            "Roch'e" Compaan (2 tokens: Roch'e Compaan)
@@ -33,7 +35,9 @@ def token_split(s, whitespace=' \r\n\t', quotes='\'"',
            \\               (1 token: \)
            \n               (1 token: a newline)
            \o               (1 token: \o)
-       Invalid:
+
+    Invalid examples::
+
            "hello world     (no matching quote)
            Roch'e Compaan   (no matching quote)
     '''
index 20ef7d93b0cfd251a09d98a63d9c0f20feece244..5f6f2be38aff7604182e253dc566ef39d9788660 100644 (file)
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: version_check.py,v 1.3 2002-09-10 00:18:20 richard Exp $
+# $Id: version_check.py,v 1.4 2004-02-11 23:55:08 richard Exp $
+
+"""Enforces the minimum Python version that Roundup requires.
+"""
+__docformat__ = 'restructuredtext'
 
 import sys
 if not hasattr(sys, 'version_info') or sys.version_info[:3] < (2,1,1):