Skip to content

Commit 46bea02

Browse files
author
Gordon B. McMillan
committed
Use a real parser for templates.
Rewrite htmltemplate to use the parser (hack, hack). Move the "do_XXX" methods to template_funcs.py. Redo the funcion tests (but not Template tests - they're hopeless). Simplified query form in cgi_client. Ability to delete msgs, files, queries. Ability to edit the metadata on files.
1 parent 6138a82 commit 46bea02

File tree

5 files changed

+1489
-1344
lines changed

5 files changed

+1489
-1344
lines changed

roundup/cgi_client.py

Lines changed: 92 additions & 41 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.156 2002-08-01 15:06:06 gmcm Exp $
18+
# $Id: cgi_client.py,v 1.157 2002-08-13 20:16:09 gmcm Exp $
1919

2020
__doc__ = """
2121
WWW request handler (also used in the stand-alone server).
@@ -186,25 +186,32 @@ def pagehead(self, title, message=None):
186186
# figure who the user is
187187
user_name = self.user
188188
userid = self.db.user.lookup(user_name)
189+
default_queries = 1
190+
links = []
191+
if user_name != 'anonymous':
192+
try:
193+
default_queries = self.db.user.get(userid, 'defaultqueries')
194+
except KeyError:
195+
pass
189196

190197
# figure all the header links
191-
if hasattr(self.instance, 'HEADER_INDEX_LINKS'):
192-
links = []
193-
for name in self.instance.HEADER_INDEX_LINKS:
194-
spec = getattr(self.instance, name + '_INDEX')
195-
# skip if we need to fill in the logged-in user id and
196-
# we're anonymous
197-
if (spec['FILTERSPEC'].has_key('assignedto') and
198-
spec['FILTERSPEC']['assignedto'] in ('CURRENT USER',
199-
None) and user_name == 'anonymous'):
200-
continue
201-
links.append(self.make_index_link(name))
202-
else:
203-
# no config spec - hard-code
204-
links = [
205-
_('All <a href="issue?status=-1,unread,deferred,chatting,need-eg,in-progress,testing,done-cbb&:sort=-activity&:filter=status&:columns=id,activity,status,title,assignedto&:group=priority&show_customization=1">Issues</a>'),
206-
_('Unassigned <a href="issue?assignedto=-1&status=-1,unread,deferred,chatting,need-eg,in-progress,testing,done-cbb&:sort=-activity&:filter=status,assignedto&:columns=id,activity,status,title,assignedto&:group=priority&show_customization=1">Issues</a>')
207-
]
198+
if default_queries:
199+
if hasattr(self.instance, 'HEADER_INDEX_LINKS'):
200+
for name in self.instance.HEADER_INDEX_LINKS:
201+
spec = getattr(self.instance, name + '_INDEX')
202+
# skip if we need to fill in the logged-in user id and
203+
# we're anonymous
204+
if (spec['FILTERSPEC'].has_key('assignedto') and
205+
spec['FILTERSPEC']['assignedto'] in ('CURRENT USER',
206+
None) and user_name == 'anonymous'):
207+
continue
208+
links.append(self.make_index_link(name))
209+
else:
210+
# no config spec - hard-code
211+
links = [
212+
_('All <a href="issue?status=-1,unread,deferred,chatting,need-eg,in-progress,testing,done-cbb&:sort=-activity&:filter=status&:columns=id,activity,status,title,assignedto&:group=priority&show_customization=1">Issues</a>'),
213+
_('Unassigned <a href="issue?assignedto=-1&status=-1,unread,deferred,chatting,need-eg,in-progress,testing,done-cbb&:sort=-activity&:filter=status,assignedto&:columns=id,activity,status,title,assignedto&:group=priority&show_customization=1">Issues</a>')
214+
]
208215

209216
user_info = _('<a href="login">Login</a>')
210217
add_links = ''
@@ -343,9 +350,11 @@ def index_arg(self, arg):
343350
return []
344351

345352
def index_sort(self):
346-
# first try query string
353+
# first try query string / simple form
347354
x = self.index_arg(':sort')
348355
if x:
356+
if self.index_arg(':descending'):
357+
return ['-'+x[0]]
349358
return x
350359
# nope - get the specs out of the form
351360
specs = []
@@ -479,10 +488,8 @@ def searchnode(self):
479488
all_columns = self.db.getclass(cn).getprops().keys()
480489
all_columns.sort()
481490
index.filter_section('', filter, columns, group, all_columns, sort,
482-
filterspec, pagesize, 0)
491+
filterspec, pagesize, 0, 0)
483492
self.pagefoot()
484-
index.db = index.cl = index.properties = None
485-
index.clear()
486493

487494
# XXX deviates from spec - loses the '+' (that's a reserved character
488495
# in URLS
@@ -524,6 +531,9 @@ def list(self, sort=None, group=None, filter=None, columns=None,
524531
startwith = int(self.form[':startwith'].value)
525532
else:
526533
startwith = 0
534+
simpleform = 1
535+
if self.form.has_key(':advancedsearch'):
536+
simpleform = 0
527537

528538
if self.form.has_key('Query') and self.form['Query'].value == 'Save':
529539
# format a query string
@@ -562,7 +572,8 @@ def list(self, sort=None, group=None, filter=None, columns=None,
562572
try:
563573
index.render(filterspec, search_text, filter, columns, sort,
564574
group, show_customization=show_customization,
565-
show_nodes=show_nodes, pagesize=pagesize, startwith=startwith)
575+
show_nodes=show_nodes, pagesize=pagesize, startwith=startwith,
576+
simple_search=simpleform)
566577
except htmltemplate.MissingTemplateError:
567578
self.basicClassEditPage()
568579
self.pagefoot()
@@ -699,17 +710,24 @@ def shownode(self, message=None, num_re=re.compile('^\d+$')):
699710
'''
700711
cn = self.classname
701712
cl = self.db.classes[cn]
713+
keys = self.form.keys()
714+
fromremove = 0
702715
if self.form.has_key(':multilink'):
703-
link = self.form[':multilink'].value
704-
designator, linkprop = link.split(':')
705-
xtra = ' for <a href="%s">%s</a>' % (designator, designator)
716+
# is the multilink there because we came from remove()?
717+
if self.form.has_key(':target'):
718+
xtra = ''
719+
fromremove = 1
720+
message = _('%s removed' % self.index_arg(":target")[0])
721+
else:
722+
link = self.form[':multilink'].value
723+
designator, linkprop = link.split(':')
724+
xtra = ' for <a href="%s">%s</a>' % (designator, designator)
706725
else:
707726
xtra = ''
708-
727+
709728
# possibly perform an edit
710-
keys = self.form.keys()
711729
# don't try to set properties if the user has just logged in
712-
if keys and not self.form.has_key('__login_name'):
730+
if keys and not fromremove and not self.form.has_key('__login_name'):
713731
try:
714732
userid = self.db.user.lookup(self.user)
715733
if not self.db.security.hasPermission('Edit', userid, cn):
@@ -1108,12 +1126,8 @@ def showuser(self, message=None, num_re=re.compile('^\d+$')):
11081126
# ok, so we need to be able to edit everything, or be this node's
11091127
# user
11101128
userid = self.db.user.lookup(self.user)
1111-
if (not self.db.security.hasPermission('Edit', userid)
1112-
and self.user != node_user):
1113-
raise Unauthorised, _("You do not have permission to access"\
1114-
" %(action)s.")%{'action': self.classname +
1115-
str(self.nodeid)}
1116-
1129+
# removed check on user's permissions - this needs to be done
1130+
# through require tags in user.item
11171131
#
11181132
# perform any editing
11191133
#
@@ -1160,6 +1174,11 @@ def showuser(self, message=None, num_re=re.compile('^\d+$')):
11601174
def showfile(self):
11611175
''' display a file
11621176
'''
1177+
# nothing in xtrapath - edit the file's metadata
1178+
if self.xtrapath is None:
1179+
return self.shownode()
1180+
1181+
# something in xtrapath - download the file
11631182
nodeid = self.nodeid
11641183
cl = self.db.classes[self.classname]
11651184
try:
@@ -1170,7 +1189,7 @@ def showfile(self):
11701189
mime_type = 'text/plain'
11711190
self.header(headers={'Content-Type': mime_type})
11721191
self.write(cl.get(nodeid, 'content'))
1173-
1192+
11741193
def permission(self):
11751194
'''
11761195
'''
@@ -1472,19 +1491,17 @@ def main_action(self):
14721491

14731492
# now figure which function to call
14741493
path = self.split_path
1494+
self.xtrapath = None
14751495

14761496
# default action to index if the path has no information in it
14771497
if not path or path[0] in ('', 'index'):
14781498
action = 'index'
14791499
else:
14801500
action = path[0]
1501+
if len(path) > 1:
1502+
self.xtrapath = path[1:]
14811503
self.desired_action = action
14821504

1483-
# Everthing ignores path[1:]
1484-
# - The file download link generator actually relies on this - it
1485-
# appends the name of the file to the URL so the download file name
1486-
# is correct, but doesn't actually use it.
1487-
14881505
# everyone is allowed to try to log in
14891506
if action == 'login_action':
14901507
# try to login
@@ -1546,6 +1563,9 @@ def do_action(self, action, dre=re.compile(r'([^\d]+)(\d+)'),
15461563
if action == 'logout':
15471564
self.logout()
15481565
return
1566+
if action == 'remove':
1567+
self.remove()
1568+
return
15491569

15501570
# see if we're to display an existing node
15511571
m = dre.match(action)
@@ -1597,6 +1617,31 @@ def do_action(self, action, dre=re.compile(r'([^\d]+)(\d+)'),
15971617
raise NotFound, self.classname
15981618
self.list()
15991619

1620+
def remove(self, dre=re.compile(r'([^\d]+)(\d+)')):
1621+
target = self.index_arg(':target')[0]
1622+
m = dre.match(target)
1623+
if m:
1624+
classname = m.group(1)
1625+
nodeid = m.group(2)
1626+
cl = self.db.getclass(classname)
1627+
cl.retire(nodeid)
1628+
# now take care of the reference
1629+
parentref = self.index_arg(':multilink')[0]
1630+
parent, prop = parentref.split(':')
1631+
m = dre.match(parent)
1632+
if m:
1633+
self.classname = m.group(1)
1634+
self.nodeid = m.group(2)
1635+
cl = self.db.getclass(self.classname)
1636+
value = cl.get(self.nodeid, prop)
1637+
value.remove(nodeid)
1638+
cl.set(self.nodeid, **{prop:value})
1639+
func = getattr(self, 'show%s'%self.classname)
1640+
return func()
1641+
else:
1642+
raise NotFound, parent
1643+
else:
1644+
raise NotFound, target
16001645

16011646
class ExtendedClient(Client):
16021647
'''Includes pages and page heading information that relate to the
@@ -1703,6 +1748,12 @@ def parsePropsFromForm(db, cl, form, nodeid=0, num_re=re.compile('^\d+$')):
17031748

17041749
#
17051750
# $Log: not supported by cvs2svn $
1751+
# Revision 1.156 2002/08/01 15:06:06 gmcm
1752+
# Use same regex to split search terms as used to index text.
1753+
# Fix to back_metakit for not changing journaltag on reopen.
1754+
# Fix htmltemplate's do_link so [No <whatever>] strings are href'd.
1755+
# Fix bogus "nosy edited ok" msg - the **d syntax does NOT share d between caller and callee.
1756+
#
17061757
# Revision 1.155 2002/08/01 00:56:22 richard
17071758
# Added the web access and email access permissions, so people can restrict
17081759
# access to users who register through the email interface (for example).

0 commit comments

Comments
 (0)