Index: PyDS/MeshTool.py
===================================================================
RCS file: /pyds/PyDS/PyDS/MeshTool.py,v
retrieving revision 1.22
diff -c -r1.22 MeshTool.py
*** PyDS/MeshTool.py	9 Feb 2004 16:43:30 -0000	1.22
--- PyDS/MeshTool.py	31 May 2004 08:57:55 -0000
***************
*** 131,136 ****
--- 131,137 ----
  # cssclass can be None or ''
  # OPTIONAL .getDesktopDisplayLinkDetailsForUniqueId(uniqueId) => same
  # OPTIONAL .getDesktopCreateLinkDetailsForProposedLinkText(linkText) => same
+ # Those two MUST raise KeyError if not thrown. 
  # REQUIRED .getUniqueIdsMatchingLinkText(linkText) => list of unique IDs
  # All the rest of the context (reftime, category, parent) via _flet
  # Not all are necessary, eg .getCloudUrlForUniqueId only might be suitable for InterWiki, cached links
***************
*** 356,361 ****
--- 357,367 ----
  		tool = PyDS.Tool.getTool(self.homeTool)
  		return tool.getCloudLinkDetailsForUniqueId(self.uniqueId)
  
+ 	def getDesktopDisplayLinkDetails(self):
+ 		"Get the display/edit link details for this item."
+ 		tool = PyDS.Tool.getTool(self.homeTool)
+ 		return tool.getDesktopDisplayLinkDetailsForUniqueId(self.uniqueId)
+ 
  class StrayLinkResolver(docutils.nodes.SparseNodeVisitor):
  	"""`Visitor` to resolve stray links.
  	
***************
*** 387,401 ****
  		previousDestination = self.itemLinks.setdefault(stray, 0)
  		# side-effect of the above: sets dest to 0 if not found
  		if previousDestination is not None: 
! 			# TODO: correctly handle the destination no longer existing,
! 			# as could/should be shown by thrown exceptions from 
! 			# getCloudLinkDetails. 
! 			#print "found match from %s:%s to %s:%s" % (
! 			#    self.itemDetail.homeTool, 
! 			#	self.itemDetail.uniqueId, 
! 			#	previousDestination.homeTool,
! 			#	previousDestination.uniqueId )
! 			return previousDestination.getCloudLinkDetails()
  
  		# Gather list of potential matches. 
    		matches = []
--- 393,405 ----
  		previousDestination = self.itemLinks.setdefault(stray, 0)
  		# side-effect of the above: sets dest to 0 if not found
  		if previousDestination is not None: 
! 			try: 
! 				if _flet.desktop:
! 					return previousDestination.getDesktopDisplayLinkDetails()
! 				else: 
! 					return previousDestination.getCloudLinkDetails()
! 			except KeyError: 
! 				pass
  
  		# Gather list of potential matches. 
    		matches = []
***************
*** 434,439 ****
--- 438,476 ----
  		refname = node.get('refname') # internal references
  		refuri = node.get('refuri') # external references
  
+ 		def applymatch(node, match): 
+ 			if len(match) == 3: 
+ 				cssclass, uri, title = match
+ 				node['title'] = title
+ 			else: 
+ 				cssclass, uri = match
+ 			node.resolved = 1
+ 			node['class'] = cssclass
+ 			node['refuri'] = uri
+ 			try: 
+ 				del node['refname']
+ 			except KeyError: 
+ 				pass
+ 			
+ 		# If the target begins with ``pyds:/``, we want to intercept it. 
+ 		if refuri is not None and refuri.startswith("pyds:/"): 
+ 			match = ('undefinednode', refuri, 'internal link not resolvable')
+ 			try: 
+ 				itemDetails = self.meshTool.getItemDetailsByUri(str(refuri))
+ 				homeTool = PyDS.Tool.getTool(itemDetails['homeTool'])
+ 				uniqueId = itemDetails['uniqueId']
+ 				if _flet.desktop: 
+ 					match = homeTool.getDesktopDisplayLinkDetailsForUniqueId(uniqueId)
+ 				else: 
+ 					match = homeTool.getCloudLinkDetailsForUniqueId(uniqueId)
+ 			except KeyError: 
+ 				# TODO: What should we do here? Really? 
+ 				# Currently: leave it with default match defined above
+ 				pass
+ 
+ 			applymatch(node, match)
+ 			return
+ 
  		# If it has been apparently resolved, return. In testing,
  		# this has been seen true with refname and refuri both 
  		# undefined. I don't yet know why. 
***************
*** 495,510 ****
  		# Only here do we try and resolve things internally. 
  		match = self.resolveStrayLink(node['refname'])
  		if match:
! 			if len(match) == 3: 
! 				cssclass, uri, title = match
! 				node['title'] = title
! 			else: 
! 				cssclass, uri = match
! 			node.resolved = 1
! 			node['class'] = cssclass
! 			node['refuri'] = uri
! 			del node['refname']
  
  	def unknown_visit(self, node):
  		pass
  	
--- 532,541 ----
  		# Only here do we try and resolve things internally. 
  		match = self.resolveStrayLink(node['refname'])
  		if match:
! 			applymatch(node, match)
  
+ 		# Otherwise, just leave it alone.
+ 			
  	def unknown_visit(self, node):
  		pass
  	
***************
*** 645,651 ****
  		e = r'pyds\:(?://(?P<hostName>[^/]+))?/(?P<toolName>[^/]+)/(?P<uniqueId>.*)'
  		m = re.match(e, uri)
  		if m is None: 
! 			return 0
  		g = m.groupdict()
  		return self.getItemDetailsByToolAndId(g['toolName'], g['uniqueId'])
  		
--- 676,682 ----
  		e = r'pyds\:(?://(?P<hostName>[^/]+))?/(?P<toolName>[^/]+)/(?P<uniqueId>.*)'
  		m = re.match(e, uri)
  		if m is None: 
! 			raise ValueError, uri
  		g = m.groupdict()
  		return self.getItemDetailsByToolAndId(g['toolName'], g['uniqueId'])
  		
***************
*** 709,715 ****
  			assert homeTool
  			if isinstance(homeTool, PyDS.Tool.StandardTool):
  				homeTool = homeTool.name
! 			return getItemDetailsByToolAndId(homeTool, handleOrUniqueId)
  
  	def delItem(self, handleOrUniqueId, homeTool=None, abortIfTarget=0): 
  		"""Delete an item, unless inbounds and `abortIfTarget`.
