diff --git a/roundup/cgi_client.py b/roundup/cgi_client.py
index f47da62d77a86f9021a51876b66140cf4897a613..86177bb6b257e0978b35d5d4970cb982d5e404f7 100644 (file)
--- a/roundup/cgi_client.py
+++ b/roundup/cgi_client.py
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: cgi_client.py,v 1.83 2001-12-15 23:51:01 richard Exp $
+# $Id: cgi_client.py,v 1.90 2002-01-08 03:56:55 richard Exp $
__doc__ = """
WWW request handler (also used in the stand-alone server).
"""
import os, cgi, pprint, StringIO, urlparse, re, traceback, mimetypes
__doc__ = """
WWW request handler (also used in the stand-alone server).
"""
import os, cgi, pprint, StringIO, urlparse, re, traceback, mimetypes
-import binascii, Cookie, time
+import binascii, Cookie, time, random
import roundupdb, htmltemplate, date, hyperdb, password
from roundup.i18n import _
import roundupdb, htmltemplate, date, hyperdb, password
from roundup.i18n import _
user_name = self.user or ''
if self.user == 'admin':
admin_links = _(' | <a href="list_classes">Class List</a>' \
user_name = self.user or ''
if self.user == 'admin':
admin_links = _(' | <a href="list_classes">Class List</a>' \
- ' | <a href="user">User List</a>')
+ ' | <a href="user">User List</a>' \
+ ' | <a href="newuser">Add User</a>')
else:
admin_links = ''
if self.user not in (None, 'anonymous'):
else:
admin_links = ''
if self.user not in (None, 'anonymous'):
if self.user is not None:
add_links = _('''
| Add
if self.user is not None:
add_links = _('''
| Add
-<a href="newissue">Issue</a>,
-<a href="newuser">User</a>
+<a href="newissue">Issue</a>
''')
else:
add_links = ''
''')
else:
add_links = ''
showissue = shownode
showmsg = shownode
showissue = shownode
showmsg = shownode
+ def _add_assignedto_to_nosy(self, props):
+ ''' add the assignedto value from the props to the nosy list
+ '''
+ if not props.has_key('assignedto'):
+ return
+ assignedto_id = props['assignedto']
+ if props.has_key('nosy') and assignedto_id not in props['nosy']:
+ props['nosy'].append(assignedto_id)
+ else:
+ props['nosy'] = cl.get(self.nodeid, 'nosy')
+ props['nosy'].append(assignedto_id)
+
def _changenode(self, props):
''' change the node based on the contents of the form
'''
def _changenode(self, props):
''' change the node based on the contents of the form
'''
unread_id = self.db.status.lookup('unread')
resolved_id = self.db.status.lookup('resolved')
chatting_id = self.db.status.lookup('chatting')
unread_id = self.db.status.lookup('unread')
resolved_id = self.db.status.lookup('resolved')
chatting_id = self.db.status.lookup('chatting')
+ current_status = cl.get(self.nodeid, 'status')
+ if props.has_key('status'):
+ new_status = props['status']
+ else:
+ # apparently there's a chance that some browsers don't
+ # send status...
+ new_status = current_status
except KeyError:
pass
else:
except KeyError:
pass
else:
- if (props['status'] == unread_id or props['status'] == resolved_id):
+ if new_status == unread_id or (new_status == resolved_id
+ and current_status == resolved_id):
props['status'] = chatting_id
props['status'] = chatting_id
- # add assignedto to the nosy list
- if props.has_key('assignedto'):
- assignedto_id = props['assignedto']
- if assignedto_id not in props['nosy']:
- props['nosy'].append(assignedto_id)
+
+ self._add_assignedto_to_nosy(props)
+
# create the message
message, files = self._handle_message()
if message:
# create the message
message, files = self._handle_message()
if message:
pass
else:
props['status'] = unread_id
pass
else:
props['status'] = unread_id
- # add assignedto to the nosy list
- if props.has_key('assignedto'):
- assignedto_id = props['assignedto']
- if props.has_key('nosy') and assignedto_id not in props['nosy']:
- props['nosy'].append(assignedto_id)
- else:
- props['nosy'] = [assignedto_id]
+
+ self._add_assignedto_to_nosy(props)
+
# check for messages and files
message, files = self._handle_message()
if message:
# check for messages and files
message, files = self._handle_message()
if message:
if self.form.has_key('__file'):
file = self.form['__file']
if file.filename:
if self.form.has_key('__file'):
file = self.form['__file']
if file.filename:
- mime_type = mimetypes.guess_type(file.filename)[0]
+ filename = file.filename.split('\\')[-1]
+ mime_type = mimetypes.guess_type(filename)[0]
if not mime_type:
mime_type = "application/octet-stream"
# create the new file entry
files.append(self.db.file.create(type=mime_type,
if not mime_type:
mime_type = "application/octet-stream"
# create the new file entry
files.append(self.db.file.create(type=mime_type,
- name=file.filename, content=file.file.read()))
+ name=filename, content=file.file.read()))
# we don't want to do a message if none of the following is true...
cn = self.classname
# we don't want to do a message if none of the following is true...
cn = self.classname
props = cl.getprops()
note = None
# in a nutshell, don't do anything if there's no note or there's no
props = cl.getprops()
note = None
# in a nutshell, don't do anything if there's no note or there's no
- # nosy
+ # NOSY
if self.form.has_key('__note'):
note = self.form['__note'].value
if not props.has_key('messages'):
if self.form.has_key('__note'):
note = self.form['__note'].value
if not props.has_key('messages'):
# don't generate a useless message
return None, files
# don't generate a useless message
return None, files
+ # handle the messageid
+ # TODO: handle inreplyto
+ messageid = "%s.%s.%s-%s"%(time.time(), random.random(),
+ self.classname, self.MAIL_DOMAIN)
+
# now create the message, attaching the files
content = '\n'.join(m)
message_id = self.db.msg.create(author=self.getuid(),
recipients=[], date=date.Date('.'), summary=summary,
# now create the message, attaching the files
content = '\n'.join(m)
message_id = self.db.msg.create(author=self.getuid(),
recipients=[], date=date.Date('.'), summary=summary,
- content=content, files=files)
+ content=content, files=files, messageid=messageid)
# update the messages property
return message_id, files
# update the messages property
return message_id, files
self._post_editnode(nid)
# and some nice feedback for the user
message = _('%(classname)s created ok')%{'classname': cn}
self._post_editnode(nid)
# and some nice feedback for the user
message = _('%(classname)s created ok')%{'classname': cn}
+
+ # render the newly created issue
+ self.db.commit()
+ self.nodeid = nid
+ self.pagehead('%s: %s'%(self.classname.capitalize(), nid),
+ message)
+ item = htmltemplate.ItemTemplate(self, self.TEMPLATES,
+ self.classname)
+ item.render(nid)
+ self.pagefoot()
+ return
except:
self.db.rollback()
s = StringIO.StringIO()
traceback.print_exc(None, s)
message = '<pre>%s</pre>'%cgi.escape(s.getvalue())
self.pagehead(_('New %(classname)s')%{'classname':
except:
self.db.rollback()
s = StringIO.StringIO()
traceback.print_exc(None, s)
message = '<pre>%s</pre>'%cgi.escape(s.getvalue())
self.pagehead(_('New %(classname)s')%{'classname':
- self.classname.capitalize()}, message)
+ self.classname.capitalize()}, message)
# call the template
newitem = htmltemplate.NewItemTemplate(self, self.TEMPLATES,
# call the template
newitem = htmltemplate.NewItemTemplate(self, self.TEMPLATES,
user_name = self.user or ''
if self.user == 'admin':
admin_links = _(' | <a href="list_classes">Class List</a>' \
user_name = self.user or ''
if self.user == 'admin':
admin_links = _(' | <a href="list_classes">Class List</a>' \
- ' | <a href="user">User List</a>')
+ ' | <a href="user">User List</a>' \
+ ' | <a href="newuser">Add User</a>')
else:
admin_links = ''
if self.user not in (None, 'anonymous'):
else:
admin_links = ''
if self.user not in (None, 'anonymous'):
| Add
<a href="newissue">Issue</a>,
<a href="newsupport">Support</a>,
| Add
<a href="newissue">Issue</a>,
<a href="newsupport">Support</a>,
-<a href="newuser">User</a>
''')
else:
add_links = ''
''')
else:
add_links = ''
#
# $Log: not supported by cvs2svn $
#
# $Log: not supported by cvs2svn $
+# Revision 1.89 2002/01/07 20:24:45 richard
+# *mutter* stupid cutnpaste
+#
+# Revision 1.88 2002/01/02 02:31:38 richard
+# Sorry for the huge checkin message - I was only intending to implement #496356
+# but I found a number of places where things had been broken by transactions:
+# . modified ROUNDUPDBSENDMAILDEBUG to be SENDMAILDEBUG and hold a filename
+# for _all_ roundup-generated smtp messages to be sent to.
+# . the transaction cache had broken the roundupdb.Class set() reactors
+# . newly-created author users in the mailgw weren't being committed to the db
+#
+# Stuff that made it into CHANGES.txt (ie. the stuff I was actually working
+# on when I found that stuff :):
+# . #496356 ] Use threading in messages
+# . detectors were being registered multiple times
+# . added tests for mailgw
+# . much better attaching of erroneous messages in the mail gateway
+#
+# Revision 1.87 2001/12/23 23:18:49 richard
+# We already had an admin-specific section of the web heading, no need to add
+# another one :)
+#
+# Revision 1.86 2001/12/20 15:43:01 rochecompaan
+# Features added:
+# . Multilink properties are now displayed as comma separated values in
+# a textbox
+# . The add user link is now only visible to the admin user
+# . Modified the mail gateway to reject submissions from unknown
+# addresses if ANONYMOUS_ACCESS is denied
+#
+# Revision 1.85 2001/12/20 06:13:24 rochecompaan
+# Bugs fixed:
+# . Exception handling in hyperdb for strings-that-look-like numbers got
+# lost somewhere
+# . Internet Explorer submits full path for filename - we now strip away
+# the path
+# Features added:
+# . Link and multilink properties are now displayed sorted in the cgi
+# interface
+#
+# Revision 1.84 2001/12/18 15:30:30 rochecompaan
+# Fixed bugs:
+# . Fixed file creation and retrieval in same transaction in anydbm
+# backend
+# . Cgi interface now renders new issue after issue creation
+# . Could not set issue status to resolved through cgi interface
+# . Mail gateway was changing status back to 'chatting' if status was
+# omitted as an argument
+#
+# Revision 1.83 2001/12/15 23:51:01 richard
+# Tested the changes and fixed a few problems:
+# . files are now attached to the issue as well as the message
+# . newuser is a real method now since we don't want to do the message/file
+# stuff for it
+# . added some documentation
+# The really big changes in the diff are a result of me moving some code
+# around to keep like methods together a bit better.
+#
# Revision 1.82 2001/12/15 19:24:39 rochecompaan
# . Modified cgi interface to change properties only once all changes are
# collected, files created and messages generated.
# Revision 1.82 2001/12/15 19:24:39 rochecompaan
# . Modified cgi interface to change properties only once all changes are
# collected, files created and messages generated.