changeset 3151:6feac4fcf883

Various bug fixes. - fix handling of invalid date input [SF#1102165] - retain Boolean selections in edit error handling [SF#1101492] - fix bug in date editing in Metakit - fixed up date spec usage string - note python 2.3 requirement in announcement and installation docs
author Richard Jones <richard@users.sourceforge.net>
date Mon, 14 Feb 2005 00:06:55 +0000
parents d69c8f0f2afe
children fdcba2ef2673
files CHANGES.txt doc/announcement.txt roundup/backends/back_metakit.py roundup/cgi/templating.py roundup/date.py
diffstat 5 files changed, 46 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES.txt	Sun Feb 13 22:47:42 2005 +0000
+++ b/CHANGES.txt	Mon Feb 14 00:06:55 2005 +0000
@@ -17,6 +17,8 @@
   1119475)
 - better edit conflict handling (sf bug 1118790)
 - consistent text searching behaviour (AND everywhere) (sf bug 1101036)
+- fix handling of invalid date input (sf bug 1102165)
+- retain Boolean selections in edit error handling (sf bug 1101492)
 
 
 2005-01-13 0.8.0b2
@@ -88,6 +90,7 @@
 - quote full-text search text in URL generation
 - fixed problem migrating mysql databases
 - fix search_checkboxes macro (sf patch 1113828)
+- fix bug in date editing in Metakit
 
 
 2005-01-06 0.7.11
--- a/doc/announcement.txt	Sun Feb 13 22:47:42 2005 +0000
+++ b/doc/announcement.txt	Mon Feb 14 00:06:55 2005 +0000
@@ -4,18 +4,20 @@
 good work getting the i18n and new configuration components of this release
 going.
 
+Please note that Roundup now requires python 2.3 or later.
+
 Version 0.8 introduces far too many features to list here so I've put
 together a What's New page:
 
   http://roundup.sourceforge.net/doc-0.8/whatsnew-0.8.html
 
-This is a bugfix release, fixing:
+0.8b3 is a bugfix release, fixing:
 
 
 If you're upgrading from an older version of Roundup you *must* follow
 the "Software Upgrade" guidelines given in the maintenance documentation.
 
-Roundup requires python 2.1.3 or later for correct operation.
+Roundup requires python 2.3 or later for correct operation.
 
 To give Roundup a try, just download (see below), unpack and run::
 
