summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d7e90ae)
raw | patch | inline | side by side (parent: d7e90ae)
author | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Thu, 6 Feb 2003 05:43:49 +0000 (05:43 +0000) | ||
committer | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Thu, 6 Feb 2003 05:43:49 +0000 (05:43 +0000) |
- fixed templating filter function arguments (sf bug 678911)
- fixed multiselect in searching (sf bug 676874)
- fixed parsing of content-disposition filenames (sf bug 675116)
- added 'h' to roundup-server optarg list (sf bug 674070)
- fixed doc for db.history in anydbm and rdbms_common (sf bug 679221)
- fixed timelog example so it handles new issues (sf bug 678908)
- handle missing os.fork() (sf bug 681046)
- fixed roundup-reminder (sf bug 681042)
- fixed int assumptions about Number values (sf bug 677762)
- added warning filter for "FutureWarning: hex/oct constants > sys.maxint will
return positive values..." (literal 0xffff0000 in portalocker.py)
- fixed ZPT code generating SyntaxWarning for assignment to None
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1487 57a73879-2fb5-44c3-a270-3262357dd7e2
- fixed multiselect in searching (sf bug 676874)
- fixed parsing of content-disposition filenames (sf bug 675116)
- added 'h' to roundup-server optarg list (sf bug 674070)
- fixed doc for db.history in anydbm and rdbms_common (sf bug 679221)
- fixed timelog example so it handles new issues (sf bug 678908)
- handle missing os.fork() (sf bug 681046)
- fixed roundup-reminder (sf bug 681042)
- fixed int assumptions about Number values (sf bug 677762)
- added warning filter for "FutureWarning: hex/oct constants > sys.maxint will
return positive values..." (literal 0xffff0000 in portalocker.py)
- fixed ZPT code generating SyntaxWarning for assignment to None
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1487 57a73879-2fb5-44c3-a270-3262357dd7e2
17 files changed:
diff --git a/CHANGES.txt b/CHANGES.txt
index 07990c7704ec1c658c9eae4a1001a553a698f445..937b7a5ed7cdc10a1b56b98ef0a85085c6f4fd95 100644 (file)
--- a/CHANGES.txt
+++ b/CHANGES.txt
- more proper sorting/grouping on mulitilink properties. Sorting is performed
not only by number of links, but also by links itself. This makes usable
grouping e.g. by topic multilink
-
-2003-??-?? 0.5.5
-- fixed rdbms searching by ID (sf bug 666615)
-- detect corrupted index and raise semi-useful exception (sf bug 666767)
-- open server logfile unbuffered
-- revert StringHTMLProperty to not hyperlink text by default
+- fixed templating filter function arguments (sf bug 678911)
+- fixed multiselect in searching (sf bug 676874)
+- fixed parsing of content-disposition filenames (sf bug 675116)
+- added 'h' to roundup-server optarg list (sf bug 674070)
+- fixed doc for db.history in anydbm and rdbms_common (sf bug 679221)
+- fixed timelog example so it handles new issues (sf bug 678908)
+- handle missing os.fork() (sf bug 681046)
+- fixed roundup-reminder (sf bug 681042)
+- fixed int assumptions about Number values (sf bug 677762)
+- added warning filter for "FutureWarning: hex/oct constants > sys.maxint will
+ return positive values..." (literal 0xffff0000 in portalocker.py)
+- fixed ZPT code generating SyntaxWarning for assignment to None
+
+
+2003-??-?? 0.5.6
+- changes appear in 0.6.0
+
+2003-01-24 0.5.5
+- changes appear in 0.6.0
2003-01-10 0.5.4
diff --git a/COPYING.txt b/COPYING.txt
index f518e8a1753d1a7a7f6ce1bc41311b82e9db8df6..0f06922c74cc956d39bc6a6f31beec96d6d48d22 100644 (file)
--- a/COPYING.txt
+++ b/COPYING.txt
+Roundup Licensing
+-----------------
+
Copyright (c) 2002 eKit.com Inc (http://www.ekit.com/)
Permission is hereby granted, free of charge, to any person obtaining a copy
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+
Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
This module is free software, and you may redistribute it and/or modify
-under the same terms as Python, so long as this copyright message and
-disclaimer are retained in their original form.
+under the same terms as Python 2.1 (the PSF LICENSE AGREEMENT), so long
+as this copyright message and disclaimer are retained in their original form.
IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-The stylesheet included with this package has been copied from the Zope
-management interface and presumably belongs to Digital Creations.
+
+PageTemplates Licensing
+-----------------------
+
+Portions of this code (roundup.cgi.PageTemplates, roundup.cgi.TAL and
+roundup.cgi.ZTUtils) have been copied from Zope. They have been modified in
+the following manner:
+
+- removal of unit tests, Zope-specific code and support files from
+ PageTemplates: PageTemplateFile.py, ZPythonExpr.py, ZRPythonExpr.py,
+ ZopePageTemplate.py, examples, help, tests, CHANGES.txt, HISTORY.txt,
+ version.txt and www. From TAL: DummyEngine.py, HISTORY.txt, CHANGES.txt,
+ benchmark, driver.py, markbench.py, ndiff.py, runtest.py, setpath.py,
+ tests and timer.py. From ZTUtils: SimpleTree.py, Zope.py, CHANGES.txt and
+ HISTORY.txt.
+- editing to remove dependencies on Zope modules (see files for change notes)
+
+The license for this code is in doc/ZPL.txt.
diff --git a/README.txt b/README.txt
index 808be60a4a0ecd75868012bfa756ac55fb0f51de..3a4e8337b806c632b1862cc1c068c0307ba8c299 100644 (file)
--- a/README.txt
+++ b/README.txt
License
=======
-Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
-This module is free software, and you may redistribute it and/or modify
-under the same terms as Python, so long as this copyright message and
-disclaimer are retained in their original form.
-
-IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
-DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OF THIS CODE, EVEN IF BIZAR SOFTWARE PTY LTD HAS BEEN ADVISED
-OF THE POSSIBILITY OF SUCH DAMAGE.
-
-BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
-BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
-SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
-
-
-PageTemplates Licensing
------------------------
-
-Portions of this code (roundup.cgi.PageTemplates, roundup.cgi.TAL and
-roundup.cgi.ZTUtils) have been copied from Zope. They have been modified in
-the following manner:
-
-- removal of unit tests, Zope-specific code and support files from
- PageTemplates: PageTemplateFile.py, ZPythonExpr.py, ZRPythonExpr.py,
- ZopePageTemplate.py, examples, help, tests, CHANGES.txt, HISTORY.txt,
- version.txt and www. From TAL: DummyEngine.py, HISTORY.txt, CHANGES.txt,
- benchmark, driver.py, markbench.py, ndiff.py, runtest.py, setpath.py,
- tests and timer.py. From ZTUtils: SimpleTree.py, Zope.py, CHANGES.txt and
- HISTORY.txt.
-- editing to remove dependencies on Zope modules (see files for change notes)
-
-The license for this code is in doc/ZPL.txt.
+See COPYING.txt
diff --git a/doc/customizing.txt b/doc/customizing.txt
index eb6b8adceeed1c70a49388a0f576c9aea12d2d35..a1b46ac3172f61e75c3bedf0cab5843160cf18f0 100644 (file)
--- a/doc/customizing.txt
+++ b/doc/customizing.txt
Customising Roundup
===================
-:Version: $Revision: 1.72 $
+:Version: $Revision: 1.73 $
.. This document borrows from the ZopeBook section on ZPT. The original is at:
http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx
'''
actions = client.Client.actions + (
('edit_with_timelog', 'timelogEditAction'),
+ ('new_with_timelog', 'timelogEditAction'),
)
def timelogEditAction(self):
self.form.list.append(MiniFieldStorage('times', entry))
# punt to the normal edit action
- return self.editItemAction()
+ if self.nodeid:
+ return self.editItemAction()
+ else:
+ return self.newItemAction()
you add this code to your Client class in your tracker's ``interfaces.py``
file. Locate the section that looks like::
<input type="submit" name="submit" value="Submit Changes">
</tal:block>
<tal:block tal:condition="not:context/id">
- <input type="hidden" name=":action" value="new">
+ <input type="hidden" name=":action" value="new_with_timelog">
<input type="submit" name="submit" value="Submit New Issue">
</tal:block>
</td>
</tr>
The important change is setting the action to "edit_with_timelog" for
- edit operations (where the item exists)
+ edit operations (where the item exists) and "new_with_timelog" for
+ creations operations.
6. We want to display a total of the time log times that have been accumulated
for an issue. To do this, we'll need to actually write some Python code,
diff --git a/doc/index.txt b/doc/index.txt
index 4774962267d4786889f4c6d2b92479498e802c81..37ad702e7cb1464680ede6cde5897f9586ff8326 100644 (file)
--- a/doc/index.txt
+++ b/doc/index.txt
Seb Brezel,
Titus Brown,
Roch'e Compaan,
+Hernan Martinez Foffani,
Engelbert Gruber,
Juergen Hermann,
Tobias Hunger,
diff --git a/roundup/admin.py b/roundup/admin.py
index 88cbace2c8e6e3bb253a4d1ec896c38eadd70d07..8dfde0d0d23bf70579f6a0cde1412a970a825169 100644 (file)
--- a/roundup/admin.py
+++ b/roundup/admin.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: admin.py,v 1.35 2002-10-03 06:56:28 richard Exp $
+# $Id: admin.py,v 1.36 2003-02-06 05:43:47 richard Exp $
'''Administration commands for maintaining Roundup trackers.
'''
elif isinstance(proptype, hyperdb.Boolean):
props[key] = value.lower() in ('yes', 'true', 'on', '1')
elif isinstance(proptype, hyperdb.Number):
- props[key] = int(value)
+ props[key] = float(value)
# try the set
try:
elif isinstance(proptype, hyperdb.Boolean):
props[propname] = value.lower() in ('yes', 'true', 'on', '1')
elif isinstance(proptype, hyperdb.Number):
- props[propname] = int(value)
+ props[propname] = float(value)
# check for the key property
propname = cl.getkey()
index c106f2f2292a715e5dc5b0f9688a54402956bd2a..681698b389d29fe04aef13b101c938d224745e18 100644 (file)
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-#$Id: back_anydbm.py,v 1.99 2003-02-03 11:14:16 kedder Exp $
+#$Id: back_anydbm.py,v 1.100 2003-02-06 05:43:47 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
The returned list contains tuples of the form
- (date, tag, action, params)
+ (nodeid, date, tag, action, params)
'date' is a Timestamp object specifying the time of the change and
'tag' is the journaltag specified when the database was opened.
index 6c64618a1a0960106f9e3a4efd53d0ba877ccd16..634c14c79aee0fb57dfb713fe913db56931fb8bd 100644 (file)
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
-# $Id: locking.py,v 1.2 2002-09-10 00:11:50 richard Exp $
+# $Id: locking.py,v 1.3 2003-02-06 05:43:47 richard Exp $
'''This module provides a generic interface to acquire and release
exclusive access to a file.
It should work on Unix and Windows.
'''
+import warnings
+warnings.filterwarnings("ignore",
+ r'hex/oct constants > sys\.maxint .*', FutureWarning,
+ 'portalocker', 0)
+
import portalocker
def acquire_lock(path, block=1):
index 30fd3712fe5221a99941bf3c842fbcba1e3d1d20..002f5a721fceaac5f8901343d8bca066fa6873e6 100644 (file)
-# $Id: rdbms_common.py,v 1.29 2003-01-15 22:17:19 kedder Exp $
+# $Id: rdbms_common.py,v 1.30 2003-02-06 05:43:47 richard Exp $
''' Relational database (SQL) backend common code.
Basics:
The returned list contains tuples of the form
- (date, tag, action, params)
+ (nodeid, date, tag, action, params)
'date' is a Timestamp object specifying the time of the change and
'tag' is the journaltag specified when the database was opened.
index 229064c79400243730bf00e90245906fba84e843..ef1343663370d77eea8fe4e6c8c67659bd432635 100644 (file)
- changed imports to import from roundup.cgi
"""
-__version__='$Revision: 1.4 $'[11:-2]
+__version__='$Revision: 1.5 $'[11:-2]
import re, sys
from roundup.cgi import ZTUtils
evaluateValue = evaluate
evaluateBoolean = evaluate
- def evaluateText(self, expr, None=None):
+ def evaluateText(self, expr):
text = self.evaluate(expr)
if text is Default or text is None:
return text
index be6d11e6b85f6b67f8349cf4e2ddd451cf05c63e..341b8612b378899ed47a02ad34662eb7ff8b1a7a 100644 (file)
bytecode_handlers = {}
- def interpret(self, program, None=None):
+ def interpret(self, program):
oldlevel = self.level
self.level = oldlevel + 1
handlers = self.dispatch
diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py
index 108e52cf4a425b42fbb2811dbf26c897beb4dbe4..aa9a3a6cd84537e11513cd9e293ad33c4c470cd0 100644 (file)
--- a/roundup/cgi/client.py
+++ b/roundup/cgi/client.py
-# $Id: client.py,v 1.75 2003-02-03 00:01:44 richard Exp $
+# $Id: client.py,v 1.76 2003-02-06 05:43:47 richard Exp $
__doc__ = """
WWW request handler (also used in the stand-alone server).
props = self.db.classes[self.classname].getprops()
for key in self.form.keys():
if not props.has_key(key): continue
- if not self.form[key].value: continue
+ if isinstance(self.form[key], type([])):
+ # search for at least one entry which is not empty
+ for minifield in self.form[key]:
+ if minifield.value:
+ break
+ else:
+ continue
+ else:
+ if not self.form[key].value: continue
self.form.value.append(cgi.MiniFieldStorage(':filter', key))
# handle saving the query params
elif isinstance(proptype, hyperdb.Boolean):
value = value.lower() in ('yes', 'true', 'on', '1')
elif isinstance(proptype, hyperdb.Number):
- value = int(value)
+ value = float(value)
else:
# if we're creating, just don't include this property
if not nodeid:
index 145b3b68b66265c13bb97dc9755f6eb540d7642b..d69f68e937d14dcc65d6441c220da82dde05417d 100644 (file)
filterspec = request.filterspec
sort = request.sort
group = request.group
+ else:
+ filterspec = {}
+ sort = (None,None)
+ group = (None,None)
if self.classname == 'user':
klass = HTMLUser
else:
diff --git a/roundup/mailgw.py b/roundup/mailgw.py
index 962d9b865e379772c49f1c53a9dc84d4512e8a0c..83ccce00001ae06cace065da72202e2629b930ee 100644 (file)
--- a/roundup/mailgw.py
+++ b/roundup/mailgw.py
an exception, the original message is bounced back to the sender with the
explanatory message given in the exception.
-$Id: mailgw.py,v 1.108 2003-01-27 16:32:46 kedder Exp $
+$Id: mailgw.py,v 1.109 2003-02-06 05:43:47 richard Exp $
'''
import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri
import time, random, sys
-import traceback, MimeWriter
+import traceback, MimeWriter, rfc822
import hyperdb, date, password
import rfc2822
description="User may use the email interface")
security.addPermissionToRole('Admin', p)
+def getparam(str, param):
+ ''' From the rfc822 "header" string, extract "param" if it appears.
+ '''
+ if ';' not in str:
+ return None
+ str = str[str.index(';'):]
+ while str[:1] == ';':
+ str = str[1:]
+ if ';' in str:
+ # XXX Should parse quotes!
+ end = str.index(';')
+ else:
+ end = len(str)
+ f = str[:end]
+ if '=' in f:
+ i = f.index('=')
+ if f[:i].strip().lower() == param:
+ return rfc822.unquote(f[i+1:].strip())
+ return None
+
class Message(mimetools.Message):
''' subclass mimetools.Message so we can retrieve the parts of the
message...
elif subtype == 'multipart/alternative':
# Search for text/plain in message with attachment and
# alternative text representation
+ # skip over intro to first boundary
part.getPart()
while 1:
# get the next part
if not name:
disp = part.getheader('content-disposition', None)
if disp:
- name = disp.getparam('filename')
+ name = getparam(disp, 'filename')
if name:
name = name.strip()
# this is just an attachment
props[propname] = value.lower() in ('yes', 'true', 'on', '1')
elif isinstance(proptype, hyperdb.Number):
value = value.strip()
- props[propname] = int(value)
+ props[propname] = float(value)
return errors, props
index 9f3a26a2c0248e587aa8aec165ebb25717086c57..afe9d5edead6b4c96705337df4dee7a33af33a70 100644 (file)
#
""" HTTP Server that serves roundup.
-$Id: roundup_server.py,v 1.17 2003-01-13 02:44:42 richard Exp $
+$Id: roundup_server.py,v 1.18 2003-02-06 05:43:49 richard Exp $
"""
# python version check
try:
# handle the command-line args
try:
- optlist, args = getopt.getopt(sys.argv[1:], 'n:p:u:d:l:')
+ optlist, args = getopt.getopt(sys.argv[1:], 'n:p:u:d:l:h')
except getopt.GetoptError, e:
usage(str(e))
# fork?
if pidfile:
+ if not hasattr(os, 'fork'):
+ print "Sorry, you can't run the server as a daemon on this" \
+ 'Operating System'
+ sys.exit(0)
daemonize(pidfile)
# redirect stdout/stderr to our logfile
index 8bc9576a6e6a9c098d5ad54576cd0b40905beff3..733d233a8f4b4d0fb792009ef30b1ce01e613f7c 100755 (executable)
--- a/scripts/roundup-reminder
+++ b/scripts/roundup-reminder
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
-# $Id: roundup-reminder,v 1.4 2002-09-10 03:01:19 richard Exp $
+# $Id: roundup-reminder,v 1.5 2003-02-06 05:43:49 richard Exp $
'''
Simple script that emails all users of a tracker with the issues that
You will want to modify this script to customise it for your own schema!
'''
-import cStringIO, MimeWriter, smtplib
+import sys, cStringIO, MimeWriter, smtplib
from roundup import instance, date
# open the instance
creation = creation_date.pretty()
if not timeliness_id: timeliness_id = ' '
title = db.issue.get(issue_id, 'title')
- issue_id = '<a href="%sissue%s">%s</a>'%(db.config.ISSUE_TRACKER_WEB,
+ issue_id = '<a href="%sissue%s">%s</a>'%(db.config.TRACKER_WEB,
issue_id, issue_id)
colour = colours.get(timeliness, '')
print >>body, '''<tr%s><td>%s</td><td>%s</td><td>%s</td>
diff --git a/test/test_mailgw.py b/test/test_mailgw.py
index 5fed0029dc83f2217b1a48cad58741b589f7f589..a2785ea3ca01dee9d25740595c50c522376fe8e4 100644 (file)
--- a/test/test_mailgw.py
+++ b/test/test_mailgw.py
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
-# $Id: test_mailgw.py,v 1.38 2003-01-15 22:17:20 kedder Exp $
+# $Id: test_mailgw.py,v 1.39 2003-02-06 05:43:49 richard Exp $
import unittest, cStringIO, tempfile, os, shutil, errno, imp, sys, difflib
_______________________________________________________________________
''')
+ def testContentDisposition(self):
+ self.doNewIssue()
+ message = cStringIO.StringIO('''Content-Type: text/plain;
+ charset="iso-8859-1"
+From: mary <mary@test>
+To: issue_tracker@your.tracker.email.domain.example
+Message-Id: <followup_dummy_id>
+In-Reply-To: <dummy_test_message_id>
+Subject: [issue1] Testing...
+Content-Type: multipart/mixed; boundary="bCsyhTFzCvuiizWE"
+Content-Disposition: inline
+
+
+--bCsyhTFzCvuiizWE
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+
+test attachment binary
+
+--bCsyhTFzCvuiizWE
+Content-Type: application/octet-stream
+Content-Disposition: attachment; filename="main.dvi"
+
+xxxxxx
+
+--bCsyhTFzCvuiizWE--
+''')
+ handler = self.instance.MailGW(self.instance, self.db)
+ handler.trapExceptions = 0
+ handler.main(message)
+ messages = self.db.issue.get('1', 'messages')
+ messages.sort()
+ file = self.db.msg.get(messages[-1], 'files')[0]
+ self.assertEqual(self.db.file.get(file, 'name'), 'main.dvi')
+
def testFollowupStupidQuoting(self):
self.doNewIssue()