Code

. web forms may now unset Link values (like assignedto)
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 31 Jul 2002 23:57:37 +0000 (23:57 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 31 Jul 2002 23:57:37 +0000 (23:57 +0000)
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@943 57a73879-2fb5-44c3-a270-3262357dd7e2

CHANGES.txt
doc/upgrading.txt
roundup/backends/back_anydbm.py
roundup/backends/back_metakit.py
roundup/cgi_client.py
roundup/templates/classic/detectors/nosyreaction.py
roundup/templates/extended/detectors/nosyreaction.py
test/test_db.py

index 23d2f2609ec13b92e1e671086c84e8f7c4ea45f0..4d394d68674524fe21336748cb85ec27eb8a3b4b 100644 (file)
@@ -9,8 +9,10 @@ Fixed:
  . #571170 ] gdbm deadlock
  . #576241 ] MultiLink problems in parsePropsFromForm
  . fixed the date module so that Date(". - 2d") works
+ . web forms may now unset Link values (like assignedto)
 
 Feature:
+TODO: roll stuff in from the TODO to here
  . added capability to save queries:
    - a query Class with name, klass (to search) and url (query string) properties
    - a Multilink to query on user called queries
index 2fb2159025c62c2931182ba06a66024af8f5b310..c80ebd8f91df1c09b0dd57c51c3fb83a05259f28 100644 (file)
@@ -19,6 +19,7 @@ reindexing
 TODO: dbinit now imports classes from selct_db
 TODO: select_db needs fixing to include Class, FileClass and IssueClass
 TODO: migration of security settings
+TODO: nosy reactor has been updated
 
 
 Migrating from 0.4.1 to 0.4.2
index fa67c05eeae6a67167aeba734605019096811e59..979382f50533736619b38de15c4373adf8de69ba 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.56 2002-07-31 22:04:33 richard Exp $
+#$Id: back_anydbm.py,v 1.57 2002-07-31 23:57:36 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
@@ -998,21 +998,23 @@ class Class(hyperdb.Class):
 
             # do stuff based on the prop type
             if isinstance(prop, Link):
-                link_class = self.properties[propname].classname
+                link_class = prop.classname
                 # if it isn't a number, it's a key
-                if type(value) != type(''):
-                    raise ValueError, 'link value must be String'
-                if not num_re.match(value):
+                if value is not None and not isinstance(value, type('')):
+                    raise ValueError, 'property "%s" link value be a string'%(
+                        propname)
+                if isinstance(value, type('')) and not num_re.match(value):
                     try:
                         value = self.db.classes[link_class].lookup(value)
                     except (TypeError, KeyError):
                         raise IndexError, 'new property "%s": %s not a %s'%(
-                            propname, value, self.properties[propname].classname)
+                            propname, value, prop.classname)
 
-                if not self.db.getclass(link_class).hasnode(value):
+                if (value is not None and
+                        not self.db.getclass(link_class).hasnode(value)):
                     raise IndexError, '%s has no node %s'%(link_class, value)
 
