Code

handled some XXXs
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Tue, 10 Sep 2002 12:44:42 +0000 (12:44 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Tue, 10 Sep 2002 12:44:42 +0000 (12:44 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1124 57a73879-2fb5-44c3-a270-3262357dd7e2

roundup/admin.py
roundup/backends/back_anydbm.py
roundup/cgi/client.py
roundup/cgi/templating.py
roundup/date.py
roundup/init.py
roundup/mailgw.py
roundup/roundupdb.py

index 51710810eafa2a7876bea19887604788e8505d10..f2b276d4ef2a557cb4d1dc1965462392b09a310f 100644 (file)
@@ -16,7 +16,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: admin.py,v 1.27 2002-09-10 07:07:16 richard Exp $
+# $Id: admin.py,v 1.28 2002-09-10 12:44:42 richard Exp $
 
 import sys, os, getpass, getopt, re, UserDict, shlex, shutil
 try:
@@ -811,11 +811,11 @@ Command help:
 
     def do_export(self, args):
         '''Usage: export [class[,class]] export_dir
-        Export the database to tab-separated-value files.
+        Export the database to colon-separated-value files.
 
         This action exports the current data from the database into
-        tab-separated-value files that are placed in the nominated destination
-        directory. The journals are not exported.
+        colon-separated-value files that are placed in the nominated
+        destination directory. The journals are not exported.
         '''
         # we need the CSV module
         if csv is None:
@@ -862,9 +862,9 @@ Command help:
         The imported nodes will have the same nodeid as defined in the
         import file, thus replacing any existing content.
 
-        XXX The new nodes are added to the existing database - if you want to
-        XXX create a new database using the imported data, then create a new
-        XXX database (or, tediously, retire all the old data.)
+        The new nodes are added to the existing database - if you want to
+        create a new database using the imported data, then create a new
+        database (or, tediously, retire all the old data.)
         '''
         if len(args) < 1:
             raise UsageError, _('Not enough arguments supplied')
index db188141017d45a764711dd949585c16be579880..12ba0e49153b6668eb7b20fd4b36587c190929f8 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: back_anydbm.py,v 1.74 2002-09-10 08:04:56 richard Exp $
+#$Id: back_anydbm.py,v 1.75 2002-09-10 12:44:42 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
@@ -1001,7 +1001,7 @@ class Class(hyperdb.Class):
 
         return d[propname]
 
-    # XXX not in spec
+    # not in spec
     def getnode(self, nodeid, cache=1):
         ''' Return a convenience wrapper for the node.
 
@@ -1368,7 +1368,7 @@ class Class(hyperdb.Class):
             cldb.close()
         raise KeyError, keyvalue
 
-    # XXX: change from spec - allows multiple props to match
+    # change from spec - allows multiple props to match
     def find(self, **propspec):
         '''Get the ids of nodes in this class which link to the given nodes.
 
@@ -1881,7 +1881,7 @@ class FileClass(Class):
         self.db.indexer.add_text((self.classname, nodeid, 'content'), content,
             mime_type)
 
-# XXX deviation from spec - was called ItemClass
+# deviation from spec - was called ItemClass
 class IssueClass(Class, roundupdb.IssueClass):
     # Overridden methods:
     def __init__(self, db, classname, **properties):
index 06bff934d236ec721eee31260b524c8ce6519e18..97342dbd9e097a0d4b9382ffaa271f27dd77aab0 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: client.py,v 1.26 2002-09-10 03:01:18 richard Exp $
+# $Id: client.py,v 1.27 2002-09-10 12:44:42 richard Exp $
 
 __doc__ = """
 WWW request handler (also used in the stand-alone server).
@@ -317,7 +317,7 @@ class Client:
         ''' Return a PageTemplate for the named page
         '''
         pt = getTemplate(self.instance.config.TEMPLATES, name, extension)
-        # XXX handle PT rendering errors here more nicely
+        # catch errors so we can handle PT rendering errors more nicely
         try:
             # let the template render figure stuff out
             return pt.render(self, None, None, **kwargs)
index 124f97d9092848920539291c5baa824f9f065281..3e34c043a1d916a98603cc85c7e17a48e3325e6a 100644 (file)
@@ -222,7 +222,7 @@ class HTMLClass:
     def __getitem__(self, item):
         ''' return an HTMLProperty instance
         '''
-        #print 'getitem', (self, item)
+       #print 'HTMLClass.getitem', (self, item)
 
         # we don't exist
         if item == 'id':
@@ -378,7 +378,7 @@ class HTMLItem:
     def __getitem__(self, item):
         ''' return an HTMLProperty instance
         '''
-        #print 'getitem', (self, item)
+       #print 'HTMLItem.getitem', (self, item)
         if item == 'id':
             return self._nodeid
 
@@ -411,7 +411,12 @@ class HTMLItem:
         return '  <input type="hidden" name=":action" value="edit">\n'\
         '  <input type="submit" name="submit" value="%s">'%label
 
-    # XXX this probably should just return the history items, not the HTML
+    def journal(self, direction='descending'):
+        ''' Return a list of HTMLJournalEntry instances.
+        '''
+        # XXX do this
+        return []
+
     def history(self, direction='descending'):
         l = ['<table class="history">'
              '<tr><th colspan="4" class="header">',
@@ -753,13 +758,13 @@ class LinkHTMLProperty(HTMLProperty):
     '''
     def __getattr__(self, attr):
         ''' return a new HTMLItem '''
-        #print 'getattr', (self, attr, self._value)
+       #print 'Link.getattr', (self, attr, self._value)
         if not self._value:
             raise AttributeError, "Can't access missing value"
         if self._prop.classname == 'user':
-            klass = HTMLItem
-        else:
             klass = HTMLUser
+        else:
+            klass = HTMLItem
         i = klass(self._client, self._prop.classname, self._value)
         return getattr(i, attr)
 
@@ -865,7 +870,7 @@ class MultilinkHTMLProperty(HTMLProperty):
     def __getitem__(self, num):
         ''' iterate and return a new HTMLItem
         '''
-        #print 'getitem', (self, num)
+       #print 'Multi.getitem', (self, num)
         value = self._value[num]
         if self._prop.classname == 'user':
             klass = HTMLUser
@@ -873,6 +878,11 @@ class MultilinkHTMLProperty(HTMLProperty):
             klass = HTMLItem
         return klass(self._client, self._prop.classname, value)
 
+    def __contains__(self, value):
+        ''' Support the "in" operator
+        '''
+        return value in self._value
+
     def reverse(self):
         ''' return the list in reverse order
         '''
index 484889bbeac2bda60d85075482811a18abeeedcb..1cc6464b9aa8748f64e13ce0a4c5b9a1d41d3c72 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: date.py,v 1.27 2002-09-10 01:27:13 richard Exp $
+# $Id: date.py,v 1.28 2002-09-10 12:44:42 richard Exp $
 
 __doc__ = """
 Date, time and time interval handling.
@@ -153,7 +153,7 @@ class Date:
         """
         return Date(self.addInterval(interval))
 
-    # XXX deviates from spec to allow subtraction of dates as well
+    # deviates from spec to allow subtraction of dates as well
     def __sub__(self, other):
         """ Subtract:
              1. an interval from this date to produce another date.
index 0fb1e5c9961e8368bc312beb870d93daa50d2c04..b0e2b5b8bc03f0e38078dc3276f84f76e3541347 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: init.py,v 1.23 2002-09-09 23:55:19 richard Exp $
+# $Id: init.py,v 1.24 2002-09-10 12:44:42 richard Exp $
 
 __doc__ = """
 Init (create) a roundup instance.
@@ -36,7 +36,7 @@ def copytree(src, dst, symlinks=0):
     it is false, the contents of the files pointed to by symbolic
     links are copied.
 
-    XXX copied from shutil.py in std lib
+    This was copied from shutil.py in std lib.
 
     """
     names = os.listdir(src)
index 50e3cbed5b80cee753f44e95c563798f1b0efc8a..07a041d63ced5e28e723bc08bb1c795536da26d8 100644 (file)
@@ -73,7 +73,7 @@ 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.85 2002-09-10 03:01:18 richard Exp $
+$Id: mailgw.py,v 1.86 2002-09-10 12:44:42 richard Exp $
 '''
 
 import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri
@@ -391,6 +391,63 @@ does not exist.
 Subject was: "%s"
 '''%(nodeid, subject)
 
+        #
+        # handle the users
+        #
+        # Don't create users if anonymous isn't allowed to register
+        create = 1
+        anonid = self.db.user.lookup('anonymous')
+        if not self.db.security.hasPermission('Email Registration', anonid):
+            create = 0
+
+        # ok, now figure out who the author is - create a new user if the
+        # "create" flag is true
+        author = uidFromAddress(self.db, message.getaddrlist('from')[0],
+            create=create)
+
+        # no author? means we're not author
+        if not author:
+            raise Unauthorized, '''
+You are not a registered user.
+
+Unknown address: %s
+'''%message.getaddrlist('from')[0][1]
+
+        # make sure the author has permission to use the email interface
+        if not self.db.security.hasPermission('Email Access', author):
+            raise Unauthorized, 'You are not permitted to access this tracker.'
+
+        # make sure they're allowed to edit this class of information
+        if not self.db.security.hasPermission('Edit', author, classname):
+            raise Unauthorized, 'You are not permitted to edit %s.'%classname
+
+        # the author may have been created - make sure the change is
+        # committed before we reopen the database
+        self.db.commit()
+
+        # reopen the database as the author
+        username = self.db.user.get(author, 'username')
+        self.db = self.instance.open(username)
+
+        # re-get the class with the new database connection
+        cl = self.db.getclass(classname)
+
+        # now update the recipients list
+        recipients = []
+        tracker_email = self.instance.config.TRACKER_EMAIL.lower()
+        for recipient in message.getaddrlist('to') + message.getaddrlist('cc'):
+            r = recipient[1].strip().lower()
+            if r == tracker_email or not r:
+                continue
+
+            # look up the recipient - create if necessary (and we're
+            # allowed to)
+            recipient = uidFromAddress(self.db, recipient, create)
+
+            # if all's well, add the recipient to the list
+            if recipient:
+                recipients.append(recipient)
+
         #
         # extract the args
         #
@@ -521,60 +578,6 @@ There were problems handling your subject line argument list:
 Subject was: "%s"
 '''%(errors, subject)
 
-        #
-        # handle the users
-        #
-
-        # Don't create users if anonymous isn't allowed to register
-        create = 1
-        anonid = self.db.user.lookup('anonymous')
-        if not self.db.security.hasPermission('Email Registration', anonid):
-            create = 0
-
-        # ok, now figure out who the author is - create a new user if the
-        # "create" flag is true
-        author = uidFromAddress(self.db, message.getaddrlist('from')[0],
-            create=create)
-
-        # no author? means we're not author
-        if not author:
-            raise Unauthorized, '''
-You are not a registered user.
-
-Unknown address: %s
-'''%message.getaddrlist('from')[0][1]
-
-        # make sure the author has permission to use the email interface
-        if not self.db.security.hasPermission('Email Access', author):
-            raise Unauthorized, 'You are not permitted to access this tracker.'
-
-        # the author may have been created - make sure the change is
-        # committed before we reopen the database
-        self.db.commit()
-            
-        # reopen the database as the author
-        username = self.db.user.get(author, 'username')
-        self.db = self.instance.open(username)
-
-        # re-get the class with the new database connection
-        cl = self.db.getclass(classname)
-
-        # now update the recipients list
-        recipients = []
-        tracker_email = self.instance.config.TRACKER_EMAIL.lower()
-        for recipient in message.getaddrlist('to') + message.getaddrlist('cc'):
-            r = recipient[1].strip().lower()
-            if r == tracker_email or not r:
-                continue
-
-            # look up the recipient - create if necessary (and we're
-            # allowed to)
-            recipient = uidFromAddress(self.db, recipient, create)
-
-            # if all's well, add the recipient to the list
-            if recipient:
-                recipients.append(recipient)
-
         #
         # handle message-id and in-reply-to
         #
index 1baf624872ea59fae91186409ab58556b81b20e1..1e1ed409bed1e34d81a3b49e5684ae6fa35f5871 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: roundupdb.py,v 1.66 2002-09-10 03:01:18 richard Exp $
+# $Id: roundupdb.py,v 1.67 2002-09-10 12:44:42 richard Exp $
 
 __doc__ = """
 Extending hyperdb with types specific to issue-tracking.
@@ -46,9 +46,11 @@ class MessageSendError(RuntimeError):
     pass
 
 class DetectorError(RuntimeError):
+    ''' Raised by detectors that want to indicate that something's amiss
+    '''
     pass
 
-# XXX deviation from spec - was called ItemClass
+# 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
@@ -134,7 +136,7 @@ class IssueClass:
             # send the message
             self.send_message(nodeid, msgid, note, sendto)
 
-    # XXX backwards compatibility - don't remove
+    # backwards compatibility - don't remove
     sendmessage = nosymessage
 
     def send_message(self, nodeid, msgid, note, sendto):