--- a/roundup/backends/back_metakit.py	Sun Feb 13 22:47:42 2005 +0000
+++ b/roundup/backends/back_metakit.py	Mon Feb 14 00:06:55 2005 +0000
@@ -1,4 +1,4 @@
-# $Id: back_metakit.py,v 1.90 2005-02-13 22:37:00 richard Exp $
+# $Id: back_metakit.py,v 1.91 2005-02-14 00:06:55 richard Exp $
 '''Metakit backend for Roundup, originally by Gordon McMillan.
 
 Known Current Bugs:
@@ -771,7 +771,10 @@
                     setattr(row, key, 0)
                 else:
                     setattr(row, key, int(calendar.timegm(value.get_tuple())))
-                changes[key] = str(oldvalue)
+                if oldvalue is None:
+                    changes[key] = oldvalue
+                else:
+                    changes[key] = str(oldvalue)
                 propvalues[key] = str(value)
 
             elif isinstance(prop, hyperdb.Interval):
--- a/roundup/cgi/templating.py	Sun Feb 13 22:47:42 2005 +0000
+++ b/roundup/cgi/templating.py	Mon Feb 14 00:06:55 2005 +0000
@@ -935,8 +935,11 @@
                                 current[k] = old
 
                     elif isinstance(prop, hyperdb.Date) and args[k]:
-                        d = date.Date(args[k],
-                            translator=self._client).local(timezone)
+                        if args[k] is None:
+                            d = ''
+                        else:
+                            d = date.Date(args[k],
+                                translator=self._client).local(timezone)
                         cell.append('%s: %s'%(self._(k), str(d)))
                         if current.has_key(k):
                             cell[-1] += ' -> %s' % current[k]
@@ -1331,8 +1334,13 @@
         if not self.is_edit_ok():
             return self.plain()
 
-        checked = self._value and "checked" or ""
-        if self._value:
+        value = self._value
+        if isinstance(value, str) or isinstance(value, unicode):
+            value = value.strip().lower() in ('checked', 'yes', 'true',
+                'on', '1')
+
+        checked = value and "checked" or ""
+        if value:
             s = self.input(type="radio", name=self._formname, value="yes",
                 checked="checked")
             s += 'Yes'
@@ -1354,7 +1362,8 @@
             anonymous=0, offset=None):
         HTMLProperty.__init__(self, client, classname, nodeid, prop, name,
                 value, anonymous=anonymous)
-        if self._value:
+        if self._value and not (isinstance(self._value, str) or
+                isinstance(self._value, unicode)):
             self._value.setTranslator(self._client.translator)
         self._offset = offset
 
@@ -1410,7 +1419,9 @@
             else:
                 return self.pretty(format)
 
-        if self._value is None:
+        value = self._value
+
+        if value is None:
             if default is None:
                 raw_value = None
             else:
@@ -1424,12 +1435,16 @@
                     raise ValueError, _('default value for '
                         'DateHTMLProperty must be either DateHTMLProperty '
                         'or string date representation.')
+        elif isinstance(value, str) or isinstance(value, unicode):
+            # most likely erroneous input to be passed back to user
+            value = cgi.escape(str(value), 1)
+            return self.input(name=self._formname, value=value, size=size)
         else:
-            raw_value = self._value
+            raw_value = value
 
         if raw_value is None:
             value = ''
-        elif type(raw_value) is type(''):
+        elif isinstance(raw_value, str) or isinstance(raw_value, unicode):
             if format is self._marker:
                 value = raw_value
             else:
@@ -1632,8 +1647,8 @@
         options = linkcl.filter(None, conditions, sort_on, (None, None))
 
         # make sure we list the current value if it's retired
-        if self._value and self._value not in options:
-            options.insert(0, self._value)
+        if value and value not in options:
+            options.insert(0, value)
 
         for optionid in options:
             # get the option value, and if it's None use an empty string
@@ -1647,6 +1662,8 @@
             # figure the label
             if showid:
                 lab = '%s%s: %s'%(self._prop.classname, optionid, option)
+            elif not option:
+                lab = '%s%s'%(self._prop.classname, optionid)
             else:
                 lab = option
 
--- a/roundup/date.py	Sun Feb 13 22:47:42 2005 +0000
+++ b/roundup/date.py	Mon Feb 14 00:06:55 2005 +0000
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 #
-# $Id: date.py,v 1.78 2005-01-03 03:05:31 richard Exp $
+# $Id: date.py,v 1.79 2005-02-14 00:06:54 richard Exp $
 
 """Date, time and time interval handling.
 """
@@ -152,7 +152,6 @@
         except:
             raise ValueError, 'Unknown spec %r'%spec
 
-    usagespec='[yyyy]-[mm]-[dd].[H]H:MM[:SS.SSS][offset]'
     def set(self, spec, offset=0, date_re=re.compile(r'''
             ((?P<y>\d\d\d\d)([/-](?P<m>\d\d?)([/-](?P<d>\d\d?))?)? # yyyy[-mm[-dd]]
             |(?P<a>\d\d?)[/-](?P<b>\d\d?))?              # or mm-dd
@@ -177,7 +176,9 @@
         # not serialised data, try usual format
         m = date_re.match(spec)
         if m is None:
-            raise ValueError, self._('Not a date spec: %s') % self.usagespec
+            raise ValueError, self._('Not a date spec: '
+                '"yyyy-mm-dd", "mm-dd", "HH:MM", "HH:MM:SS" or '
+                '"yyyy-mm-dd.HH:MM:SS.SSS"')
 
         info = m.groupdict()
 
@@ -228,8 +229,9 @@
             try:
                 self.applyInterval(Interval(info['o'], allowdate=0))
             except ValueError:
-                raise ValueError, self._('%r not a date spec (%s)')%(spec,
-                    self.usagespec)
+                raise ValueError, self._('%r not a date / time spec '
+                    '"yyyy-mm-dd", "mm-dd", "HH:MM", "HH:MM:SS" or '
+                    '"yyyy-mm-dd.HH:MM:SS.SSS"')%(spec,)
 
     def addInterval(self, interval):
         ''' Add the interval to this date, returning the date tuple

Roundup Issue Tracker: http://roundup-tracker.org/