--- 740,746 ----
  			assert homeTool
  			if isinstance(homeTool, PyDS.Tool.StandardTool):
  				homeTool = homeTool.name
! 			return self.getItemDetailsByToolAndId(homeTool, handleOrUniqueId)
  
  	def delItem(self, handleOrUniqueId, homeTool=None, abortIfTarget=0): 
  		"""Delete an item, unless inbounds and `abortIfTarget`.
Index: PyDS/ShutdownTool.py
===================================================================
RCS file: /pyds/PyDS/PyDS/ShutdownTool.py,v
retrieving revision 1.4
diff -c -r1.4 ShutdownTool.py
*** PyDS/ShutdownTool.py	9 Feb 2004 16:43:30 -0000	1.4
--- PyDS/ShutdownTool.py	31 May 2004 08:57:55 -0000
***************
*** 37,46 ****
  class ShutdownTool(PyDS.Tool.StandardTool):
  
  	def _initopts(self):
! 		self.hasAPI = 0
  		self.shutdown = 0
  
! 	def index_html(self, req):
  		def thunk():
  			time.sleep(2)
  			self.log('Shutting down!')
--- 37,52 ----
  class ShutdownTool(PyDS.Tool.StandardTool):
  
  	def _initopts(self):
! 		self.hasAPI = 1
  		self.shutdown = 0
+ 		self.background = None
  
! 	# Initiate shutdown. 
! 	def startShutdown(self): 
! 		"Initiate shutdown, returning 1 if started or 0 if already started."
! 		if self.background: 
! 			return 0
! 		
  		def thunk():
  			time.sleep(2)
  			self.log('Shutting down!')
***************
*** 49,62 ****
  		        # shutdown all threads
  			PyDS.Server.terminate()
  
! 		background = threading.Thread(
  			target=thunk,
  			args=[],
  			kwargs={}
  		)
! 		background.start()
  
! 		html = "<p>%s: %s" % (self.title, self.desc)
  		return req.renderPage('BaseTemplate', body=html)
  
  		
--- 55,73 ----
  		        # shutdown all threads
  			PyDS.Server.terminate()
  
! 		self.background = threading.Thread(
  			target=thunk,
  			args=[],
  			kwargs={}
  		)
! 		self.background.start()
! 		return 1
  
! 	def index_html(self, req): 
! 		res = self.startShutdown()
! 		desc = [_('Shutdown previously started.'), 
! 		        _('Shutdown started.')][res]
! 		html = "<p>%s: %s</p><p>%s</p>" % (self.title, self.desc, desc)
  		return req.renderPage('BaseTemplate', body=html)
  
  		
Index: PyDS/StructuredText.py
===================================================================
RCS file: /pyds/PyDS/PyDS/StructuredText.py,v
retrieving revision 1.36
diff -c -r1.36 StructuredText.py
*** PyDS/StructuredText.py	19 Apr 2004 16:32:02 -0000	1.36
--- PyDS/StructuredText.py	31 May 2004 08:57:55 -0000
***************
*** 186,208 ****
  	try: 
  		# make uniqueId and homeTool available to the renderer, so 
  		# that the MeshTool (if registered) can determine backlinks. 
! 		_flet.begin(uniqueId=uniqueId, homeTool=homeTool)
  		# crank it through
  		writer = HTMLFragmentWriter(
  			section_level=section_level,
  			suppress_paragraphs=suppress_paragraphs)
  		output = docutils.core.publish_string(
  			source=text,
  			reader=Reader(),
  			writer=writer,
  			parser_name='restructuredText',
! 			settings_overrides={
! 				'input_encoding': _PyDS.documentEncoding,
! 				'output_encoding': 'unicode'
! 			}
  		)
  		try:
! 			output = output.encode(_PyDS.documentEncoding)
  		except:
  			output = re.sub(
  				r'([^\x00-\xff])',
--- 186,213 ----
  	try: 
  		# make uniqueId and homeTool available to the renderer, so 
  		# that the MeshTool (if registered) can determine backlinks. 
! 		if runningUnderPyDS: 
! 			_flet.begin(uniqueId=uniqueId, homeTool=homeTool)
  		# crank it through
  		writer = HTMLFragmentWriter(
  			section_level=section_level,
  			suppress_paragraphs=suppress_paragraphs)
+ 		settings = { 'output_encoding': 'unicode' }
+ 		if runningUnderPyDS: 
+ 			settings['input_encoding'] = _PyDS.documentEncoding
  		output = docutils.core.publish_string(
  			source=text,
  			reader=Reader(),
  			writer=writer,
  			parser_name='restructuredText',
! 			settings_overrides=settings
  		)
  		try:
! 			if runningUnderPyDS: 
! 				args = [_PyDS.documentEncoding]
! 			else:
! 				args = []
! 			output = output.encode(*args)
  		except:
  			output = re.sub(
  				r'([^\x00-\xff])',
***************
*** 210,229 ****
  				output
  			)
  			output = output.encode(_PyDS.documentEncoding)
! 	finally: _flet.end()
  
  	return output
  
  	return destination.destination
  
  if __name__ == '__main__':
! 	print renderText("""
  This is a headline
  ------------------
  
  This is a paragraph.
  