-                if self.do_journal and self.properties[propname].do_journal:
+                if self.do_journal and prop.do_journal:
                     # register the unlink with the old linked node
                     if node[propname] is not None:
                         self.db.addjournal(link_class, node[propname], 'unlink',
@@ -1791,6 +1793,9 @@ class IssueClass(Class, roundupdb.IssueClass):
 
 #
 #$Log: not supported by cvs2svn $
+#Revision 1.56  2002/07/31 22:04:33  richard
+#cleanup
+#
 #Revision 1.55  2002/07/30 08:22:38  richard
 #Session storage in the hyperdb was horribly, horribly inefficient. We use
 #a simple anydbm wrapper now - which could be overridden by the metakit
index 46d82ea3c5f5a44b7a813cfc4fbf355692254632..26bf2aa33a4b4d8b8c8f50d92cdbc32ebd44ab32 100755 (executable)
@@ -324,9 +324,11 @@ class Class:
             # do stuff based on the prop type
             if isinstance(prop, hyperdb.Link):
                 link_class = prop.classname
+                # must be a string or None
+                if value is not None and not isinstance(value, type('')):
+                    raise ValueError, 'property "%s" link value be a string'%(
+                        propname)
                 # if it isn't a number, it's a key
-                if type(value) != _STRINGTYPE:
-                    raise ValueError, 'link value must be String'
                 try:
                     int(value)
                 except ValueError:
@@ -336,7 +338,8 @@ class Class:
                         raise IndexError, 'new property "%s": %s not a %s'%(
                             key, value, prop.classname)
 
-                if not self.db.getclass(link_class).hasnode(value):
+                if (value is not None and
+                        not self.db.getclass(link_class).hasnode(value)):
                     raise IndexError, '%s has no node %s'%(link_class, value)
 
                 setattr(row, key, int(value))
@@ -345,11 +348,13 @@ class Class:
                 if self.do_journal and prop.do_journal:
                     # register the unlink with the old linked node
                     if oldvalue:
-                        self.db.addjournal(link_class, value, _UNLINK, (self.classname, str(row.id), key))
+                        self.db.addjournal(link_class, value, _UNLINK,
+                            (self.classname, str(row.id), key))
 
                     # register the link with the newly linked node
                     if value:
-                        self.db.addjournal(link_class, value, _LINK, (self.classname, str(row.id), key))
+                        self.db.addjournal(link_class, value, _LINK,
+                            (self.classname, str(row.id), key))
 
             elif isinstance(prop, hyperdb.Multilink):
                 if type(value) != _LISTTYPE:
index b5da4150a5dbf20ccf08f4795dba2d210b244e94..632b1d4f955e3c678a371056afa1fcd77e32f6c0 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: cgi_client.py,v 1.153 2002-07-31 22:40:50 gmcm Exp $
+# $Id: cgi_client.py,v 1.154 2002-07-31 23:57:36 richard Exp $
 
 __doc__ = """
 WWW request handler (also used in the stand-alone server).
@@ -1631,8 +1631,7 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
             value = form[key].value.strip()
             # see if it's the "no selection" choice
             if value == '-1':
-                # don't set this property
-                continue
+                value = None
             else:
                 # handle key values
                 link = cl.properties[key].classname
@@ -1691,6 +1690,10 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.153  2002/07/31 22:40:50  gmcm
+# Fixes to the search form and saving queries.
+# Fixes to  sorting in back_metakit.py.
+#
 # Revision 1.152  2002/07/31 22:04:14  richard
 # cleanup
 #
index 4490b49a3df850ffc20818c504a25ae5580e32de..93d8b67505b8f5f4de66e2b7519d2dfdc254b5bd 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: nosyreaction.py,v 1.12 2002-05-29 01:16:17 richard Exp $
+#$Id: nosyreaction.py,v 1.13 2002-07-31 23:57:36 richard Exp $
 
 from roundup import roundupdb, hyperdb
 
@@ -88,7 +88,7 @@ def updatenosy(db, cl, nodeid, newvalues):
                 current[value] = 1
 
     # add assignedto(s) to the nosy list
-    if newvalues.has_key('assignedto'):
+    if newvalues.has_key('assignedto') and newvalues['assignedto'] is not None:
         propdef = cl.getprops()
         if isinstance(propdef['assignedto'], hyperdb.Link):
             assignedto_ids = [newvalues['assignedto']]
@@ -141,6 +141,18 @@ def init(db):
 
 #
 #$Log: not supported by cvs2svn $
+#Revision 1.12  2002/05/29 01:16:17  richard
+#Sorry about this huge checkin! It's fixing a lot of related stuff in one go
+#though.
+#
+#. #541941 ] changing multilink properties by mail
+#. #526730 ] search for messages capability
+#. #505180 ] split MailGW.handle_Message
+#  - also changed cgi client since it was duplicating the functionality
+#. build htmlbase if tests are run using CVS checkout (removed note from
+#  installation.txt)
+#. don't create an empty message on email issue creation if the email is empty
+#
 #Revision 1.11  2002/01/14 22:21:38  richard
 ##503353 ] setting properties in initial email
 #
index 4490b49a3df850ffc20818c504a25ae5580e32de..a11928ac6452c43d6f6d53a01f16b20f22adc0e3 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: nosyreaction.py,v 1.12 2002-05-29 01:16:17 richard Exp $
+#$Id: nosyreaction.py,v 1.13 2002-07-31 23:57:37 richard Exp $
 
 from roundup import roundupdb, hyperdb
 
@@ -88,7 +88,7 @@ def updatenosy(db, cl, nodeid, newvalues):
                 current[value] = 1
 
     # add assignedto(s) to the nosy list
-    if newvalues.has_key('assignedto'):
+    if newvalues.has_key('assignedto') and newvalues['assignedto'] is not None:
         propdef = cl.getprops()
         if isinstance(propdef['assignedto'], hyperdb.Link):
             assignedto_ids = [newvalues['assignedto']]
@@ -141,6 +141,18 @@ def init(db):
 
 #
 #$Log: not supported by cvs2svn $
+#Revision 1.12  2002/05/29 01:16:17  richard
+#Sorry about this huge checkin! It's fixing a lot of related stuff in one go
+#though.
+#
+#. #541941 ] changing multilink properties by mail
+#. #526730 ] search for messages capability
+#. #505180 ] split MailGW.handle_Message
+#  - also changed cgi client since it was duplicating the functionality
+#. build htmlbase if tests are run using CVS checkout (removed note from
+#  installation.txt)
+#. don't create an empty message on email issue creation if the email is empty
+#
 #Revision 1.11  2002/01/14 22:21:38  richard
 ##503353 ] setting properties in initial email
 #
index d1796720c7835bb7e03420610ce4f26f5b3d3876..a7aa3c0b28d1b31129ae458185c32cdd0fadc812 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: test_db.py,v 1.38 2002-07-26 08:27:00 richard Exp $ 
+# $Id: test_db.py,v 1.39 2002-07-31 23:57:37 richard Exp $ 
 
 import unittest, os, shutil, time
 
@@ -90,12 +90,16 @@ class anydbmDBTestCase(MyTestCase):
         self.assertEqual(self.db.issue.get('2', 'title'), 'ham')
         self.db.commit()
         self.assertEqual(self.db.issue.get('2', 'title'), 'ham')
+        self.db.issue.set('1', title=None)
+        self.assertEqual(self.db.issue.get('1', "title"), None)
 
     def testLinkChange(self):
         self.db.issue.create(title="spam", status='1')
         self.assertEqual(self.db.issue.get('1', "status"), '1')
         self.db.issue.set('1', status='2')
         self.assertEqual(self.db.issue.get('1', "status"), '2')
+        self.db.issue.set('1', status=None)
+        self.assertEqual(self.db.issue.get('1', "status"), None)
 
     def testDateChange(self):
         self.db.issue.create(title="spam", status='1')
@@ -106,12 +110,16 @@ class anydbmDBTestCase(MyTestCase):
         self.assertNotEqual(a, b)
         self.assertNotEqual(b, date.Date('1970-1-1 00:00:00'))
         self.db.issue.set('1', deadline=date.Date())
+        self.db.issue.set('1', deadline=None)
+        self.assertEqual(self.db.issue.get('1', "deadline"), None)
 
     def testIntervalChange(self):
         self.db.issue.create(title="spam", status='1')
         a = self.db.issue.get('1', "foo")
         self.db.issue.set('1', foo=date.Interval('-1d'))
         self.assertNotEqual(self.db.issue.get('1', "foo"), a)
+        self.db.issue.set('1', foo=None)
+        self.assertEqual(self.db.issue.get('1', "foo"), None)
 
     def testBooleanChange(self):
         userid = self.db.user.create(username='foo', assignable=1)
@@ -121,6 +129,8 @@ class anydbmDBTestCase(MyTestCase):
         self.assertNotEqual(self.db.user.get(userid, 'assignable'), a)
         self.db.user.set(userid, assignable=0)
         self.db.user.set(userid, assignable=1)
+        self.db.user.set('1', assignable=None)
+        self.assertEqual(self.db.user.get('1', "assignable"), None)
 
     def testNumberChange(self):
         self.db.user.create(username='foo', age='1')
@@ -128,6 +138,8 @@ class anydbmDBTestCase(MyTestCase):
         self.db.user.set('1', age='3')
         self.assertNotEqual(self.db.user.get('1', 'age'), a)
         self.db.user.set('1', age='1.0')
+        self.db.user.set('1', age=None)
+        self.assertEqual(self.db.user.get('1', "age"), None)
 
     def testNewProperty(self):
         self.db.issue.create(title="spam", status='1')
@@ -576,7 +588,7 @@ def suite():
          unittest.makeSuite(anydbmDBTestCase, 'test'),
          unittest.makeSuite(anydbmReadOnlyDBTestCase, 'test')
     ]
-#    return unittest.TestSuite(l)
+    #return unittest.TestSuite(l)
 
     try:
         import bsddb
@@ -603,6 +615,11 @@ def suite():
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.38  2002/07/26 08:27:00  richard
+# Very close now. The cgi and mailgw now use the new security API. The two
+# templates have been migrated to that setup. Lots of unit tests. Still some
+# issue in the web form for editing Roles assigned to users.
+#
 # Revision 1.37  2002/07/25 07:14:06  richard
 # Bugger it. Here's the current shape of the new security implementation.
 # Still to do: