From d3dfc9e4e7df5968ad38f993ffeff20c462803e5 Mon Sep 17 00:00:00 2001 From: helmutm Date: Tue, 3 Mar 2009 08:51:42 +0000 Subject: [PATCH] work in progress: link processing - add handling of external links git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@3258 fd906abe-77d9-0310-91a1-e0d9ade77398 --- wiki/README.txt | 39 +++++++++++++++++++++++++++++++++++++++ wiki/base/link.py | 18 +++++++++--------- wiki/base/wiki.py | 30 +++++++++++++++++++++++++----- wiki/common.py | 43 +++++++++++++++++++++++++++++++++++++++++++ wiki/interfaces.py | 17 ++++++++++++++++- 5 files changed, 132 insertions(+), 15 deletions(-) create mode 100644 wiki/common.py diff --git a/wiki/README.txt b/wiki/README.txt index db0ecdd..bab221e 100644 --- a/wiki/README.txt +++ b/wiki/README.txt @@ -82,4 +82,43 @@ Links to not yet existing pages

?More...

+ >>> len(links) + 2 +External links +-------------- + + >>> linksPage = wiki.createPage('links') + >>> linksPage.text = ''' + ... **A collection of interesting links** + ... + ... - http://python.org + ... - `Zope `_ + ... ''' + +An absolute URL given as link target will not be changed in the process. + + >>> print linksPage.render(TestRequest()) +

A collection of interesting links

+ + +Nevertheless the links are registered in the link manager. + + >>> len(links) + 4 + +When we render external links repeatedly no new link objects will be +created. + + >>> print linksPage.render(TestRequest()) +

A collection of interesting links

+ + + >>> len(links) + 4 diff --git a/wiki/base/link.py b/wiki/base/link.py index 884c00f..754f026 100644 --- a/wiki/base/link.py +++ b/wiki/base/link.py @@ -17,7 +17,7 @@ # """ -Basic (sample) implementations for links and link management +Basic (sample) implementations for links and link management. $Id$ """ @@ -111,16 +111,18 @@ class LinkProcessor(object): def process(self): wiki = self.source.getWiki() manager = wiki.getManager() - sourceUid = self.source.getUid() + sourceUid = self.source.uid lmName = self.source.getConfig('linkManager') - lm = wiki.getManager().getPlugin(ILinkManager, lmName) + lm = manager.getPlugin(ILinkManager, lmName) existing = lm.query(source=sourceUid, name=self.targetName) if existing: - link = list(existing)[0] + link = existing.next() + #print '*** #1', self.targetName, link target = manager.getObject(link.target) else: target = wiki.getPage(self.targetName) - targetUid = target is not None and target.getUid() or None + #print '*** #2', self.targetName, target + targetUid = target is not None and target.uid or None link = lm.createLink(self.targetName, sourceUid, targetUid) if link.refuri is None: if self.request is not None: @@ -128,15 +130,12 @@ class LinkProcessor(object): link.refuri = '%s/create.html?linkid=%s' % ( absoluteURL(wiki, self.request), link.identifier) else: - link.refuri = self.getTargetURI(target) + link.refuri = target.getURI(self.request) self.setURI(link.refuri) if target is None: self.markPresentation('create') self.addText('?') - def getTargetURI(self, obj): - return absoluteURL(obj, self.request) - def setURI(self, uri): raise ValueError('To be implemented by subclass.') @@ -145,3 +144,4 @@ class LinkProcessor(object): def addText(self, text): raise ValueError('To be implemented by subclass.') + diff --git a/wiki/base/wiki.py b/wiki/base/wiki.py index e83dc4e..181dfe0 100644 --- a/wiki/base/wiki.py +++ b/wiki/base/wiki.py @@ -22,10 +22,12 @@ A Wiki manager managing wikis and wiki-related objects, esp plugins. $Id$ """ +from zope.app.intid.interfaces import IIntIds from zope import component from zope.interface import implements -from zope.app.intid.interfaces import IIntIds +from zope.traversing.browser import absoluteURL +from cybertools.wiki.common import protocols, ExternalPage from cybertools.wiki.interfaces import IWikiConfiguration from cybertools.wiki.interfaces import IWikiManager, IWiki, IWikiPage from cybertools.wiki.interfaces import IParser, IWriter @@ -62,9 +64,17 @@ class WikiManager(BaseConfiguration): return component.getUtility(IIntIds).getId(obj) def getObject(self, uid): - if uid is None: - return None - return component.getUtility(IIntIds).getObject(int(uid)) + obj = self.resolveUid(uid) + if obj is None: + return component.getUtility(IIntIds).getObject(int(uid)) + return obj + + def resolveUid(self, uid): + if isinstance(uid, basestring) and ':' in uid: + protocol, address = uid.split(':', 1) + if protocol.lower() in protocols: + return ExternalPage(uid) + return None # configuration @@ -103,6 +113,10 @@ class Wiki(BaseConfiguration): del self.pages[name] def getPage(self, name): + if ':' in name: + protocol, address = name.split(':', 1) + if protocol in protocols: + return ExternalPage(name) return self.pages.get(name) def listPages(self): @@ -151,9 +165,15 @@ class WikiPage(BaseConfiguration): def postprocess(self, result): return result - def getUid(self): + # IWebResource + + @property + def uid(self): return self.getWiki().getManager().getUid(self) + def getURI(self, request): + return absoluteURL(self, request) + # configuration def getConfigParent(self): diff --git a/wiki/common.py b/wiki/common.py new file mode 100644 index 0000000..8c149fd --- /dev/null +++ b/wiki/common.py @@ -0,0 +1,43 @@ +# +# Copyright (c) 2009 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Common basic generic stuff. + +$Id$ +""" + +from zope.interface import implements + +from cybertools.wiki.interfaces import IWebResource + + +protocols = set(['dav', 'file', 'ftp', 'http', 'https', 'javascript', + 'mailto', 'sftp', 'smb']) + + +class ExternalPage(object): + + implements(IWebResource) + + def __init__(self, uid): + self.uid = uid + + def getURI(self, request): + return self.uid + diff --git a/wiki/interfaces.py b/wiki/interfaces.py index d7b8492..d50648f 100644 --- a/wiki/interfaces.py +++ b/wiki/interfaces.py @@ -105,7 +105,20 @@ class IWiki(Interface): """ -class IWikiPage(Interface): +class IWebResource(Interface): + """ An object (may be a proxy or some other kind of representation) that + may be addressed by a Unique (Resource) Identifier (UID or URI). + """ + + uid = Attribute('A string uniquely addressing the object within a ' + 'certain context (local pages) or globally.') + + def getURI(self, request): + """ Return a unique resource identifier based on the request given. + """ + + +class IWikiPage(IWebResource): """ An object representing a page of a wiki. """ @@ -230,6 +243,8 @@ class ILink(Interface): 'for external links - the target URI.') targetFragment = Attribute('Optional: an address part leading to a ' 'text anchor or the part of an image.') + targetParameters = Attribute('Optional: a dictionary of URI parameters ' + 'that will have to be appended to the link to the target object.') refuri = Attribute('The URI linking to the target object.') user = Attribute('Optional: a string denoting the creator of the record.') run = Attribute('Optional: May be used to group the links from a certain '