RE: RE: Speeding up FTP upstreams
"Garth T Kidd" <garth-OnzZ1s1DREKDegMON/[email protected]> Sat, 31 Jul 2004 00:06:33 +1000
| Newsgroups | gmane.comp.pythin.pyds.devel |
|---|---|
| Organization | Deadly Bloody Serious |
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format.
------=_NextPart_000_009B_01C47692.3F040F70
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Here's another patch, chockers full of changes. PLEASE TEST BEFORE
APPLICATION: there's a lot of stuff in there. If you get into trouble,
delete the affected files (``Tool.py`` and ``WikiTool.py``) and ``cvs
update`` again to get 'em back.=20
All the changes are for the Wiki tool. Amongst them:=20
* Stray links PyDS-wide match against Wiki titles again. Oops.=20
* The toolbar is above the title, not between the title and the text. I
don't know what I was smoking, before.=20
* Breadcrumbs are generated, which is pretty handy for people like me =
that
tend to stack Wiki nodes inside each other rather than all alongside =
each
other. As usual, the user-visible breadcrumbs point to other pages. =
Yours
point back to the Wiki tool.=20
TODO: add a way to turn them off. =20
* Along with the breadcrumbs, one level of subnodes are displayed.=20
TODO: add a way to configure how deep to go, and to turn them off.=20
* There's MUCH better protection against adding nodes with invalid IDs.
Invalid IDs are adjusted before the node is saved. It's still saved, =
though,
so you won't end up caught out and losing data. You even get told why it =
was
changed, and have the opportunity to edit the ID again to fix it.=20
* If you're looking at a node and use the New button, you can set the =
parent
for the new node to be anywhere from the root of the Wiki to the node =
you
were just looking at. The default is to create a peer of the node you =
were
looking at. This is MUCH cleaner than hitting / a lot.=20
TODO: make that the default for clicking on unresolved links, also.=20
TODO: disable use of / inside the ID box now it's no longer necessary. =
* If you're using MSIE, try: Alt-N, Alt-E, Alt-V, and Alt-B. Whilst =
editing,
try Alt-S. All these have been there for ages, but I bet you didn't know
that. :)=20
* If the Wiki tool is set to level 0, you'll find the /wiki part of the =
path
isn't generated. It's all part of my Evil Plan. I'll tell you the rest
later.=20
Georg, can you suggest a better way to prevent ``addNode('index')`` in
``_initopts`` than I'm using? At present it's failing, I guess because =
the
tool level hasn't yet been set...=20
Regards,
Garth.=20
-----Original Message-----
From: pyds-dev-admin-iYtK5bfT9M//Ad8WF/[email protected]
[mailto:pyds-dev-admin-iYtK5bfT9M//Ad8WF/[email protected]] On Behalf Of Bauer, Georg
Sent: Friday, 30 July 2004 5:59 PM
To: 'Garth T Kidd'; 'List PyDS'
Cc: Peter Wilkinson
Subject: AW: [Pyds-dev] RE: Speeding up FTP upstreams
Hi!
His problems arise in the MirrorTool. That uses the RSS methods to fetch
items from tools that are hooked into the mirroring. For example =
mirroring
is used for the cloud search engine. Why PyDS thinks there is some =
posting
that doesn't exist is beyond me - Peter does have a bit weird =
installation,
so maybe his data file is borked.
Garth: I added both your patches. I changed the patch to getRSSItem, =
though,
because you returned None. If people access methods via XMLRPC, this =
would
pose a problem, as None can't be transported by XMLRPC, so I changed the
return value to {} (empty hash).
bye, Georg
-----Urspr=FCngliche Nachricht-----
Von: Garth T Kidd [mailto:garth-OnzZ1s1DREKDegMON/[email protected]]
Gesendet: Freitag, 30. Juli 2004 07:19
An: 'List PyDS'
Cc: Peter Wilkinson
Betreff: [Pyds-dev] RE: Speeding up FTP upstreams
I'm not entirely sure why WeblogTool is trying to RSS-render items that
don't exist, but hopefully the attached patch will help Peter's =
`upstreaming
woes`__.
__ http://www.pycs.net/users/0000348/weblog/2004/07/28.html#P403
Regards,
Garth.=20
_______________________________________________
Pyds-dev mailing list
Pyds-dev-iYtK5bfT9M//Ad8WF/[email protected]
http://www.westfalen.de/cgi-bin/mailman/listinfo/pyds-dev
------=_NextPart_000_009B_01C47692.3F040F70
Content-Type: application/octet-stream;
name="20040730-2342-ratherlarge.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="20040730-2342-ratherlarge.diff"
? .pyds.css.swp
? Settings
? Thumbs.db
? and
? in.txt
? out.txt
? testSomething.py
? PyDS/.Tool.py.swp
Index: pyds.css
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /pyds/PyDS/pyds.css,v
retrieving revision 1.24
diff -c -r1.24 pyds.css
*** pyds.css 6 Jul 2004 08:30:36 -0000 1.24
--- pyds.css 30 Jul 2004 12:54:21 -0000
***************
*** 29,34 ****
--- 29,38 ----
*/
=20
/* basic styles */
+ #toolbar input {
+ text-padding: 1px;
+ font-size: 10px;
+ }
body {
font-family: verdana, sans-serif;
background-color: white;
***************
*** 141,146 ****
--- 145,162 ----
padding: 0.25em;
text-align: right;
font-size: 0.8em;
+ }
+ .wikicrumbs {
+ background-color: #f0fff0;
+ /* border: solid;
+ border-color: green;
+ border-width: 1px; */
+ padding: 0.25em;
+ text-align: left;
+ font-size: 0.8em;
+ }
+ .undefinedwikicrumb {
+ color: red;=20
}
=20
/* message/text styles */
Index: PyDS/MeshTool.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /pyds/PyDS/PyDS/MeshTool.py,v
retrieving revision 1.27
diff -c -r1.27 MeshTool.py
*** PyDS/MeshTool.py 14 Jul 2004 15:55:18 -0000 1.27
--- PyDS/MeshTool.py 20 Jul 2004 06:14:32 -0000
***************
*** 396,402 ****
instance. The latter should have already been walked over the
document. `itemDetail` should be an `ItemDetail` object =
corresponding=20
to the source being rendered, or None."""
! PyDS.Tool.traceargs()
docutils.nodes.SparseNodeVisitor.__init__(self, document)
self.targetVisitor =3D targetVisitor
self.foundTools =3D toolsWithStrayLinkResolvers()
--- 396,402 ----
instance. The latter should have already been walked over the
document. `itemDetail` should be an `ItemDetail` object =
corresponding=20
to the source being rendered, or None."""
! # PyDS.Tool.traceargs()
docutils.nodes.SparseNodeVisitor.__init__(self, document)
self.targetVisitor =3D targetVisitor
self.foundTools =3D toolsWithStrayLinkResolvers()
Index: PyDS/Tool.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /pyds/PyDS/PyDS/Tool.py,v
retrieving revision 1.192
diff -c -r1.192 Tool.py
*** PyDS/Tool.py 15 Jul 2004 14:10:01 -0000 1.192
--- PyDS/Tool.py 30 Jul 2004 13:49:54 -0000
***************
*** 1728,1745 ****
mainindex =3D 0
if toolname =3D=3D None:
toolname =3D self.name
if year and month and day:
! dn =3D os.path.join(_PyDS.ROOTDIR, toolname, category,
'%04d' % year,
'%02d' % month)
fn =3D os.path.join(dn, '%02d.html' % day)
elif year and month:
! dn =3D os.path.join(_PyDS.ROOTDIR, toolname, category,
'%04d' % year,
'%02d' % month)
fn =3D os.path.join(dn, page)
else:
! dn =3D os.path.join(_PyDS.ROOTDIR, toolname, category)
d, f =3D os.path.split(page) # WikiTool specifying paths in `page`
if d:=20
dn =3D os.path.join(dn, d)
--- 1728,1749 ----
mainindex =3D 0
if toolname =3D=3D None:
toolname =3D self.name
+ if toolname =3D=3D 'wiki' and self.level =3D=3D 0:=20
+ toolRoot =3D _PyDS.ROOTDIR
+ else:=20
+ toolRoot =3D os.path.join(_PyDS.ROOTDIR, toolname)
if year and month and day:
! dn =3D os.path.join(toolRoot, category,
'%04d' % year,
'%02d' % month)
fn =3D os.path.join(dn, '%02d.html' % day)
elif year and month:
! dn =3D os.path.join(toolRoot, category,
'%04d' % year,
'%02d' % month)
fn =3D os.path.join(dn, page)
else:
! dn =3D os.path.join(toolRoot, category)
d, f =3D os.path.split(page) # WikiTool specifying paths in `page`
if d:=20
dn =3D os.path.join(dn, d)
***************
*** 1854,1860 ****
# get flat filenames instead of structured directories. This is
# usefull for exports to CD-ROM or stuff like that. In that case,
# base is usually '/'
! def getStaticUrl(self, page=3DNone, tool=3DNone, year=3DNone, =
month=3DNone, day=3DNone, category=3D'', base=3DNone, flat=3D0):
if not(page) and year and month and day:
page =3D '%04d/%02d/%02d.html' % (year, month, day)
elif not(page) and year and month:
--- 1858,1865 ----
# get flat filenames instead of structured directories. This is
# usefull for exports to CD-ROM or stuff like that. In that case,
# base is usually '/'
! def getStaticUrl(self, page=3DNone, tool=3DNone, year=3DNone, =
month=3DNone, day=3DNone, category=3D'', base=3DNone, flat=3D0, =
stripToolPrefix=3D0):
! # traceargs()
if not(page) and year and month and day:
page =3D '%04d/%02d/%02d.html' % (year, month, day)
elif not(page) and year and month:
***************
*** 1865,1870 ****
--- 1870,1876 ----
tool =3D self.getToolByNamespace(tool)
else:
tool =3D self
+ # PyDS.Tool.debugOutput("tool level: %d" % tool.level)
if not(base):
upstream =3D self.getToolByNamespace('upstream')
base =3D upstream.get('prefs','cloudurl')
***************
*** 1878,1888 ****
else:
return '%s%s-%s' % (base, tool.name, page)
else:
url =3D ''
if category:
! url =3D '%s%s/%s/%s' % (base, tool.name, category, page)
else:
! url =3D '%s%s/%s' % (base, tool.name, page)
if len(url) >=3D 11 and url[-11:] =3D=3D '/index.html':
url =3D url[:-10]
return url
--- 1884,1899 ----
else:
return '%s%s-%s' % (base, tool.name, page)
else:
+ # print "Tool level: %d" % tool.level
+ if stripToolPrefix and tool.level=3D=3D0:=20
+ toolPart =3D ''
+ else:=20
+ toolPart =3D '%s/' % tool.name
url =3D ''
if category:
! url =3D '%s%s%s/%s' % (base, toolPart, category, page)
else:
! url =3D '%s%s%s' % (base, toolPart, page)
if len(url) >=3D 11 and url[-11:] =3D=3D '/index.html':
url =3D url[:-10]
return url
Index: PyDS/WikiTool.py
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /pyds/PyDS/PyDS/WikiTool.py,v
retrieving revision 1.26
diff -c -r1.26 WikiTool.py
*** PyDS/WikiTool.py 15 Jul 2004 22:08:09 -0000 1.26
--- PyDS/WikiTool.py 30 Jul 2004 13:33:52 -0000
***************
*** 78,94 ****
def _initopts(self):
self.rss =3D 1
self.showCalendar =3D0=20
! if self._getNode('index') is None:=20
# If I add a preference for rendering Wiki pages to the main site=20
# rather than a tool-specific subdirectory, I'll need to suppress=20
# automatic creation of this file.=20
self.addNode('index',=20
_("Wiki Index"),=20
! _("Edit this page to begin your Wiki"))
if self._getNode('404') is None:=20
self.addNode('404',=20
_("Unresolved Target"),=20
! _("Not-yet-resolved links in the Wiki are pointed here."))
=09
def _initactive(self):
navigation =3D self.getToolByNamespace('navigation')
--- 78,94 ----
def _initopts(self):
self.rss =3D 1
self.showCalendar =3D0=20
! if self.level>0 and self._getNode('index') is None:=20
# If I add a preference for rendering Wiki pages to the main site=20
# rather than a tool-specific subdirectory, I'll need to suppress=20
# automatic creation of this file.=20
self.addNode('index',=20
_("Wiki Index"),=20
! _("Edit this page to begin your Wiki"))
if self._getNode('404') is None:=20
self.addNode('404',=20
_("Unresolved Target"),=20
! _("Not-yet-resolved links in the Wiki are pointed =
here."))
=09
def _initactive(self):
navigation =3D self.getToolByNamespace('navigation')
***************
*** 156,168 ****
# this method returns an URL to the cloud in the context of the =
current tool
# or the given tool. Weblog patches the URL if radio compatibility is =
requested.
def getStaticUrl(self, page=3DNone, tool=3DNone, year=3DNone, =
month=3DNone, day=3DNone, category=3D'', base=3DNone, flat=3D0):
! if filter(None, (year, month, day, category)):=20
! pass # aah, ignore it for the time being=20
! # raise NotImplementedError, _("argument not supported by Wiki =
tool")
! if page is None:=20
! pass # aah, ignore it for the time being
! # raise ValueError, _("page argument required by Wiki tool")
! url =3D PyDS.Tool.StandardTool.getStaticUrl(self, page, tool, year, =
month, day, category, base, flat)
return url
=20
# This method returns the URL for a node. Depending on context it
--- 156,165 ----
# this method returns an URL to the cloud in the context of the =
current tool
# or the given tool. Weblog patches the URL if radio compatibility is =
requested.
def getStaticUrl(self, page=3DNone, tool=3DNone, year=3DNone, =
month=3DNone, day=3DNone, category=3D'', base=3DNone, flat=3D0):
! url =3D PyDS.Tool.StandardTool.getStaticUrl(self, page, tool, year,=20
! month, day, category,=20
! base, flat, stripToolPrefix=3D1)
! # PyDS.Tool.debugOutput("=3D> %s" % url)
return url
=20
# This method returns the URL for a node. Depending on context it
***************
*** 210,216 ****
# baseid match
lambda: baseid =3D=3D m,=20
# title match
! lambda: m =3D=3D _munge(node.title()),
)
=20
# prepare filter results dictionary
--- 207,213 ----
# baseid match
lambda: baseid =3D=3D m,=20
# title match
! lambda: m =3D=3D _munge(node.title),
)
=20
# prepare filter results dictionary
***************
*** 278,286 ****
# Return a link to a creation page for an item, based on link text.=20
def getDesktopCreateLinkDetailsForProposedLinkText(self, linkText):=20
"""Return the edit URL for a non-existent item, based on =
`linkText`."""
return ('undefinednode',=20
! self.getUrl('edit_html', id=3D_munge(linkText)),
! _("Create this item in WikiTool"))
=20
# Render an item by its unique ID
def renderItemByUniqueId(self, uniqueId):
--- 275,296 ----
# Return a link to a creation page for an item, based on link text.=20
def getDesktopCreateLinkDetailsForProposedLinkText(self, linkText):=20
"""Return the edit URL for a non-existent item, based on =
`linkText`."""
+ # split linkText into words on whitespace
+ words =3D re.split(r"\s+", str(linkText))
+ # remove non-alphanumerics from each word
+ words =3D [re.sub(r"\W", '', word) for word in words]
+ # capitalise each word
+ words =3D [word[0:1].upper() + word[1:].lower() for word in words]
+ # string 'em together
+ id =3D ''.join(words)
+ # figure out our Wiki context, and prepend it if found
+ concatid =3D _flet.get('categoryid', '').lower()
+ if concatid:=20
+ id =3D '/'.join(concatid, id)
+ # et voila!=20
return ('undefinednode',=20
! self.getUrl('edit_html', id=3Did),
! _("Create this item in WikiTool"))
=20
# Render an item by its unique ID
def renderItemByUniqueId(self, uniqueId):
***************
*** 323,333 ****
html =3D [_("<h3>Your Wiki Nodes</h3>")]
append =3D html.append
editvars =3D {
! 'edit_html': self.getUrl('edit_html'),
'editlabel': _("New")
}
! append('<form action=3D"%(edit_html)s" method=3D"GET">' % editvars)
! append('<input type=3D"submit" value=3D"%(editlabel)s" =
accesskey=3D"n">' % editvars)
hashedNodes =3D {}
for node in self.nodes:=20
nids =3D _splitPath(node.id)
--- 333,344 ----
html =3D [_("<h3>Your Wiki Nodes</h3>")]
append =3D html.append
editvars =3D {
! 'edit_html': self.getUrl('mux_redir'),=20
'editlabel': _("New")
}
! append('<div id=3D"toolbar"><form action=3D"%(edit_html)s" =
method=3D"POST">' % editvars)
! append('<input type=3D"submit" name=3D"WikiNew" =
value=3D"%(editlabel)s" accesskey=3D"n"></div>' % editvars)
!=20
hashedNodes =3D {}
for node in self.nodes:=20
nids =3D _splitPath(node.id)
***************
*** 371,376 ****
--- 382,392 ----
macros =3D self.getToolByNamespace('macros')
id =3D req.getFirstValue('id')
node =3D self.getNode(id)
+ subnodes =3D req.getFirstValue('subnodes')
+ if 1: # subnodes and subnodes=3D=3D'yes':=20
+ subnodehtml =3D self.renderSubNodes(id, depthLimit=3D1)
+ else:=20
+ subnodehtml =3D ''
template =3D ''
if node.get('template',0):
template =3D _(' (Template)')
***************
*** 378,402 ****
# _flet.begin(categoryid=3Dnode.get('categoryid',''), id=3Did)
rendered =3D req.renderText(
node.get('text',_('This node has no text.')),=20
! structured =3D 1,
uniqueId =3D id,=20
! homeTool =3D self)
! # breadcrumbs
! nids =3D _splitPath(id)
! sofar =3D ''
! crumbs =3D ['<strong><a href=3D"%s">%s</a></strong>' % =
(self.getUrl('index_html'), _('Wiki'))]
! for nid in nids:=20
! if sofar:=20
! sofar =3D sofar + '/' + nid
! else:=20
! sofar =3D nid
! if self._getNode(sofar) is None:=20
! cssclass =3D 'undefinednode'
! else:=20
! cssclass =3D 'node'
! crumbs.append('<a class=3D"%s" href=3D"%s">%s</a>' % (
! cssclass, self.getUrl('show_html', id=3Dsofar), nid
! ))
viewhtml =3D ''
if not(node.get('template',0)):
viewhtml =3D '<input type=3D"submit" name=3D"WikiView" =
value=3D"%(viewlabel)s" accesskey=3D"v">' % {
--- 394,402 ----
# _flet.begin(categoryid=3Dnode.get('categoryid',''), id=3Did)
rendered =3D req.renderText(
node.get('text',_('This node has no text.')),=20
! structured =3D 2, # TODO: check 'structured' pref
uniqueId =3D id,=20
! homeTool =3D self)=20
viewhtml =3D ''
if not(node.get('template',0)):
viewhtml =3D '<input type=3D"submit" name=3D"WikiView" =
value=3D"%(viewlabel)s" accesskey=3D"v">' % {
***************
*** 404,430 ****
'viewurl': self.getStaticUrl(page=3D'%s.html' % id),
}
html =3D """\
! <p>%(crumbs)s</p>
! <h2>%(title)s%(template)s</h2>
! <form action=3D"%(mux_redir)s" method=3D"POST">
<input type=3D"hidden" name=3D"id" value=3D"%(id)s">
<input type=3D"submit" name=3D"WikiEdit" value=3D"%(editlabel)s" =
accesskey=3D"e">
<input type=3D"submit" name=3D"WikiDelete" value=3D"%(deletelabel)s">
%(viewhtml)s
<input type=3D"submit" name=3D"WikiClone" value=3D"%(clonelabel)s" =
accesskey=3D"c">
<input type=3D"submit" name=3D"WikiBlog" value=3D"%(bloglabel)s" =
accesskey=3D"b">
! </form>
%(rendered)s
<p align=3D"right" class=3D"smallfont">%(lastlabel)s =
%(pubtimestr)s</p>
<p align=3D"right"><a href=3D"%(toolurl)s" =
accesskey=3D"i">%(index)s</a></p>""" % {
! 'title': node.get('title',_('Set your page title here')),=20
! 'crumbs': ' / '.join(crumbs),=20
'mux_redir': self.getUrl('mux_redir'),
'id': str(id),=20
'editlabel': _("Edit"),=20
'deletelabel': _("Delete"),=20
'clonelabel': _("Clone"),
'bloglabel': _("Blog"),
'rendered': rendered,=20
'lastlabel': _("last change"),=20
'pubtimestr': macros.Today(node.get('pubtime',time.time()), =
withtime=3D1),=20
--- 404,438 ----
'viewurl': self.getStaticUrl(page=3D'%s.html' % id),
}
html =3D """\
! %(breadcrumbs)s
! %(subnodes)s
! <div id=3D"toolbar"><form action=3D"%(mux_redir)s" method=3D"POST">
<input type=3D"hidden" name=3D"id" value=3D"%(id)s">
+ <input type=3D"hidden" name=3D"concatid" value=3D"%(concatid)s">
+ <input type=3D"submit" name=3D"WikiNew" value=3D"%(newlabel)s" =
accesskey=3D"n">
<input type=3D"submit" name=3D"WikiEdit" value=3D"%(editlabel)s" =
accesskey=3D"e">
<input type=3D"submit" name=3D"WikiDelete" value=3D"%(deletelabel)s">
%(viewhtml)s
<input type=3D"submit" name=3D"WikiClone" value=3D"%(clonelabel)s" =
accesskey=3D"c">
<input type=3D"submit" name=3D"WikiBlog" value=3D"%(bloglabel)s" =
accesskey=3D"b">
! <!-- input type=3D"submit" name=3D"WikiSubNodes" =
value=3D"%(subnodeslabel)s" accesskey=3D"s" -->
! </form></div>
! <h2>%(title)s%(template)s</h2>
%(rendered)s
<p align=3D"right" class=3D"smallfont">%(lastlabel)s =
%(pubtimestr)s</p>
<p align=3D"right"><a href=3D"%(toolurl)s" =
accesskey=3D"i">%(index)s</a></p>""" % {
! 'title': cgi.escape(node.get('title',_('Set your page title =
here'))),=20
! 'breadcrumbs': self.renderBreadCrumbs(id, startWithTool=3D1),=20
! 'subnodes': subnodehtml,=20
'mux_redir': self.getUrl('mux_redir'),
'id': str(id),=20
+ 'concatid': '/'.join(_splitPath(str(id))[:-1]),=20
+ 'newlabel': _("New"),=20
'editlabel': _("Edit"),=20
'deletelabel': _("Delete"),=20
'clonelabel': _("Clone"),
'bloglabel': _("Blog"),
+ 'subnodeslabel': _("SubNodes"),
'rendered': rendered,=20
'lastlabel': _("last change"),=20
'pubtimestr': macros.Today(node.get('pubtime',time.time()), =
withtime=3D1),=20
***************
*** 440,445 ****
--- 448,460 ----
id =3D req.getFirstValue('id')
if not id:=20
id =3D ''
+ if req.getFirstValue('WikiNew'):=20
+ concatid =3D id # req.getFirstValue('concatid')
+ if concatid:=20
+ id =3D concatid + '/<new node>'
+ else:=20
+ id =3D '<new node>'
+ return self.getUrl('edit_html', id=3Dstr(id), title=3D'', =
text=3D'')
if req.getFirstValue('WikiEdit'):=20
return self.getUrl('edit_html', id=3Dstr(id))
if req.getFirstValue('WikiClone'):=20
***************
*** 455,460 ****
--- 470,477 ----
ptitle=3Dnode['title'],
plink=3Dself.getStaticUrl(page=3D'%s.html' % id)
)
+ if req.getFirstValue('WikiSubNodes'):=20
+ return self.getUrl('show_html', id=3Dstr(id), subnodes=3D'yes')
return self.getUrl('show_html', id=3Dstr(id))
=20
def delete_html(self, req):
***************
*** 462,475 ****
id =3D req.getFirstValue('id')
node =3D self.getNode(id)
html =3D """\
! %(rendered)s
! <form action=3D"%(delete_redir)s" method=3D"POST">
<input type=3D"hidden" name=3D"id" value=3D"%(id)s">
<input type=3D"submit" name=3D"WikiDeleteConfirm" =
value=3D"%(confirmlabel)s" accesskey=3D"d">
<input type=3D"submit" name=3D"WikiDeleteCancel" =
value=3D"%(cancellabel)s" accesskey=3D"c">
! </form>
<p align=3D"right" class=3D"smallfont">%(lastlabel)s =
%(pubtimestr)s</p>""" % {
! 'title': node['title'],=20
'show_html': self.getUrl('show_html', id=3Dstr(id)),=20
'delete_redir': self.getUrl('delete_redir', id=3Dstr(id)),=20
'id': str(id),=20
--- 479,494 ----
id =3D req.getFirstValue('id')
node =3D self.getNode(id)
html =3D """\
! %(breadcrumbs)s
! <div id=3D"toolbar"><form action=3D"%(delete_redir)s" method=3D"POST">
<input type=3D"hidden" name=3D"id" value=3D"%(id)s">
<input type=3D"submit" name=3D"WikiDeleteConfirm" =
value=3D"%(confirmlabel)s" accesskey=3D"d">
<input type=3D"submit" name=3D"WikiDeleteCancel" =
value=3D"%(cancellabel)s" accesskey=3D"c">
! </form></div>
! <h2>%(title)s</h2>
! %(rendered)s
<p align=3D"right" class=3D"smallfont">%(lastlabel)s =
%(pubtimestr)s</p>""" % {
! 'title': cgi.escape(node['title']),=20
'show_html': self.getUrl('show_html', id=3Dstr(id)),=20
'delete_redir': self.getUrl('delete_redir', id=3Dstr(id)),=20
'id': str(id),=20
***************
*** 477,489 ****
'confirmlabel': _("Confirm Deletion"),=20
'rendered': req.renderText(
node['text'],=20
! structured =3D 1,=20
#categoryid=3Dnode['categoryid'],=20
#id=3Did,
uniqueId =3D id,=20
homeTool =3D self),
'lastlabel': _("last change"),=20
'pubtimestr': macros.Today(node['pubtime'], withtime=3D1),=20
}
req.setLocalValue('title', node['title'])
return req.renderPage('BaseTemplate', body=3Dhtml, title=3D"Wiki: =
Delete: %s" % node.get('title', '(no title)'))
--- 496,509 ----
'confirmlabel': _("Confirm Deletion"),=20
'rendered': req.renderText(
node['text'],=20
! structured =3D 2, # TODO: check 'structured' pref
#categoryid=3Dnode['categoryid'],=20
#id=3Did,
uniqueId =3D id,=20
homeTool =3D self),
'lastlabel': _("last change"),=20
'pubtimestr': macros.Today(node['pubtime'], withtime=3D1),=20
+ 'breadcrumbs': self.renderBreadCrumbs(id, startWithTool=3D1),
}
req.setLocalValue('title', node['title'])
return req.renderPage('BaseTemplate', body=3Dhtml, title=3D"Wiki: =
Delete: %s" % node.get('title', '(no title)'))
***************
*** 517,536 ****
node['title'] =3D self.getNode(template)['title']
node['text'] =3D self.getNode(template)['text']
values =3D {}=20
! for field in ['id', 'title', 'text']:=20
! value =3D cgi.escape(node.get(field,id))
! values[field+'value'] =3D value
for field in ['Id', 'Title', 'Text', 'delete', 'save']:=20
values[field.lower()+'label'] =3D _(field)
values['edit_redir'] =3D self.getUrl('edit_redir')
values['templatelabel'] =3D _('Template')
values['templateselect'] =3D macros.checkBox('template', =
node.get('template',0))
html =3D """
<form action=3D"%(edit_redir)s" method=3D"POST">
<table border=3D0>
<tr>
<th align=3D"right">%(idlabel)s</th>
! <td><input name=3D"oldid" value=3D"%(idvalue)s" type=3D"hidden">
<input name=3D"id" value=3D"%(idvalue)s" size=3D50></td>
</tr><tr>
<th align=3D"right">%(titlelabel)s</th>
--- 537,592 ----
node['title'] =3D self.getNode(template)['title']
node['text'] =3D self.getNode(template)['text']
values =3D {}=20
! values['idvalue'] =3D node.get('id', id)
! values['titlevalue'] =3D node.get('title', '')
! values['textvalue'] =3D node.get('text', '')
for field in ['Id', 'Title', 'Text', 'delete', 'save']:=20
values[field.lower()+'label'] =3D _(field)
values['edit_redir'] =3D self.getUrl('edit_redir')
values['templatelabel'] =3D _('Template')
values['templateselect'] =3D macros.checkBox('template', =
node.get('template',0))
+ =09
+ # Make a copy of the full ID before we truncate it
+ values['oldidvalue'] =3D values['idvalue']
+ =09
+ # Try and figure out the context selector
+ catids =3D []
+ segs =3D _splitPath(id)
+ values['idvalue'] =3D segs[-1]
+ for seg in segs[:-1]:=20
+ if catids:=20
+ catids.append('%s/%s' % (catids[-1], seg))
+ else:=20
+ catids.append(seg)
+ catids.reverse()
+ catids.append(_("(The Wiki)"))
+ if node or len(catids)<2:=20
+ catidvalue =3D catids[0]
+ else:=20
+ catidvalue =3D catids[1]
+ values['breadcrumbs'] =3D self.renderBreadCrumbs(catids[0], =
startWithTool=3D1)
+ catidoptions =3D []
+ for catid in catids:=20
+ if catid =3D=3D catidvalue:=20
+ selected =3D ' selected'
+ else:=20
+ selected =3D ''
+ catidoptions.append('<option value=3D"%s"%s>%s</option>' % (
+ cgi.escape(catid), selected, cgi.escape(catid)))
+ values['catidoptions'] =3D '\n'.join(catidoptions)
+=20
+ # Now for the text
html =3D """
+ %(breadcrumbs)s
<form action=3D"%(edit_redir)s" method=3D"POST">
<table border=3D0>
<tr>
+ <th align=3D"right">Context</th>
+ <td><select name=3D"catid">%(catidoptions)s
+ </select></td>
+ </tr><tr>
<th align=3D"right">%(idlabel)s</th>
! <td><input name=3D"oldid" value=3D"%(oldidvalue)s" type=3D"hidden">
<input name=3D"id" value=3D"%(idvalue)s" size=3D50></td>
</tr><tr>
<th align=3D"right">%(titlelabel)s</th>
***************
*** 561,585 ****
self.deleteNode(id)
return self.getUrl()
=20
def edit_redir(self, req):
! id, oldid, title, text, desc, template =3D map(req.getFirstValue,=20
! ('id', 'oldid', 'title', 'text', 'desc', 'template'))
! id =3D _normPath(id)
if req.getFirstValue('WikiDelete'):
return self.getUrl('delete_html', id=3Dstr(id))
else:
if not id:
id =3D ''
! if oldid and text and oldid !=3D id:=20
! self.renameNode(oldid, id, renderNew=3D0)
! if id and text:
! id =3D self.addNode(id, title, text, template=3Dint(template))
! return self.getUrl('show_html', id=3Dstr(id))
! else:
if id:
return self.getUrl('edit_html', id=3Dstr(id), errmsg=3D_('You =
need to give id and text!'))
else:
return self.getUrl('edit_html', errmsg=3D_('You need to give id =
and text!'))
=20
# this method renames an existing node
def renameNode(self, id, newid, renderNew=3D1):=20
--- 617,683 ----
self.deleteNode(id)
return self.getUrl()
=20
+ def invalid_id(self, id):=20
+ "Is the ID invalid? Why?"
+ if ' ' in id:=20
+ return _("Spaces not allowed.")
+ if re.match(r"^[\\\/].*", id):=20
+ return _("Can't start with a slash.")
+ if re.match(r"^.*[\\\/]$", id):=20
+ return _("Can't end with a slash.")
+ if not re.match(r"^\w+([\\\/]\w+)*$", id):=20
+ return _("Can't figure out exactly why. Probably a non-alphanumeric =
character.")
+ splits =3D _splitPath(id)
+ first =3D splits[0]
+ try:=20
+ tool =3D self.getToolByNamespace(first.lower())=20
+ return _("First path component %s conflicts with a tool name") % =
repr(first)
+ except KeyError:=20
+ pass
+ if re.match(r"^[0-9]{4}$", first):=20
+ return _("First path component %s might conflict with a year") % =
repr(first)
+ return ''
+=20
+ def fixid(self, id):=20
+ "Return a FixId for the invalid id."
+ if id:=20
+ return '%s%s' % (
+ time.strftime("%Y%m%d%H%M_"),=20
+ _munge(id))
+ else:
+ return ''
+ =09
def edit_redir(self, req):
! catid, id, oldid, title, text, desc, template =3D =
map(req.getFirstValue,=20
! ('catid', 'id', 'oldid', 'title', 'text', 'desc', 'template'))
if req.getFirstValue('WikiDelete'):
return self.getUrl('delete_html', id=3Dstr(id))
else:
if not id:
id =3D ''
! errmsg =3D self.invalid_id(id)
! if errmsg:=20
! id =3D self.fixid(id)
! # if we have a context, use it -- unless it starts with a=20
! # bracket, in which case the context is the Wiki itself
! if catid and catid[0] !=3D '(':=20
! id =3D '/'.join((catid, id))
! if not text:=20
if id:
return self.getUrl('edit_html', id=3Dstr(id), errmsg=3D_('You =
need to give id and text!'))
else:
return self.getUrl('edit_html', errmsg=3D_('You need to give id =
and text!'))
+ id =3D _normPath(id)
+ if oldid and text and oldid !=3D id:=20
+ self.renameNode(oldid, id, renderNew=3D0)
+ id =3D self.addNode(id, title, text, template=3Dint(template))
+ if errmsg:=20
+ errmsg =3D ' '.join([
+ _("Adjusted invalid ID before saving your record: "),=20
+ errmsg])
+ return self.getUrl('edit_html', id=3Dstr(id), errmsg=3Derrmsg)
+ else:=20
+ return self.getUrl('show_html', id=3Dstr(id))
=20
# this method renames an existing node
def renameNode(self, id, newid, renderNew=3D1):=20
***************
*** 611,616 ****
--- 709,715 ----
meshTool.delItem(id, self)
finally: self._release()
=20
+ # This method deletes the rendered output for a given node.=20
def _deleteRenderedNode(self, id, dummy):
self.logVerbose("Deleting rendered output for Wiki node %s", id)
self.deleteFile('%s.html' % id)
***************
*** 624,632 ****
=09
# Internal getNode; returns the row, not a dict.
def _getNode(self, id):=20
! (res,found) =3D self.nodes.locate({'id':id})
! if found: return self.nodes[res]
! else: return None
=20
# get a posting by ID
def getNode(self, id):
--- 723,738 ----
=09
# Internal getNode; returns the row, not a dict.
def _getNode(self, id):=20
! try:
! # self._acquire()
! (res,found) =3D self.nodes.locate({'id':id})
! if found:=20
! return self.nodes[res]
! else:=20
! return None
! finally:=20
! # self._release
! pass
=20
# get a posting by ID
def getNode(self, id):
***************
*** 776,782 ****
--- 882,980 ----
msg +=3D '<br>%s[%s] in %s' % (file, line, function)
self.logError(msg.replace('%', '%%'))
=20
+ def renderBreadCrumbs(self, id, startWithTool=3D0, skipLevels=3D0, =
nodiv=3D0):=20
+ nids =3D _splitPath(id)
+ sofar =3D ''
+ crumbs =3D []
+ if startWithTool:=20
+ crumbs.append('<strong><a href=3D"%s" =
class=3D"wikicrumb">%s</a></strong>' % (
+ self.getUrl('index_html'), _('Wiki')))
+ levels =3D 0
+ for nid in nids:=20
+ if sofar:=20
+ sofar =3D sofar + '/' + nid
+ else:=20
+ sofar =3D nid
+ levels =3D levels + 1
+ if levels <=3D skipLevels:
+ continue
+ found =3D self._getNode(sofar) is not None
+ if not _flet.desktop:=20
+ if found:=20
+ cssclass =3D 'wikicrumb'
+ target =3D self.getCloudUrlForNode(sofar)
+ crumbs.append('<a class=3D"%s" href=3D"%s">%s</a>' % (
+ cssclass, target, nid))
+ else:=20
+ cssclass =3D 'undefinedwikicrumb'
+ crumbs.append('<span class=3D"%s">%s</span>' % (
+ cssclass, nid))
+ else:=20
+ if found:=20
+ cssclass =3D 'wikicrumb'
+ target =3D self.getCloudUrlForNode(sofar)
+ else:=20
+ cssclass =3D 'undefinedwikicrumb'
+ target =3D self.getUrl('show_html', id=3Dsofar)
+ crumbs.append('<a class=3D"%s" href=3D"%s">%s</a>' % (
+ cssclass, target, nid))
+ crumbhtml =3D '<span class=3D"wikicrumbs">%s</span>\n' % =
(' / '.join(crumbs))
+ if not nodiv:=20
+ crumbhtml =3D '<div id=3D"wikicrumbsdiv">%s</div>' % crumbhtml
+ return crumbhtml
+ =09
+ def subNodes(self, id):=20
+ "What subnodes does this node have?"
+ if id:=20
+ spec =3D '/'.join((str(id), ''))
+ else:=20
+ spec =3D '' # all nodes
+ try:
+ self._acquire()
+ return [row.id for row in self.nodes if row.id.startswith(spec)]
+ finally:=20
+ self._release()
+ =09
+ def renderSubNodes(self, id, depthLimit=3D0):
+ idsegs =3D _splitPath(id)
+ skip =3D len(idsegs)
+ subnodeids =3D self.subNodes(id)
+=20
+ base =3D {}
+ for subnodeid in subnodeids:=20
+ segs =3D _splitPath(subnodeid)[skip:]
+ cursor =3D base
+ for seg in segs:=20
+ cursor =3D cursor.setdefault(seg, {})
+ PyDS.Tool.debugOutput("RSN: %s" % repr(base))
+ def spit(out, baseids, cursor, depthLimit, depth=3D1):=20
+ ids =3D cursor.keys()
+ ids.sort()
+ if len(ids):=20
+ out.append('<ul>')
+ for id in ids:
+ nbi =3D list(baseids) + [id]
+ where =3D '/'.join(nbi)
+ out.append('<li>')
+ out.append(self.renderBreadCrumbs(where, =
skipLevels=3Dlen(baseids), nodiv=3D1))
+ if depth < depthLimit:=20
+ spit(out, nbi, cursor[id], depthLimit, depth+1)
+ out.append('</li>')
+ out.append('</ul>')
+ output =3D []
+ spit(output, idsegs, base, depthLimit)
+ return '<div id=3D"subnodes">%s</div>' % '\n'.join(output)
+=20
+ =09
+ subnodes =3D []
+ for subnodeid in subnodeids:=20
+ subnodes.append('<li>%s</li>' % self.renderBreadCrumbs(subnodeid, =
skipLevels=3Dskip))
+ if len(subnodes):
+ return '<div id=3D"subnodes"><ul>%s</ul></div>' % ''.join(subnodes)
+ return '<div id=3D"subnodes"></div>'
+ =09
def __renderNodeOnline(self, key, data):
+ PyDS.Tool.traceargs()
(id,) =3D key
mirror =3D self.getToolByNamespace('mirror')
node =3D self.getNode(id=3Did)
***************
*** 788,799 ****
toolname =3D self.name # consider ''
body =3D req.renderText(
node['text'],=20
! structured =3D 1,
uniqueId =3D id,
homeTool =3D self)
node['cloud'] =3D body
! html =3D req.renderPage('WikiRendering', node=3Dnode)
src =3D req.renderPage('BaseRendering', body=3Dhtml, category=3D'', =
title=3Dnode.get('title', '(no title)'))
fn =3D self.storeHTML(src, page=3Dpagename, toolname=3Dtoolname)
try:
self._acquire()
--- 986,1003 ----
toolname =3D self.name # consider ''
body =3D req.renderText(
node['text'],=20
! structured =3D 2, # TODO: check 'structured' pref
uniqueId =3D id,
homeTool =3D self)
node['cloud'] =3D body
! crumbhtml =3D self.renderBreadCrumbs(id, startWithTool=3D0)
! subnodeshtml =3D self.renderSubNodes(id, depthLimit=3D1)
! PyDS.Tool.debugOutput("rendering the page")
! html =3D crumbhtml + subnodeshtml + req.renderPage('WikiRendering', =
node=3Dnode)
! PyDS.Tool.debugOutput("finished rendering the page")
! # render the result into a full page
src =3D req.renderPage('BaseRendering', body=3Dhtml, category=3D'', =
title=3Dnode.get('title', '(no title)'))
+ # ... and store it
fn =3D self.storeHTML(src, page=3Dpagename, toolname=3Dtoolname)
try:
self._acquire()
------=_NextPart_000_009B_01C47692.3F040F70--