Skip to content

Commit a43f362

Browse files
author
Richard Jones
committed
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.
1 parent 78fc9e2 commit a43f362

File tree

1 file changed

+169
-112
lines changed

1 file changed

+169
-112
lines changed

roundup/cgi_client.py

Lines changed: 169 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: cgi_client.py,v 1.82 2001-12-15 19:24:39 rochecompaan Exp $
18+
# $Id: cgi_client.py,v 1.83 2001-12-15 23:51:01 richard Exp $
1919

2020
__doc__ = """
2121
WWW request handler (also used in the stand-alone server).
@@ -324,6 +324,8 @@ def shownode(self, message=None):
324324
', '.join(changed.keys())}
325325
elif self.form.has_key('__note') and self.form['__note'].value:
326326
message = _('note added')
327+
elif self.form.has_key('__file'):
328+
message = _('file added')
327329
else:
328330
message = _('nothing changed')
329331
except:
@@ -348,75 +350,34 @@ def shownode(self, message=None):
348350
showissue = shownode
349351
showmsg = shownode
350352

351-
def showuser(self, message=None):
352-
'''Display a user page for editing. Make sure the user is allowed
353-
to edit this node, and also check for password changes.
353+
def _changenode(self, props):
354+
''' change the node based on the contents of the form
354355
'''
355-
if self.user == 'anonymous':
356-
raise Unauthorised
357-
358-
user = self.db.user
359-
360-
# get the username of the node being edited
361-
node_user = user.get(self.nodeid, 'username')
362-
363-
if self.user not in ('admin', node_user):
364-
raise Unauthorised
365-
366-
#
367-
# perform any editing
368-
#
369-
keys = self.form.keys()
370-
num_re = re.compile('^\d+$')
371-
if keys:
372-
try:
373-
props, changed = parsePropsFromForm(self.db, user, self.form,
374-
self.nodeid)
375-
set_cookie = 0
376-
if self.nodeid == self.getuid() and changed.has_key('password'):
377-
password = self.form['password'].value.strip()
378-
if password:
379-
set_cookie = password
380-
else:
381-
# no password was supplied - don't change it
382-
del props['password']
383-
del changed['password']
384-
user.set(self.nodeid, **props)
385-
# and some feedback for the user
386-
message = _('%(changes)s edited ok')%{'changes':
387-
', '.join(changed.keys())}
388-
except:
389-
self.db.rollback()
390-
s = StringIO.StringIO()
391-
traceback.print_exc(None, s)
392-
message = '<pre>%s</pre>'%cgi.escape(s.getvalue())
356+
cl = self.db.classes[self.classname]
357+
# set status to chatting if 'unread' or 'resolved'
358+
try:
359+
# determine the id of 'unread','resolved' and 'chatting'
360+
unread_id = self.db.status.lookup('unread')
361+
resolved_id = self.db.status.lookup('resolved')
362+
chatting_id = self.db.status.lookup('chatting')
363+
except KeyError:
364+
pass
393365
else:
394-
set_cookie = 0
395-
396-
# fix the cookie if the password has changed
397-
if set_cookie:
398-
self.set_cookie(self.user, set_cookie)
399-
400-
#
401-
# now the display
402-
#
403-
self.pagehead(_('User: %(user)s')%{'user': node_user}, message)
404-
405-
# use the template to display the item
406-
item = htmltemplate.ItemTemplate(self, self.TEMPLATES, 'user')
407-
item.render(self.nodeid)
408-
self.pagefoot()
409-
410-
def showfile(self):
411-
''' display a file
412-
'''
413-
nodeid = self.nodeid
414-
cl = self.db.file
415-
mime_type = cl.get(nodeid, 'type')
416-
if mime_type == 'message/rfc822':
417-
mime_type = 'text/plain'
418-
self.header(headers={'Content-Type': mime_type})
419-
self.write(cl.get(nodeid, 'content'))
366+
if (props['status'] == unread_id or props['status'] == resolved_id):
367+
props['status'] = chatting_id
368+
# add assignedto to the nosy list
369+
if props.has_key('assignedto'):
370+
assignedto_id = props['assignedto']
371+
if assignedto_id not in props['nosy']:
372+
props['nosy'].append(assignedto_id)
373+
# create the message
374+
message, files = self._handle_message()
375+
if message:
376+
props['messages'] = cl.get(self.nodeid, 'messages') + [message]
377+
if files:
378+
props['files'] = cl.get(self.nodeid, 'files') + files
379+
# make the changes
380+
cl.set(self.nodeid, **props)
420381

421382
def _createnode(self):
422383
''' create a node based on the contents of the form
@@ -436,47 +397,22 @@ def _createnode(self):
436397
# add assignedto to the nosy list
437398
if props.has_key('assignedto'):
438399
assignedto_id = props['assignedto']
439-
if props.has_key('nosy') and not assignedto_id in props['nosy']:
400+
if props.has_key('nosy') and assignedto_id not in props['nosy']:
440401
props['nosy'].append(assignedto_id)
441402
else:
442403
props['nosy'] = [assignedto_id]
443-
# check for messages
444-
message = self._handle_message()
404+
# check for messages and files
405+
message, files = self._handle_message()
445406
if message:
446407
props['messages'] = [message]
408+
if files:
409+
props['files'] = files
447410
# create the node and return it's id
448411
return cl.create(**props)
449412

450-
def _changenode(self, props):
451-
''' change the node based on the contents of the form
452-
'''
453-
cl = self.db.classes[self.classname]
454-
# set status to chatting if 'unread' or 'resolved'
455-
try:
456-
# determine the id of 'unread','resolved' and 'chatting'
457-
unread_id = self.db.status.lookup('unread')
458-
resolved_id = self.db.status.lookup('resolved')
459-
chatting_id = self.db.status.lookup('chatting')
460-
except KeyError:
461-
pass
462-
else:
463-
if (props['status'] == unread_id or props['status'] == resolved_id):
464-
props['status'] = chatting_id
465-
# add assignedto to the nosy list
466-
if props.has_key('assignedto'):
467-
assignedto_id = props['assignedto']
468-
if not assignedto_id in props['nosy']:
469-
props['nosy'].append(assignedto_id)
470-
# create the message
471-
message = self._handle_message()
472-
if message:
473-
props['messages'] = cl.get(self.nodeid, 'messages') + [message]
474-
# make the changes
475-
cl.set(self.nodeid, **props)
476-
477413
def _handle_message(self):
478-
''' generate and edit message '''
479-
414+
''' generate and edit message
415+
'''
480416
# handle file attachments
481417
files = []
482418
if self.form.has_key('__file'):
@@ -494,16 +430,18 @@ def _handle_message(self):
494430
cl = self.db.classes[self.classname]
495431
props = cl.getprops()
496432
note = None
433+
# in a nutshell, don't do anything if there's no note or there's no
434+
# nosy
497435
if self.form.has_key('__note'):
498436
note = self.form['__note'].value
499437
if not props.has_key('messages'):
500-
return
438+
return None, files
501439
if not isinstance(props['messages'], hyperdb.Multilink):
502-
return
440+
return None, files
503441
if not props['messages'].classname == 'msg':
504-
return
442+
return None, files
505443
if not (self.form.has_key('nosy') or note):
506-
return
444+
return None, files
507445

508446
# handle the note
509447
if note:
@@ -512,22 +450,32 @@ def _handle_message(self):
512450
else:
513451
summary = note
514452
m = ['%s\n'%note]
515-
else:
516-
summary = _('This %(classname)s has been edited through'
517-
' the web.\n')%{'classname': cn}
518-
m = [summary]
453+
elif not files:
454+
# don't generate a useless message
455+
return None, files
519456

520-
# now create the message
457+
# now create the message, attaching the files
521458
content = '\n'.join(m)
522459
message_id = self.db.msg.create(author=self.getuid(),
523460
recipients=[], date=date.Date('.'), summary=summary,
524461
content=content, files=files)
525462

526463
# update the messages property
527-
return message_id
464+
return message_id, files
528465

529466
def _post_editnode(self, nid):
530-
''' do the linking part of the node creation
467+
'''Do the linking part of the node creation.
468+
469+
If a form element has :link or :multilink appended to it, its
470+
value specifies a node designator and the property on that node
471+
to add _this_ node to as a link or multilink.
472+
473+
This is typically used on, eg. the file upload page to indicated
474+
which issue to link the file to.
475+
476+
TODO: I suspect that this and newfile will go away now that
477+
there's the ability to upload a file using the issue __file form
478+
element!
531479
'''
532480
cn = self.classname
533481
cl = self.db.classes[cn]
@@ -603,7 +551,39 @@ def newnode(self, message=None):
603551

604552
self.pagefoot()
605553
newissue = newnode
606-
newuser = newnode
554+
555+
def newuser(self, message=None):
556+
''' Add a new user to the database.
557+
558+
Don't do any of the message or file handling, just create the node.
559+
'''
560+
cn = self.classname
561+
cl = self.db.classes[cn]
562+
563+
# possibly perform a create
564+
keys = self.form.keys()
565+
if [i for i in keys if i[0] != ':']:
566+
try:
567+
props, dummy = parsePropsFromForm(self.db, cl, self.form)
568+
nid = cl.create(**props)
569+
# handle linked nodes
570+
self._post_editnode(nid)
571+
# and some nice feedback for the user
572+
message = _('%(classname)s created ok')%{'classname': cn}
573+
except:
574+
self.db.rollback()
575+
s = StringIO.StringIO()
576+
traceback.print_exc(None, s)
577+
message = '<pre>%s</pre>'%cgi.escape(s.getvalue())
578+
self.pagehead(_('New %(classname)s')%{'classname':
579+
self.classname.capitalize()}, message)
580+
581+
# call the template
582+
newitem = htmltemplate.NewItemTemplate(self, self.TEMPLATES,
583+
self.classname)
584+
newitem.render(self.form)
585+
586+
self.pagefoot()
607587

608588
def newfile(self, message=None):
609589
''' Add a new file to the database.
@@ -642,6 +622,76 @@ def newfile(self, message=None):
642622
newitem.render(self.form)
643623
self.pagefoot()
644624

625+
def showuser(self, message=None):
626+
'''Display a user page for editing. Make sure the user is allowed
627+
to edit this node, and also check for password changes.
628+
'''
629+
if self.user == 'anonymous':
630+
raise Unauthorised
631+
632+
user = self.db.user
633+
634+
# get the username of the node being edited
635+
node_user = user.get(self.nodeid, 'username')
636+
637+
if self.user not in ('admin', node_user):
638+
raise Unauthorised
639+
640+
#
641+
# perform any editing
642+
#
643+
keys = self.form.keys()
644+
num_re = re.compile('^\d+$')
645+
if keys:
646+
try:
647+
props, changed = parsePropsFromForm(self.db, user, self.form,
648+
self.nodeid)
649+
set_cookie = 0
650+
if self.nodeid == self.getuid() and changed.has_key('password'):
651+
password = self.form['password'].value.strip()
652+
if password:
653+
set_cookie = password
654+
else:
655+
# no password was supplied - don't change it
656+
del props['password']
657+
del changed['password']
658+
user.set(self.nodeid, **props)
659+
# and some feedback for the user
660+
message = _('%(changes)s edited ok')%{'changes':
661+
', '.join(changed.keys())}
662+
except:
663+
self.db.rollback()
664+
s = StringIO.StringIO()
665+
traceback.print_exc(None, s)
666+
message = '<pre>%s</pre>'%cgi.escape(s.getvalue())
667+
else:
668+
set_cookie = 0
669+
670+
# fix the cookie if the password has changed
671+
if set_cookie:
672+
self.set_cookie(self.user, set_cookie)
673+
674+
#
675+
# now the display
676+
#
677+
self.pagehead(_('User: %(user)s')%{'user': node_user}, message)
678+
679+
# use the template to display the item
680+
item = htmltemplate.ItemTemplate(self, self.TEMPLATES, 'user')
681+
item.render(self.nodeid)
682+
self.pagefoot()
683+
684+
def showfile(self):
685+
''' display a file
686+
'''
687+
nodeid = self.nodeid
688+
cl = self.db.file
689+
mime_type = cl.get(nodeid, 'type')
690+
if mime_type == 'message/rfc822':
691+
mime_type = 'text/plain'
692+
self.header(headers={'Content-Type': mime_type})
693+
self.write(cl.get(nodeid, 'content'))
694+
645695
def classes(self, message=None):
646696
''' display a list of all the classes in the database
647697
'''
@@ -1100,6 +1150,13 @@ def parsePropsFromForm(db, cl, form, nodeid=0):
11001150

11011151
#
11021152
# $Log: not supported by cvs2svn $
1153+
# Revision 1.82 2001/12/15 19:24:39 rochecompaan
1154+
# . Modified cgi interface to change properties only once all changes are
1155+
# collected, files created and messages generated.
1156+
# . Moved generation of change note to nosyreactors.
1157+
# . We now check for changes to "assignedto" to ensure it's added to the
1158+
# nosy list.
1159+
#
11031160
# Revision 1.81 2001/12/12 23:55:00 richard
11041161
# Fixed some problems with user editing
11051162
#

0 commit comments

Comments
 (0)