diff --git a/wiki/README.txt b/wiki/README.txt index eb0bf0d..25ba4c9 100644 --- a/wiki/README.txt +++ b/wiki/README.txt @@ -65,8 +65,8 @@ from the page content. >>> len(links) 1 >>> link = links.values()[0] - >>> link.source, link.target, link.name, link.refuri - (0, 1, u'start_page', 'http://127.0.0.1/demo_wiki/start_page') + >>> link.source, link.target, link.name + (0, 1, u'start_page') Links to not yet existing pages ------------------------------- diff --git a/wiki/base/link.py b/wiki/base/link.py index f5ffe5a..b790f33 100644 --- a/wiki/base/link.py +++ b/wiki/base/link.py @@ -114,9 +114,11 @@ class LinkProcessor(object): self.context = context def process(self): + if '..' in self.targetName: + return wiki = self.source.getWiki() manager = wiki.getManager() - sourceUid = self.source.uid + sourceUid = self.source.getUid() lmName = self.source.getConfig('linkManager') lm = manager.getPlugin(ILinkManager, lmName) targetPageName = self.targetName @@ -134,24 +136,26 @@ class LinkProcessor(object): target = None else: target = wiki.getPage(targetPageName) - targetUid = target is not None and target.uid or None + targetUid = target is not None and target.getUid() or None link = lm.createLink(self.targetName, sourceUid, targetUid) - if link.refuri is None: - if fragment: - link.targetFragment = fragment - if params: - link.targetParameters = params - if self.request is not None: - if target is None: - uri = link.refuri = '%s/create.html?name=%s' % ( - absoluteURL(wiki, self.request), link.name) - else: - uri = link.refuri = target.getURI(self.request) - uri += self.fragmentAndParams(fragment, params) - else: - uri = link.refuri + self.fragmentAndParams( - link.targetFragment, - link.targetParameters) + #if link.refuri is None: + if fragment: + link.targetFragment = fragment + if params: + link.targetParameters = params + if self.request is not None: + if target is None: + #uri = link.refuri = '%s/create.html?name=%s' % ( + uri = '%s/create.html?name=%s' % ( + absoluteURL(wiki, self.request), link.name) + else: + #uri = link.refuri = target.getURI(self.request) + uri = target.getURI(self.request) + uri += self.fragmentAndParams(fragment, params) + #else: + # uri = link.refuri + self.fragmentAndParams( + # link.targetFragment, + # link.targetParameters) self.setURI(uri) if target is None: self.markPresentation('create') diff --git a/wiki/base/wiki.py b/wiki/base/wiki.py index 7ae7ba5..709e212 100644 --- a/wiki/base/wiki.py +++ b/wiki/base/wiki.py @@ -124,8 +124,9 @@ class Wiki(BaseConfiguration): def createPage(self, name, title=None): if name in self.pages: raise ValueError("Name '%s' already present." % name) - page = self.pages[name] = WikiPage(name, title) + page = self.pages[name] = WikiPage(name) page.wiki = self + page.title = title or name return page def addPage(self, page): @@ -142,10 +143,13 @@ class Wiki(BaseConfiguration): protocol, address = name.split(':', 1) if protocol in protocols: return ExternalPage(name) - return self.pages.get(name) + return self.getPages().get(name) def listPages(self): - return self.pages.values() + return self.getPages().values() + + def getPages(self): + return self.pages # configuration @@ -198,6 +202,9 @@ class WikiPage(BaseConfiguration): @property def uid(self): + return self.getUid() + + def getUid(self): return self.getWiki().getManager().getUid(self) def getURI(self, request): diff --git a/wiki/common.py b/wiki/common.py index 8c149fd..aca311f 100644 --- a/wiki/common.py +++ b/wiki/common.py @@ -38,6 +38,9 @@ class ExternalPage(object): def __init__(self, uid): self.uid = uid + def getUid(self): + return self.uid + def getURI(self, request): return self.uid diff --git a/wiki/generic/mixin.py b/wiki/generic/mixin.py new file mode 100644 index 0000000..78f4bfa --- /dev/null +++ b/wiki/generic/mixin.py @@ -0,0 +1,145 @@ +# +# 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 +# + +""" +Wiki implementation = adapters for Zope2 content objects. + +$Id$ +""" + +try: + from Acquisition import aq_inner, aq_parent +except ImportError: + pass +from BTrees.IOBTree import IOTreeSet +from BTrees.OOBTree import OOBTree +from persistent.mapping import PersistentMapping +from zope.app.intid import IntIds +from zope.app.intid.interfaces import IIntIds +from zope.cachedescriptors.property import Lazy +from zope import component +from zope.component import adapts +from zope.interface import implements + +from cybertools.util.generic.interfaces import IGenericObject, IGenericFolder +from cybertools.wiki.base.config import WikiConfigInfo, BaseConfigurator +from cybertools.wiki.base.wiki import WikiManager as BaseWikiManager +from cybertools.wiki.base.wiki import Wiki as BaseWiki +from cybertools.wiki.base.wiki import WikiPage as BaseWikiPage +from cybertools.wiki.interfaces import ILinkManager, IWikiConfigInfo +from cybertools.wiki.tracking.link import Link, TrackingStorage + + +class PersistentConfigInfo(PersistentMapping): + + implements(IWikiConfigInfo) + + def set(self, functionality, value): + self[functionality] = value + + def __getattr__(self, attr): + return self.get(attr, None) + + +class GenericConfigurator(BaseConfigurator): + + def initialize(self): + ci = PersistentConfigInfo() + self.context.setGenericAttribute('configInfo', ci) + return ci + + def getConfigInfo(self): + return self.context.getGenericAttribute('configInfo', None) + + +class WikiManager(BaseWikiManager): + + configurator = GenericConfigurator + + def setup(self): + self.setGenericAttribute('wikis', IOTreeSet()) + plugins = self.setGenericAttribute('plugins', PersistentMapping()) + plugins[(IIntIds, '')] = IntIds() + linkStorage = TrackingStorage(trackFactory=Link) + plugins[(ILinkManager, 'tracking')] = linkStorage + self.setConfig('linkManager', 'tracking') + + def addWiki(self, wiki): + uid = self.getUid(wiki) + self.wikiUids.insert(uid) + wiki.setManager(self) + return wiki + + def removeWiki(self, wiki): + uid = self.getUid(wiki) + if uid in self.wikiUids: + self.wikiUids.remove(uid) + + def listWikis(self): + for uid in self.wikiUids: + yield self.getObject(uid) + + @Lazy + def wikiUids(self): + return self.getGenericAttribute('wikis') + + def getPlugins(self): + return self.getGenericAttribute('plugins') + + def getObject(self, uid): + obj = self.resolveUid(uid) + if obj is None: + return super(WikiManager, self).getObject(uid) + return obj + + +class Wiki(BaseWiki): + + @property + def name(self): + return self.getId() + + def getPages(self): + # TODO: restrict to wiki page objects; use generic access methods + return dict((k, v) for k, v in self.objectItems()) + + def createPage(self, name, title, text=u''): + # TODO: delegate to generic folder + # page = self[name] = WikiPage(name) + self._setObject(name, self.pageFactory(name)) + page = getattr(self, name) + page.title = title + page.text = text + return page + + def getManager(self): + # TODO: fetch tool/utility in a generic way + return self.portal_wikimanager + + +class WikiPage(BaseWikiPage): + + def getText(self): + return self.getGenericAttribute('text') + def setText(self, text): + self.setGenericAttribute('text', text) + text = property(getText, setText) + + def getWiki(self): + # TODO: fetch wiki in a generic way + return aq_parent(aq_inner(self))