summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5e2c22e)
raw | patch | inline | side by side (parent: 5e2c22e)
author | kedder <kedder@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Tue, 22 Apr 2003 20:53:55 +0000 (20:53 +0000) | ||
committer | kedder <kedder@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Tue, 22 Apr 2003 20:53:55 +0000 (20:53 +0000) |
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1671 57a73879-2fb5-44c3-a270-3262357dd7e2
diff --git a/CHANGES.txt b/CHANGES.txt
index 81cd0e5d9b51c46f1535b1bfe9dae53019e967ea..7cb8e42901dd5c6de6358a51e9f9fcb53d8310c4 100644 (file)
--- a/CHANGES.txt
+++ b/CHANGES.txt
- HTML templating files now have a .html extension
- Roundup templates are now distributed much more sanely, allowing for
3rd-party templates.
+- extended date syntax to make range searches even more useful
Fixed:
- applied unicode patch. All data is stored in utf-8. Incoming messages
diff --git a/doc/user_guide.txt b/doc/user_guide.txt
index 8d945309daa5264e664f21f3d2d1e11a9391aada..b40b39fe26f9721a7898fa66f71c9e7f7da7b18a 100644 (file)
--- a/doc/user_guide.txt
+++ b/doc/user_guide.txt
User Guide
==========
-:Version: $Revision: 1.20 $
+:Version: $Revision: 1.21 $
.. contents::
1. English syntax::
- [[From] <value>][ To <value>]
+ [From <value>][To <value>]
Keywords "From" and "To" are case insensitive. Keyword "From" is optional.
2. "Geek" syntax::
- [<value>][; <value>]
+ [<value>];[<value>]
Either first or second ``<value>`` can be omitted in both syntaxes.
Other possible examples (consider local time is Sat Mar 8 22:07:48 2003)::
- >>> Range("from 2-12 to 4-2")
- <Range from 2003-02-12.00:00:00 to 2003-04-02.00:00:00>
-
- >>> Range("18:00 TO +2m")
- <Range from 2003-03-08.18:00:00 to 2003-05-08.20:07:48>
-
- >>> Range("12:00")
- <Range from 2003-03-08.12:00:00 to None>
-
- >>> Range("tO +3d")
- <Range from None to 2003-03-11.20:07:48>
-
- >>> Range("2002-11-10; 2002-12-12")
- <Range from 2002-11-10.00:00:00 to 2002-12-12.00:00:00>
-
- >>> Range("; 20:00 +1d")
- <Range from None to 2003-03-09.20:00:00>
+ >>> Range("from 2-12 to 4-2")
+ <Range from 2003-02-12.00:00:00 to 2003-04-02.00:00:00>
+
+ >>> Range("FROM 18:00 TO +2m")
+ <Range from 2003-03-08.18:00:00 to 2003-05-08.20:07:48>
+
+ >>> Range("12:00;")
+ <Range from 2003-03-08.12:00:00 to None>
+
+ >>> Range("tO +3d")
+ <Range from None to 2003-03-11.20:07:48>
+
+ >>> Range("2002-11-10; 2002-12-12")
+ <Range from 2002-11-10.00:00:00 to 2002-12-12.00:00:00>
+ >>> Range("; 20:00 +1d")
+ <Range from None to 2003-03-09.20:00:00>
+
+ >>> Range("2003")
+ <Range from 2003-01-01.00:00:00 to 2003-12-31.23:59:59>
+
+ >>> Range("2003-04")
+ <Range from 2003-04-01.00:00:00 to 2003-04-30.23:59:59>
+
Interval properties
~~~~~~~~~~~~~~~~~~~
-u -- the user[:password] to use for commands
-d -- print full designators not just class id numbers
-c -- when outputting lists of data, comma-separate them.
- Same as '-S ","'.
+ Same as '-S ","'.
-S <string> -- when outputting lists of data, string-separate them
-s -- when outputting lists of data, space-separate them.
- Same as '-S " "'.
+ Same as '-S " "'.
Only one of -s, -c or -S can be specified.
"11-07.09:32:43" yyyy-11-07.14:32:43
"14:25" yyyy-mm-dd.19:25:00
"8:47:11" yyyy-mm-dd.13:47:11
+ "2003" 2003-01-01.00:00:00
+ "2003-04" 2003-04-01.00:00:00
"." "right now"
- Link values are printed as item designators. When given as an argument,
or status::
shell% roundup-admin get name `/tools/roundup/bin/roundup-admin \
- -dc -i /var/roundup/sysadmin get status issue3,issue1`
+ -dc -i /var/roundup/sysadmin get status issue3,issue1`
unread
deferred
Also the tautological::
shell% roundup-admin get name \
- `roundup-admin -dc get status \`roundup-admin -dc find issue \
+ `roundup-admin -dc get status \`roundup-admin -dc find issue \
status=chatting\``
chatting
chatting
index 670a0aff0267b61202f62a0d22b85b4e3686c257..8299415e12658d3cb1b88178b958bbfc710b443a 100644 (file)
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-#$Id: back_anydbm.py,v 1.119 2003-04-20 11:58:45 kedder Exp $
+#$Id: back_anydbm.py,v 1.120 2003-04-22 20:53:54 kedder 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
elif t == DATE or t == INTERVAL:
if node[k] is None: break
if v.to_value:
- if not (v.from_value < node[k] and v.to_value > node[k]):
+ if not (v.from_value <= node[k] and v.to_value >= node[k]):
break
else:
- if not (v.from_value < node[k]):
+ if not (v.from_value <= node[k]):
break
elif t == OTHER:
# straight value comparison for the other types
index 454fe3e3acd459bd906cc441ceb4c67bdbc87cba..2d4a67a1cc2d9c2a5f64c49b46dfa9232c2f306f 100644 (file)
-# $Id: rdbms_common.py,v 1.54 2003-04-20 11:58:45 kedder Exp $
+# $Id: rdbms_common.py,v 1.55 2003-04-22 20:53:54 kedder Exp $
''' Relational database (SQL) backend common code.
Basics:
# Try to filter on range of dates
date_rng = Range(v, date.Date, offset=timezone)
if (date_rng.from_value):
- where.append('_%s > %s'%(k, a))
+ where.append('_%s >= %s'%(k, a))
args.append(date_rng.from_value.serialise())
if (date_rng.to_value):
- where.append('_%s < %s'%(k, a))
+ where.append('_%s <= %s'%(k, a))
args.append(date_rng.to_value.serialise())
except ValueError:
# If range creation fails - ignore that search parameter
# Try to filter on range of intervals
date_rng = Range(v, date.Interval)
if (date_rng.from_value):
- where.append('_%s > %s'%(k, a))
+ where.append('_%s >= %s'%(k, a))
args.append(date_rng.from_value.serialise())
if (date_rng.to_value):
- where.append('_%s < %s'%(k, a))
+ where.append('_%s <= %s'%(k, a))
args.append(date_rng.to_value.serialise())
except ValueError:
# If range creation fails - ignore that search parameter
diff --git a/roundup/date.py b/roundup/date.py
index 95777a33b4ca27eceb5506558576c46e1b1f60ab..2a543cdd69788103640d14d06b03f1b424c7bd2d 100644 (file)
--- a/roundup/date.py
+++ b/roundup/date.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: date.py,v 1.52 2003-04-21 14:29:39 kedder Exp $
+# $Id: date.py,v 1.53 2003-04-22 20:53:54 kedder Exp $
__doc__ = """
Date, time and time interval handling.
"11-07.09:32:43" means <Date yyyy-11-07.14:32:43>
"14:25" means <Date yyyy-mm-dd.19:25:00>
"8:47:11" means <Date yyyy-mm-dd.13:47:11>
+ "2003" means <Date 2003-01-01.00:00:00>
+ "2003-06" means <Date 2003-06-01.00:00:00>
"." means "right now"
The Date class should understand simple date expressions of the form
minute, second) is the serialisation format returned by the serialise()
method, and is accepted as an argument on instatiation.
'''
+
def __init__(self, spec='.', offset=0, add_granularity=0):
"""Construct a date given a specification and a time zone offset.
self.year, self.month, self.day, self.hour, self.minute, \
self.second, x, x, x = time.gmtime(ts)
+ usagespec='[yyyy]-[mm]-[dd].[H]H:MM[:SS][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<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
(?P<n>\.)? # .
(((?P<H>\d?\d):(?P<M>\d\d))?(:(?P<S>\d\d))?)? # hh:mm:ss
(?P<o>.+)? # offset
# not serialised data, try usual format
m = date_re.match(spec)
if m is None:
- raise ValueError, _('Not a date spec: [[yyyy-]mm-dd].'
- '[[h]h:mm[:ss]][offset]')
+ raise ValueError, _('Not a date spec: %s' % self.usagespec)
info = m.groupdict()
if add_granularity:
- _add_granularity(info, 'SMHdmy')
+ _add_granularity(info, 'SMHdmyab')
# get the current date as our default
y,m,d,H,M,S,x,x,x = time.gmtime(time.time())
- # override year, month, day parts
- if info['m'] is not None and info['d'] is not None:
- m = int(info['m'])
- d = int(info['d'])
+ if info['y'] is not None or info['a'] is not None:
if info['y'] is not None:
y = int(info['y'])
- # time defaults to 00:00:00 GMT - offset (local midnight)
+ m,d = (1,1)
+ if info['m'] is not None:
+ m = int(info['m'])
+ if info['d'] is not None:
+ d = int(info['d'])
+ if info['a'] is not None:
+ m = int(info['a'])
+ d = int(info['b'])
H = -offset
M = S = 0
try:
self.applyInterval(Interval(info['o'], allowdate=0))
except ValueError:
- raise ValueError, _('Not a date spec: [[yyyy-]mm-dd].'
- '[[h]h:mm[:ss]][offset]')
+ raise ValueError, _('Not a date spec: %s' % self.usagespec)
def addInterval(self, interval):
''' Add the interval to this date, returning the date tuple
diff --git a/test/test_dates.py b/test/test_dates.py
index 54a4857089ae4ac3043b219ca9803cc7ba2ac919..69c1f4e9263c1dcfc740fbc2a023ca02b5bd3ee5 100644 (file)
--- a/test/test_dates.py
+++ b/test/test_dates.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: test_dates.py,v 1.23 2003-04-21 14:29:40 kedder Exp $
+# $Id: test_dates.py,v 1.24 2003-04-22 20:53:54 kedder Exp $
import unittest, time
ae(str(date), '%s-%02d-%02d.14:25:00'%(y, m, d))
date = Date("8:47:11")
ae(str(date), '%s-%02d-%02d.08:47:11'%(y, m, d))
+ ae(str(Date('2003')), '2003-01-01.00:00:00')
+ ae(str(Date('2004-06')), '2004-06-01.00:00:00')
def testDateError(self):
self.assertRaises(ValueError, Date, "12")
ae = self.assertEqual
ae(str(Date('2003-2-12', add_granularity=1)), '2003-02-12.23:59:59')
ae(str(Date('2003-1-1.23:00', add_granularity=1)), '2003-01-01.23:00:59')
+ ae(str(Date('2003', add_granularity=1)), '2003-12-31.23:59:59')
+ ae(str(Date('2003-5', add_granularity=1)), '2003-05-31.23:59:59')
ae(str(Interval('+1w', add_granularity=1)), '+ 14d')
ae(str(Interval('-2m 3w', add_granularity=1)), '- 2m 14d')
diff --git a/test/test_db.py b/test/test_db.py
index 8fc18d4b2e43a2708f1494d103a52096331c6936..da9f3c7fdbbdb9c907125deec9e5282bf7bf84dc 100644 (file)
--- a/test/test_db.py
+++ b/test/test_db.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: test_db.py,v 1.87 2003-04-21 22:38:48 richard Exp $
+# $Id: test_db.py,v 1.88 2003-04-22 20:53:55 kedder Exp $
import unittest, os, shutil, time
ae(filt(None, {'deadline': 'from 2003-02-16'}), ['2', '3', '4'])
ae(filt(None, {'deadline': '2003-02-16;'}), ['2', '3', '4'])
# year and month granularity
+ ae(filt(None, {'deadline': '2002'}), [])
ae(filt(None, {'deadline': '2003'}), ['1', '2', '3'])
ae(filt(None, {'deadline': '2004'}), ['4'])
ae(filt(None, {'deadline': '2003-02'}), ['2', '3'])
ae(filt(None, {'foo': 'from 0:50 to 2:00'}), ['1'])
ae(filt(None, {'foo': 'from 0:50 to 1d 2:00'}), ['1', '2'])
ae(filt(None, {'foo': 'from 5:50'}), ['2'])
- ae(filt(None, {'foo': 'to 0:50'}), [])
+ ae(filt(None, {'foo': 'to 0:05'}), [])
def testFilteringIntervalSort(self):
ae, filt = self.filteringSetup()