diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py
index ea1ad7359af8048f831407d3afced4486f1c06e5..d4499bb334839aef8aa2abe05e2a15eebff01ca7 100644 (file)
--- a/roundup/cgi/client.py
+++ b/roundup/cgi/client.py
-# $Id: client.py,v 1.136 2003-09-08 09:28:28 jlgijsbers Exp $
+# $Id: client.py,v 1.141 2003-10-04 11:21:47 jlgijsbers Exp $
__doc__ = """
WWW request handler (also used in the stand-alone server).
import os, os.path, cgi, StringIO, urlparse, re, traceback, mimetypes, urllib
import binascii, Cookie, time, random, MimeWriter, smtplib, socket, quopri
-import stat, rfc822, string
+import stat, rfc822
from roundup import roundupdb, date, hyperdb, password, token, rcsv
from roundup.i18n import _
pass
# used by a couple of routines
-if hasattr(string, 'ascii_letters'):
- chars = string.ascii_letters+string.digits
-else:
- # python2.1 doesn't have ascii_letters
- chars = string.letters+string.digits
+chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
-# XXX actually _use_ FormError
class FormError(ValueError):
''' An "expected" exception occurred during form parsing.
- ie. something we know can go wrong, and don't want to alarm the
except NotFound:
# pass through
raise
+ except FormError, e:
+ self.error_message.append(_('Form Error: ') + str(e))
+ self.write(self.renderContext())
except:
# everything else
self.write(cgitb.html())
return 1 on successful login
'''
- # parse the props from the form
- try:
- props = self.parsePropsFromForm()[0][('user', None)]
- except (ValueError, KeyError), message:
- self.error_message.append(_('Error: ') + str(message))
- return
+ props = self.parsePropsFromForm()[0][('user', None)]
# make sure we're allowed to register
if not self.registerPermission(props):
# send the email
tracker_name = self.db.config.TRACKER_NAME
- subject = 'Complete your registration to %s'%tracker_name
- body = '''
-To complete your registration of the user "%(name)s" with %(tracker)s,
-please visit the following URL:
+ tracker_email = self.db.config.TRACKER_EMAIL
+ subject = 'Complete your registration to %s -- key %s' % (tracker_name,
+ otk)
+ body = """To complete your registration of the user "%(name)s" with
+%(tracker)s, please do one of the following:
+
+- send a reply to %(tracker_email)s and maintain the subject line as is (the
+reply's additional "Re:" is ok),
+
+- or visit the following URL:
%(url)s?@action=confrego&otk=%(otk)s
-'''%{'name': props['username'], 'tracker': tracker_name, 'url': self.base,
- 'otk': otk}
- if not self.standard_message(props['address'], subject, body):
+""" % {'name': props['username'], 'tracker': tracker_name, 'url': self.base,
+ 'otk': otk, 'tracker_email': tracker_email}
+ if not self.standard_message([props['address']], subject, body,
+ tracker_email):
return
# commit changes to the database
# redirect to the "you're almost there" page
raise Redirect, '%suser?@template=rego_progress'%self.base
- def standard_message(self, to, subject, body):
+ def standard_message(self, to, subject, body, author=None):
try:
- self.mailer.standard_message(to, subject, body)
+ self.mailer.standard_message(to, subject, body, author)
return 1
- except MessageSendException, e:
+ except MessageSendError, e:
self.error_message.append(str(e))
-
def registerPermission(self, props):
''' Determine whether the user has permission to register
Your password is now: %(password)s
'''%{'name': name, 'password': newpw}
- if not self.standard_message(address, subject, body):
+ if not self.standard_message([address], subject, body):
return
self.ok_message.append('Password reset and email sent to %s'%address)
You should then receive another email with the new password.
'''%{'name': name, 'tracker': tracker_name, 'url': self.base, 'otk': otk}
- if not self.standard_message(address, subject, body):
+ if not self.standard_message([address], subject, body):
return
self.ok_message.append('Email sent to %s'%address)
See parsePropsFromForm and _editnodes for special variables
'''
- # parse the props from the form
- try:
- props, links = self.parsePropsFromForm()
- except (ValueError, KeyError), message:
- self.error_message.append(_('Parse Error: ') + str(message))
- return
+ props, links = self.parsePropsFromForm()
# handle the props
try:
self.classname, self.nodeid, urllib.quote(message),
urllib.quote(self.template))
+ newItemAction = editItemAction
+
def editItemPermission(self, props):
''' Determine whether the user has permission to edit this item.
return 1
return 0
- def newItemAction(self):
- ''' Add a new item to the database.
-
- This follows the same form as the editItemAction, with the same
- special form values.
- '''
- # parse the props from the form
- try:
- props, links = self.parsePropsFromForm()
- except (ValueError, KeyError), message:
- self.error_message.append(_('Error: ') + str(message))
- return
-
- # handle the props - edit or create
- try:
- # when it hits the None element, it'll set self.nodeid
- messages = self._editnodes(props, links)
-
- except (ValueError, KeyError, IndexError), message:
- # these errors might just be indicative of user dumbness
- self.error_message.append(_('Error: ') + str(message))
- return
-
- # commit now that all the tricky stuff is done
- self.db.commit()
-
- # redirect to the new item's page
- raise Redirect, '%s%s%s?@ok_message=%s&@template=%s'%(self.base,
- self.classname, self.nodeid, urllib.quote(messages),
- urllib.quote(self.template))
-
def newItemPermission(self, props):
''' Determine whether the user has permission to create (edit) this
item.
for entry in extractFormList(form[key]):
m = self.FV_DESIGNATOR.match(entry)
if not m:
- raise ValueError, \
+ raise FormError, \
'link "%s" value "%s" not a designator'%(key, entry)
value.append((m.group(1), m.group(2)))
# make sure the link property is valid
if (not isinstance(propdef[propname], hyperdb.Multilink) and
not isinstance(propdef[propname], hyperdb.Link)):
- raise ValueError, '%s %s is not a link or '\
+ raise FormError, '%s %s is not a link or '\
'multilink property'%(cn, propname)
all_links.append((cn, nodeid, propname, value))
# does the property exist?
if not propdef.has_key(propname):
if mlaction != 'set':
- raise ValueError, 'You have submitted a %s action for'\
+ raise FormError, 'You have submitted a %s action for'\
' the property "%s" which doesn\'t exist'%(mlaction,
propname)
# the form element is probably just something we don't care
else:
# multiple values are not OK
if isinstance(value, type([])):
- raise ValueError, 'You have submitted more than one value'\
+ raise FormError, 'You have submitted more than one value'\
' for the %s property'%propname
# value might be a file upload...
if not hasattr(value, 'filename') or value.filename is None:
confirm = form[key]
break
else:
- raise ValueError, 'Password and confirmation text do '\
+ raise FormError, 'Password and confirmation text do '\
'not match'
if isinstance(confirm, type([])):
- raise ValueError, 'You have submitted more than one value'\
+ raise FormError, 'You have submitted more than one value'\
' for the %s property'%propname
if value != confirm.value:
- raise ValueError, 'Password and confirmation text do '\
+ raise FormError, 'Password and confirmation text do '\
'not match'
value = password.Password(value)
try:
value = db.classes[link].lookup(value)
except KeyError:
- raise ValueError, _('property "%(propname)s": '
+ raise FormError, _('property "%(propname)s": '
'%(value)s not a %(classname)s')%{
'propname': propname, 'value': value,
'classname': link}
except TypeError, message:
- raise ValueError, _('you may only enter ID values '
+ raise FormError, _('you may only enter ID values '
'for property "%(propname)s": %(message)s')%{
'propname': propname, 'message': message}
elif isinstance(proptype, hyperdb.Multilink):
try:
entry = link_cl.lookup(entry)
except KeyError:
- raise ValueError, _('property "%(propname)s": '
+ raise FormError, _('property "%(propname)s": '
'"%(value)s" not an entry of %(classname)s')%{
'propname': propname, 'value': entry,
'classname': link}
except TypeError, message:
- raise ValueError, _('you may only enter ID values '
+ raise FormError, _('you may only enter ID values '
'for property "%(propname)s": %(message)s')%{
'propname': propname, 'message': message}
l.append(entry)
try:
existing.remove(entry)
except ValueError:
- raise ValueError, _('property "%(propname)s": '
+ raise FormError, _('property "%(propname)s": '
'"%(value)s" not currently in list')%{
'propname': propname, 'value': entry}
else:
elif isinstance(proptype, hyperdb.Number):
value = float(value)
except ValueError, msg:
- raise ValueError, _('Error with %s property: %s')%(
+ raise FormError, _('Error with %s property: %s')%(
propname, msg)
# register that we got this property
# no existing value
if not propdef.has_key(propname):
raise
+ except IndexError, message:
+ raise FormError(str(message))
# make sure the existing multilink is sorted
if isinstance(proptype, hyperdb.Multilink):
s.append('Required %s %s %s not supplied'%(thing[0], p,
', '.join(required)))
if s:
- raise ValueError, '\n'.join(s)
+ raise FormError, '\n'.join(s)
# When creating a FileClass node, it should have a non-empty content
# property to be created. When editing a FileClass node, it should
if not props.get('content', ''):
del all_props[(cn, id)]
elif props.has_key('content') and not props['content']:
- raise ValueError, _('File is empty')
+ raise FormError, _('File is empty')
return all_props, all_links
def fixNewlines(text):