! This is another paragraph. |Wertschoepfungskette|
  
  1. first item
  2. second item
--- 215,244 ----
  				output
  			)
  			output = output.encode(_PyDS.documentEncoding)
! 	finally:
! 		if runningUnderPyDS:
! 			_flet.end()
  
  	return output
  
  	return destination.destination
  
  if __name__ == '__main__':
! 	import time
! 	try: 
! 		import psyco
! 		psyco.log()
! 		psyco.profile()
! 		print "PSYCO ENABLED."
! 	except ImportError: 
! 		pass
! 	testText = """
  This is a headline
  ------------------
  
  This is a paragraph.
  
! This is another paragraph. 
  
  1. first item
  2. second item
***************
*** 267,270 ****
  .. __: http://www.f-2.org/
  .. __: http://muensterland.org/
  
! """)
--- 282,299 ----
  .. __: http://www.f-2.org/
  .. __: http://muensterland.org/
  
! """
! 	LOOPS=50
! 	begin = time.time()
! 	print "Rendering example text %d times" % LOOPS,
! 	for i in range(LOOPS): 
! 		renderedText = renderText(testText)
! 		print ".", 
! 	print
! 	elapsed = time.time() - begin
! 	print renderedText
! 	print "Rendered example text %d times in %f seconds (%f renders/s)" % (
! 			LOOPS,
! 			elapsed,
! 			LOOPS/elapsed)
! 
Index: PyDS/WeblogTool.py
===================================================================
RCS file: /pyds/PyDS/PyDS/WeblogTool.py,v
retrieving revision 1.119
diff -c -r1.119 WeblogTool.py
*** PyDS/WeblogTool.py	26 Apr 2004 18:15:04 -0000	1.119
--- PyDS/WeblogTool.py	31 May 2004 08:57:58 -0000
***************
*** 320,326 ****
  	# Render an item by its unique ID
  	def renderItemByUniqueId(self, uniqueId):
  		"""Render all pages associated with the post identified by `uniqueId`."""
! 		post  = getPost(uniqueId)
  		pubtime = post['pubtime']
  		if post['onhome']: 
  			self.renderTimeframes(pubtime, '')
--- 320,326 ----
  	# Render an item by its unique ID
  	def renderItemByUniqueId(self, uniqueId):
  		"""Render all pages associated with the post identified by `uniqueId`."""
! 		post  = self.getPost(uniqueId)
  		pubtime = post['pubtime']
  		if post['onhome']: 
  			self.renderTimeframes(pubtime, '')
Index: PyDS/WikiTool.py
===================================================================
RCS file: /pyds/PyDS/PyDS/WikiTool.py,v
retrieving revision 1.23
diff -c -r1.23 WikiTool.py
*** PyDS/WikiTool.py	26 Apr 2004 18:15:04 -0000	1.23
--- PyDS/WikiTool.py	31 May 2004 08:58:00 -0000
***************
*** 42,54 ****
  	t = re.sub('\W', '', s)
  	return t.lower()
  
! def _fullSplit(path): 
! 	"split a path to a tuple, with '' as the first item"
  	p, b = os.path.split(path)
  	if not p: 
  		return (b,)
  	else: 
! 		return _fullSplit(p) + (b,)
  
  class WikiTool(PyDS.Tool.StandardTool):
  
--- 42,58 ----
  	t = re.sub('\W', '', s)
  	return t.lower()
  
! def _splitPath(path): 
! 	"Split a path to a tuple, with '' as the first item"
  	p, b = os.path.split(path)
  	if not p: 
  		return (b,)
  	else: 
! 		return _splitPath(p) + (b,)
! 
! def _normPath(path): 
! 	"Normalise a path a little -- primarily, converting \\ to /."
! 	return '/'.join(_splitPath(path))
  
  class WikiTool(PyDS.Tool.StandardTool):
  
***************
*** 323,329 ****
  		append('<input type="submit" value="%(editlabel)s" accesskey="n">' % editvars)
  		hashedNodes = {}
  		for node in self.nodes: 
! 			nids = _fullSplit(node.id)
  			current = hashedNodes
  			for id in nids: 
  				idnode = current.setdefault(id, [None, {}])
--- 327,333 ----
  		append('<input type="submit" value="%(editlabel)s" accesskey="n">' % editvars)
  		hashedNodes = {}
  		for node in self.nodes: 
! 			nids = _splitPath(node.id)
  			current = hashedNodes
  			for id in nids: 
  				idnode = current.setdefault(id, [None, {}])
***************
*** 375,381 ****
  			uniqueId = id, 
  			homeTool = self)
  		# breadcrumbs
! 		nids = _fullSplit(id)
  		sofar = ''
  		crumbs = ['<strong><a href="%s">%s</a></strong>' % (self.getUrl('index_html'), _('Wiki'))]
  		for nid in nids: 
--- 379,385 ----
  			uniqueId = id, 
  			homeTool = self)
  		# breadcrumbs
! 		nids = _splitPath(id)
  		sofar = ''
  		crumbs = ['<strong><a href="%s">%s</a></strong>' % (self.getUrl('index_html'), _('Wiki'))]
  		for nid in nids: 
***************
*** 536,542 ****
    <td><textarea nowrap name="text" rows=15 cols=60>%(textvalue)s</textarea></td>
  </tr><tr>
    <td colspan=2 align="right">
-     <input type=submit name="WikiDelete" value="%(deletelabel)s">
      <input type=submit name="WikiSave" accesskey="s" value="%(savelabel)s">
    </td>
  </tr></table></form>
--- 540,545 ----
***************
*** 558,563 ****
--- 561,567 ----
  	def edit_redir(self, req):
  		id, oldid, title, text, desc, template = map(req.getFirstValue, 
  			('id', 'oldid', 'title', 'text', 'desc', 'template'))
+ 		id = _normPath(id)
  		if req.getFirstValue('WikiDelete'):
  			return self.getUrl('delete_html', id=str(id))
  		else:
***************
*** 616,624 ****
  		if node is None: 
  			return {}
  		else: 
  			return {
  				'id': node.id,
! 				'title': node.title,
  				'text': node.text,
  				'pubtime': node.pubtime,
  				'categoryid': node.categoryid, 
--- 620,631 ----
  		if node is None: 
  			return {}
  		else: 
+ 			title = node.title
+ 			if not node.title: 
+ 				title = node.baseid
  			return {
  				'id': node.id,
! 				'title': title,
  				'text': node.text,
  				'pubtime': node.pubtime,
  				'categoryid': node.categoryid, 
