add track-base link and link manager implementation

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@3213 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2009-02-06 16:05:05 +00:00
parent 553f4e3f27
commit d7d6558b3a
6 changed files with 158 additions and 3 deletions

View file

@ -14,9 +14,13 @@ An Example for an Elementary Wiki Structure
>>> from cybertools.wiki.base.wiki import WikiManager, Wiki
We create a wiki manager with one wiki that in turn contains a simple
start page.
start page. We also set the ``linkManager`` configuration option explicitly
to make sure the btree-based tracking link manager will be used.
>>> manager = WikiManager()
>>> linkManagerName = 'tracking'
>>> manager.linkManager = linkManagerName
>>> wiki = manager.addWiki(Wiki('demo_wiki'))
>>> startPage = wiki.createPage('start_page')
@ -56,7 +60,7 @@ Let's now have a look at the link manager - it should have recorded the link
from the page content.
>>> from cybertools.wiki.interfaces import ILinkManager
>>> linkManager = manager.getPlugin(ILinkManager, 'basic')
>>> linkManager = manager.getPlugin(ILinkManager, linkManagerName)
>>> links = linkManager.links
>>> len(links)
1

View file

@ -116,7 +116,7 @@ class LinkProcessor(object):
lm = wiki.getManager().getPlugin(ILinkManager, lmName)
existing = lm.query(source=sourceUid, name=self.targetName)
if existing:
link = existing[0]
link = list(existing)[0]
target = manager.getObject(link.target)
else:
target = wiki.getPage(self.targetName)

View file

@ -203,6 +203,10 @@ class ILinkManager(Interface):
Additional (optional) criteria may be supported by the implementation.
"""
def __iter__():
""" Return an iterator of all links.
"""
class ILink(Interface):
""" A hyperlink between two local or foreign objects.

View file

@ -21,6 +21,7 @@ from cybertools.wiki.dcu.html import Writer as DocutilsHTMLWriter
from cybertools.wiki.dcu.rstx import Parser as DocutilsRstxParser
from cybertools.wiki.dcu import process
from cybertools.wiki.interfaces import IWiki, IWikiPage
from cybertools.wiki.tracking import link
class WikiURL(object):
@ -58,6 +59,9 @@ def setUp(testCase):
component.provideUtility(DocutilsRstxParser(), name='docutils.rstx')
component.provideAdapter(process.Reference, name='default')
component.provideUtility(LinkManager(), name='basic')
component.provideAdapter(link.LinkManager)
links = link.setupLinkManager(None)
component.provideUtility(links, name='tracking')
def test_suite():

View file

@ -0,0 +1,3 @@
"""
$Id$
"""

140
wiki/tracking/link.py Normal file
View file

@ -0,0 +1,140 @@
#
# 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
#
"""
Planning and recording activities (work items).
$Id$
"""
from zope import component
from zope.component import adapts
from zope.interface import implementer, implements
from zope.traversing.api import getName, getParent
from cybertools.stateful.base import Stateful
from cybertools.stateful.definition import StatesDefinition
from cybertools.stateful.definition import State, Transition
from cybertools.stateful.interfaces import IStatesDefinition
from cybertools.tracking.btree import TrackingStorage, Track
from cybertools.tracking.interfaces import ITrackingStorage
from cybertools.wiki.base.link import Link as BaseLink
from cybertools.wiki.base.link import LinkManager as BaseLinkManager
from cybertools.wiki.interfaces import ILink, ILinkManager
@implementer(IStatesDefinition)
def linkStates():
return StatesDefinition('wiki.linkStates',
State('valid', 'valid', ('invalidate',), color='green'),
State('invalid', 'invalid', ('validate',), color='red'),
# transitions:
Transition('invalidate', 'invalidate', 'invalid'),
Transition('validate', 'validate', 'valid'),
initialState='valid')
class Link(BaseLink, Stateful, Track):
""" A link that is stored as a track in a tracking storage.
"""
statesDefinition = 'wiki.linkStates'
metadata_attributes = Track.metadata_attributes + ('name', 'targetId')
index_attributes = metadata_attributes
typeName = 'Link'
def __init__(self, taskId, runId, userName, data={}):
self.name = data.pop('name', '???')
self.targetId = data.pop('targetId', '')
Track.__init__(self, taskId, runId, userName, data={})
@property
def identifier(self):
return self.__name__
#return getName(self)
@property
def source(self):
return self.taskId
@property
def target(self):
return self.targetId
def __getattr__(self, k):
if k not in ILink:
raise AttributeError(k)
return self.data.get(k)
def getManager(self):
return getParent(self)
# IStateful
def getStatesDefinition(self):
return component.getUtility(IStatesDefinition, name=self.statesDefinition)
class LinkManager(BaseLinkManager):
""" A tracking storage adapter managing wiki links.
"""
adapts(ITrackingStorage)
def __init__(self, context):
self.context = context
def getLink(self, identifier):
return self.context.get(identifier)
def query(self, source=None, target=None, name=None, **kw):
criteria = kw
if source is not None:
criteria['taskId'] = source
if target is not None:
criteria['targetId'] = target
if name is not None:
criteria['name'] = name
return self.context.query(**criteria)
def createLink(self, name, source, target, **kw):
taskId = source
runId = kw.pop('runId', 0) or 0
userName = kw.pop('userName', '') or ''
if not runId:
runId = self.context.startRun()
kw['name'] = name
kw['targetId'] = target
trackId = self.context.saveUserTrack(taskId, runId, userName, kw)
track = self.context[trackId]
return track
def removeLink(self, link):
id = link.identifier
if id in self.context:
del self.context[id]
@property
def links(self):
return self.context
def setupLinkManager(manager):
ts = TrackingStorage(trackFactory=Link)
return ILinkManager(ts)