Skip to content

Commit bc4dd85

Browse files
author
Richard Jones
committed
Hack hack...
. Lots of cleanup in the classic html (stylesheet, search page, index page, ...) . Reinstated searching, but not query saving yet . Filtering only allows sorting and grouping by one property - all backends now implement this behaviour. . Nosy list journalling turned off by default, everything else is on. . Added some convenience methods (reverse, propchanged, [item] accesses, ...) . Did I mention the stylesheet is much cleaner now? :)
1 parent 4afafe7 commit bc4dd85

File tree

14 files changed

+798
-566
lines changed

14 files changed

+798
-566
lines changed

TODO.txt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ pending hyperdb: range searching of values (dates in particular)
1414
[value, value, ...] implies "in"
1515
pending hyperdb: make creator, creation and activity available pre-commit
1616
pending hyperdb: migrate "id" property to be Number type
17-
pending hyperdb: allow classes to define their ordering (properties, asc/desc)
1817
pending instance: including much simpler upgrade path and the use of
1918
non-Python configuration files (ConfigParser)
2019
pending instance: split instance.open() into open() and login()
@@ -34,25 +33,27 @@ pending project: have the demo allow anonymous login
3433
pending security: at least an LDAP user database implementation
3534
pending security: authenticate over a secure connection
3635
pending security: use digital signatures in mailgw
36+
pending security: submission protection
3737
pending web: I18N
3838
pending web: Better message summary display (feature request #520244)
3939
pending web: Navigating around the issues (feature request #559149)
40-
pending web: Re-enable link backrefs from messages (feature request #568714)
4140
pending web: Quick help links next to the property labels giving a
4241
description of the property. Combine with help for the actual
4342
form element too, eg. how to use the nosy list edit box.
4443
pending web: clicking on a group header should filter for that type of entry
4544
pending web: re-enable auth by basic http auth
4645

47-
New templating TODO
46+
New templating TODO:
47+
. generic class editing
4848
. classhelp
4949
. query saving
50-
. search page is a shambles
51-
. view customisation is a shambles
52-
. style is a shambles
50+
. search "refinement" (pre-fill the search page with the current search
51+
parameters)
52+
. security on actions (only allows/enforces generic Edit perm on the class :()
5353

5454
ongoing: any bugs
5555

56+
done web: Re-enable link backrefs from messages (feature request #568714) (RJ)
5657
done web: have the page layout (header/footer) be templatable (RJ)
5758
done web: fixing the templating so it works (RJ)
5859
done web: re-work cgi interface to abstract out the explicit "issue"

roundup/backends/back_anydbm.py

Lines changed: 92 additions & 104 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: back_anydbm.py,v 1.65 2002-08-30 08:35:45 richard Exp $
18+
#$Id: back_anydbm.py,v 1.66 2002-09-01 04:32:30 richard Exp $
1919
'''
2020
This module defines a backend that saves the hyperdatabase in a database
2121
chosen by anydbm. It is guaranteed to always be available in python
@@ -1471,8 +1471,8 @@ def filter(self, search_matches, filterspec, sort, group,
14711471
sort spec.
14721472
14731473
"filterspec" is {propname: value(s)}
1474-
"sort" is ['+propname', '-propname', 'propname', ...]
1475-
"group is ['+propname', '-propname', 'propname', ...]
1474+
"sort" and "group" are (dir, prop) where dir is '+', '-' or None
1475+
and prop is a prop name or None
14761476
"search_matches" is {nodeid: marker}
14771477
'''
14781478
cn = self.classname
@@ -1591,126 +1591,109 @@ def filter(self, search_matches, filterspec, sort, group,
15911591
k.append(v)
15921592
l = k
15931593

1594-
# optimise sort
1595-
m = []
1596-
for entry in sort:
1597-
if entry[0] != '-':
1598-
m.append(('+', entry))
1599-
else:
1600-
m.append((entry[0], entry[1:]))
1601-
sort = m
1602-
1603-
# optimise group
1604-
m = []
1605-
for entry in group:
1606-
if entry[0] != '-':
1607-
m.append(('+', entry))
1608-
else:
1609-
m.append((entry[0], entry[1:]))
1610-
group = m
16111594
# now, sort the result
16121595
def sortfun(a, b, sort=sort, group=group, properties=self.getprops(),
16131596
db = self.db, cl=self):
16141597
a_id, an = a
16151598
b_id, bn = b
16161599
# sort by group and then sort
1617-
for list in group, sort:
1618-
for dir, prop in list:
1619-
# sorting is class-specific
1620-
propclass = properties[prop]
1600+
for dir, prop in group, sort:
1601+
if dir is None: continue
16211602

1622-
# handle the properties that might be "faked"
1623-
# also, handle possible missing properties
1624-
try:
1625-
if not an.has_key(prop):
1626-
an[prop] = cl.get(a_id, prop)
1627-
av = an[prop]
1628-
except KeyError:
1629-
# the node doesn't have a value for this property
1630-
if isinstance(propclass, Multilink): av = []
1631-
else: av = ''
1603+
# sorting is class-specific
1604+
propclass = properties[prop]
1605+
1606+
# handle the properties that might be "faked"
1607+
# also, handle possible missing properties
1608+
try:
1609+
if not an.has_key(prop):
1610+
an[prop] = cl.get(a_id, prop)
1611+
av = an[prop]
1612+
except KeyError:
1613+
# the node doesn't have a value for this property
1614+
if isinstance(propclass, Multilink): av = []
1615+
else: av = ''
1616+
try:
1617+
if not bn.has_key(prop):
1618+
bn[prop] = cl.get(b_id, prop)
1619+
bv = bn[prop]
1620+
except KeyError:
1621+
# the node doesn't have a value for this property
1622+
if isinstance(propclass, Multilink): bv = []
1623+
else: bv = ''
1624+
1625+
# String and Date values are sorted in the natural way
1626+
if isinstance(propclass, String):
1627+
# clean up the strings
1628+
if av and av[0] in string.uppercase:
1629+
av = an[prop] = av.lower()
1630+
if bv and bv[0] in string.uppercase:
1631+
bv = bn[prop] = bv.lower()
1632+
if (isinstance(propclass, String) or
1633+
isinstance(propclass, Date)):
1634+
# it might be a string that's really an integer
16321635
try:
1633-
if not bn.has_key(prop):
1634-
bn[prop] = cl.get(b_id, prop)
1635-
bv = bn[prop]
1636-
except KeyError:
1637-
# the node doesn't have a value for this property
1638-
if isinstance(propclass, Multilink): bv = []
1639-
else: bv = ''
1640-
1641-
# String and Date values are sorted in the natural way
1642-
if isinstance(propclass, String):
1643-
# clean up the strings
1644-
if av and av[0] in string.uppercase:
1645-
av = an[prop] = av.lower()
1646-
if bv and bv[0] in string.uppercase:
1647-
bv = bn[prop] = bv.lower()
1648-
if (isinstance(propclass, String) or
1649-
isinstance(propclass, Date)):
1650-
# it might be a string that's really an integer
1651-
try:
1652-
av = int(av)
1653-
bv = int(bv)
1654-
except:
1655-
pass
1636+
av = int(av)
1637+
bv = int(bv)
1638+
except:
1639+
pass
1640+
if dir == '+':
1641+
r = cmp(av, bv)
1642+
if r != 0: return r
1643+
elif dir == '-':
1644+
r = cmp(bv, av)
1645+
if r != 0: return r
1646+
1647+
# Link properties are sorted according to the value of
1648+
# the "order" property on the linked nodes if it is
1649+
# present; or otherwise on the key string of the linked
1650+
# nodes; or finally on the node ids.
1651+
elif isinstance(propclass, Link):
1652+
link = db.classes[propclass.classname]
1653+
if av is None and bv is not None: return -1
1654+
if av is not None and bv is None: return 1
1655+
if av is None and bv is None: continue
1656+
if link.getprops().has_key('order'):
16561657
if dir == '+':
1657-
r = cmp(av, bv)
1658+
r = cmp(link.get(av, 'order'),
1659+
link.get(bv, 'order'))
16581660
if r != 0: return r
16591661
elif dir == '-':
1660-
r = cmp(bv, av)
1662+
r = cmp(link.get(bv, 'order'),
1663+
link.get(av, 'order'))
16611664
if r != 0: return r
1662-
1663-
# Link properties are sorted according to the value of
1664-
# the "order" property on the linked nodes if it is
1665-
# present; or otherwise on the key string of the linked
1666-
# nodes; or finally on the node ids.
1667-
elif isinstance(propclass, Link):
1668-
link = db.classes[propclass.classname]
1669-
if av is None and bv is not None: return -1
1670-
if av is not None and bv is None: return 1
1671-
if av is None and bv is None: continue
1672-
if link.getprops().has_key('order'):
1673-
if dir == '+':
1674-
r = cmp(link.get(av, 'order'),
1675-
link.get(bv, 'order'))
1676-
if r != 0: return r
1677-
elif dir == '-':
1678-
r = cmp(link.get(bv, 'order'),
1679-
link.get(av, 'order'))
1680-
if r != 0: return r
1681-
elif link.getkey():
1682-
key = link.getkey()
1683-
if dir == '+':
1684-
r = cmp(link.get(av, key), link.get(bv, key))
1685-
if r != 0: return r
1686-
elif dir == '-':
1687-
r = cmp(link.get(bv, key), link.get(av, key))
1688-
if r != 0: return r
1689-
else:
1690-
if dir == '+':
1691-
r = cmp(av, bv)
1692-
if r != 0: return r
1693-
elif dir == '-':
1694-
r = cmp(bv, av)
1695-
if r != 0: return r
1696-
1697-
# Multilink properties are sorted according to how many
1698-
# links are present.
1699-
elif isinstance(propclass, Multilink):
1665+
elif link.getkey():
1666+
key = link.getkey()
17001667
if dir == '+':
1701-
r = cmp(len(av), len(bv))
1668+
r = cmp(link.get(av, key), link.get(bv, key))
17021669
if r != 0: return r
17031670
elif dir == '-':
1704-
r = cmp(len(bv), len(av))
1671+
r = cmp(link.get(bv, key), link.get(av, key))
17051672
if r != 0: return r
1706-
elif isinstance(propclass, Number) or isinstance(propclass, Boolean):
1673+
else:
17071674
if dir == '+':
17081675
r = cmp(av, bv)
1676+
if r != 0: return r
17091677
elif dir == '-':
17101678
r = cmp(bv, av)
1711-
1712-
# end for dir, prop in list:
1713-
# end for list in sort, group:
1679+
if r != 0: return r
1680+
1681+
# Multilink properties are sorted according to how many
1682+
# links are present.
1683+
elif isinstance(propclass, Multilink):
1684+
if dir == '+':
1685+
r = cmp(len(av), len(bv))
1686+
if r != 0: return r
1687+
elif dir == '-':
1688+
r = cmp(len(bv), len(av))
1689+
if r != 0: return r
1690+
elif isinstance(propclass, Number) or isinstance(propclass, Boolean):
1691+
if dir == '+':
1692+
r = cmp(av, bv)
1693+
elif dir == '-':
1694+
r = cmp(bv, av)
1695+
1696+
# end for dir, prop in sort, group:
17141697
# if all else fails, compare the ids
17151698
return cmp(a[0], b[0])
17161699

@@ -1909,13 +1892,18 @@ def __init__(self, db, classname, **properties):
19091892
if not properties.has_key('files'):
19101893
properties['files'] = hyperdb.Multilink("file")
19111894
if not properties.has_key('nosy'):
1912-
properties['nosy'] = hyperdb.Multilink("user")
1895+
# note: journalling is turned off as it really just wastes
1896+
# space. this behaviour may be overridden in an instance
1897+
properties['nosy'] = hyperdb.Multilink("user", do_journal="no")
19131898
if not properties.has_key('superseder'):
19141899
properties['superseder'] = hyperdb.Multilink(classname)
19151900
Class.__init__(self, db, classname, **properties)
19161901

19171902
#
19181903
#$Log: not supported by cvs2svn $
1904+
#Revision 1.65 2002/08/30 08:35:45 richard
1905+
#minor edits
1906+
#
19191907
#Revision 1.64 2002/08/22 07:57:11 richard
19201908
#Consistent quoting
19211909
#

roundup/backends/back_gadfly.py

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $Id: back_gadfly.py,v 1.6 2002-08-30 08:35:16 richard Exp $
1+
# $Id: back_gadfly.py,v 1.7 2002-09-01 04:32:30 richard Exp $
22
__doc__ = '''
33
About Gadfly
44
============
@@ -1469,8 +1469,8 @@ def filter(self, search_matches, filterspec, sort, group):
14691469
sort spec
14701470
14711471
"filterspec" is {propname: value(s)}
1472-
"sort" is ['+propname', '-propname', 'propname', ...]
1473-
"group is ['+propname', '-propname', 'propname', ...]
1472+
"sort" and "group" are (dir, prop) where dir is '+', '-' or None
1473+
and prop is a prop name or None
14741474
"search_matches" is {nodeid: marker}
14751475
'''
14761476
cn = self.classname
@@ -1511,26 +1511,24 @@ def filter(self, search_matches, filterspec, sort, group):
15111511
# figure the order by clause
15121512
orderby = []
15131513
ordercols = []
1514-
if sort:
1515-
for entry in sort:
1516-
if entry[0] != '-':
1517-
orderby.append('_'+entry)
1518-
ordercols.append(entry)
1519-
else:
1520-
orderby.append('_'+entry[1:]+' desc')
1521-
ordercols.append(entry)
1514+
if sort is not None:
1515+
if sort[0] != '-':
1516+
orderby.append('_'+sort[1])
1517+
ordercols.append(sort[1])
1518+
else:
1519+
orderby.append('_'+sort[1]+' desc')
1520+
ordercols.append(sort[1])
15221521

15231522
# figure the group by clause
15241523
groupby = []
15251524
groupcols = []
1526-
if group:
1527-
for entry in group:
1528-
if entry[0] != '-':
1529-
groupby.append('_'+entry)
1530-
groupcols.append(entry)
1531-
else:
1532-
groupby.append('_'+entry[1:]+' desc')
1533-
groupcols.append(entry[1:])
1525+
if group is not None:
1526+
if group[0] != '-':
1527+
groupby.append('_'+group[1])
1528+
groupcols.append(group[1])
1529+
else:
1530+
groupby.append('_'+group[1]+' desc')
1531+
groupcols.append(group[1])
15341532

15351533
# construct the SQL
15361534
frum = ','.join(frum)
@@ -1743,13 +1741,18 @@ def __init__(self, db, classname, **properties):
17431741
if not properties.has_key('files'):
17441742
properties['files'] = hyperdb.Multilink("file")
17451743
if not properties.has_key('nosy'):
1746-
properties['nosy'] = hyperdb.Multilink("user")
1744+
# note: journalling is turned off as it really just wastes
1745+
# space. this behaviour may be overridden in an instance
1746+
properties['nosy'] = hyperdb.Multilink("user", do_journal="no")
17471747
if not properties.has_key('superseder'):
17481748
properties['superseder'] = hyperdb.Multilink(classname)
17491749
Class.__init__(self, db, classname, **properties)
17501750

17511751
#
17521752
# $Log: not supported by cvs2svn $
1753+
# Revision 1.6 2002/08/30 08:35:16 richard
1754+
# very basic filter support
1755+
#
17531756
# Revision 1.5 2002/08/23 05:33:32 richard
17541757
# implemented multilink changes (and a unit test)
17551758
#

0 commit comments

Comments
 (0)