Python3 fixes: test setup OK, starting with fixes in README.txt
This commit is contained in:
parent
494612235e
commit
42d24a5c3f
4 changed files with 103 additions and 137 deletions
174
loops/README.txt
174
loops/README.txt
|
@ -48,14 +48,14 @@ top-level loops container and a concept manager:
|
|||
>>> cc1 = Concept()
|
||||
>>> concepts['cc1'] = cc1
|
||||
>>> cc1.title
|
||||
u''
|
||||
''
|
||||
>>> loopsRoot.getLoopsUri(cc1)
|
||||
u'.loops/concepts/cc1'
|
||||
'.loops/concepts/cc1'
|
||||
|
||||
>>> cc2 = Concept(u'Zope 3')
|
||||
>>> cc2 = Concept('Zope 3')
|
||||
>>> concepts['cc2'] = cc2
|
||||
>>> cc2.title
|
||||
u'Zope 3'
|
||||
'Zope 3'
|
||||
|
||||
Now we want to relate the second concept to the first one.
|
||||
|
||||
|
@ -73,11 +73,11 @@ ConceptRelation):
|
|||
We can now ask our concepts for their related child and parent concepts:
|
||||
|
||||
>>> [getName(c) for c in cc1.getChildren()]
|
||||
[u'cc2']
|
||||
['cc2']
|
||||
>>> len(cc1.getParents())
|
||||
0
|
||||
>>> [getName(p) for p in cc2.getParents()]
|
||||
[u'cc1']
|
||||
['cc1']
|
||||
|
||||
>>> len(cc2.getChildren())
|
||||
0
|
||||
|
@ -90,24 +90,24 @@ a special predicate 'hasType'.
|
|||
>>> typeObject = concepts['type']
|
||||
>>> typeObject.setConceptType(typeObject)
|
||||
>>> typeObject.getConceptType().title
|
||||
u'Type'
|
||||
'Type'
|
||||
|
||||
>>> concepts['unknown'] = Concept(u'Unknown Type')
|
||||
>>> concepts['unknown'] = Concept('Unknown Type')
|
||||
>>> unknown = concepts['unknown']
|
||||
>>> unknown.setConceptType(typeObject)
|
||||
>>> unknown.getConceptType().title
|
||||
u'Type'
|
||||
'Type'
|
||||
|
||||
>>> cc1.setConceptType(unknown)
|
||||
>>> cc1.getConceptType().title
|
||||
u'Unknown Type'
|
||||
'Unknown Type'
|
||||
|
||||
>>> concepts['topic'] = Concept(u'Topic')
|
||||
>>> concepts['topic'] = Concept('Topic')
|
||||
>>> topic = concepts['topic']
|
||||
>>> topic.setConceptType(typeObject)
|
||||
>>> cc1.setConceptType(topic)
|
||||
>>> cc1.getConceptType().title
|
||||
u'Topic'
|
||||
'Topic'
|
||||
|
||||
We get a list of types using the ConceptTypeSourceList.
|
||||
In order for the type machinery to work we first have to provide a
|
||||
|
@ -124,7 +124,7 @@ type manager.
|
|||
>>> from loops.concept import ConceptTypeSourceList
|
||||
>>> types = ConceptTypeSourceList(cc1)
|
||||
>>> sorted(t.title for t in types)
|
||||
[u'Customer', u'Domain', u'Predicate', u'Topic', u'Type', u'Unknown Type']
|
||||
['Customer', 'Domain', 'Predicate', 'Topic', 'Type', 'Unknown Type']
|
||||
|
||||
Using a PredicateSourceList we can retrieve a list of the available
|
||||
predicates.
|
||||
|
@ -136,7 +136,7 @@ Note that the 'hasType' predicate is suppressed from this list as the
|
|||
corresponding relation is only assigned via the conceptType attribute:
|
||||
|
||||
>>> sorted(t.title for t in predicates)
|
||||
[u'subobject']
|
||||
['subobject']
|
||||
|
||||
Concept Views
|
||||
-------------
|
||||
|
@ -146,7 +146,7 @@ Concept Views
|
|||
|
||||
>>> children = list(view.children())
|
||||
>>> [c.title for c in children]
|
||||
[u'Zope 3']
|
||||
['Zope 3']
|
||||
|
||||
The token attribute provided with the items returned by the children() and
|
||||
parents() methods identifies identifies not only the item itself but
|
||||
|
@ -154,19 +154,19 @@ also the relationship to the context object using a combination
|
|||
of URIs to item and the predicate of the relationship:
|
||||
|
||||
>>> [c.token for c in children]
|
||||
[u'.loops/concepts/cc2:.loops/concepts/standard']
|
||||
['.loops/concepts/cc2:.loops/concepts/standard']
|
||||
|
||||
There is also a concept configuration view that allows updating the
|
||||
underlying context object:
|
||||
|
||||
>>> cc3 = Concept(u'loops for Zope 3')
|
||||
>>> cc3 = Concept('loops for Zope 3')
|
||||
>>> concepts['cc3'] = cc3
|
||||
>>> view = ConceptConfigureView(cc1,
|
||||
... TestRequest(action='assign', tokens=['.loops/concepts/cc3']))
|
||||
>>> view.update()
|
||||
True
|
||||
>>> sorted(c.title for c in cc1.getChildren())
|
||||
[u'Zope 3', u'loops for Zope 3']
|
||||
['Zope 3', 'loops for Zope 3']
|
||||
|
||||
>>> input = {'action': 'remove', 'qualifier': 'children',
|
||||
... 'form.button.submit': 'Remove Chiildren',
|
||||
|
@ -175,18 +175,18 @@ underlying context object:
|
|||
>>> view.update()
|
||||
True
|
||||
>>> sorted(c.title for c in cc1.getChildren())
|
||||
[u'loops for Zope 3']
|
||||
['loops for Zope 3']
|
||||
|
||||
We can also create a new concept and assign it.
|
||||
|
||||
>>> params = {'action': 'create', 'create.name': 'cc4',
|
||||
... 'create.title': u'New concept',
|
||||
... 'create.title': 'New concept',
|
||||
... 'create.type': '.loops/concepts/topic'}
|
||||
>>> view = ConceptConfigureView(cc1, TestRequest(**params))
|
||||
>>> view.update()
|
||||
True
|
||||
>>> sorted(c.title for c in cc1.getChildren())
|
||||
[u'New concept', u'loops for Zope 3']
|
||||
['New concept', 'loops for Zope 3']
|
||||
|
||||
The concept configuration view provides methods for displaying concept
|
||||
types and predicates.
|
||||
|
@ -198,15 +198,15 @@ types and predicates.
|
|||
>>> component.provideAdapter(LoopsTerms, (IIterableSource, IBrowserRequest), ITerms)
|
||||
|
||||
>>> sorted((t.title, t.token) for t in view.conceptTypes())
|
||||
[(u'Customer', '.loops/concepts/customer'),
|
||||
(u'Domain', '.loops/concepts/domain'),
|
||||
(u'Predicate', '.loops/concepts/predicate'),
|
||||
(u'Topic', '.loops/concepts/topic'),
|
||||
(u'Type', '.loops/concepts/type'),
|
||||
(u'Unknown Type', '.loops/concepts/unknown')]
|
||||
[('Customer', '.loops/concepts/customer'),
|
||||
('Domain', '.loops/concepts/domain'),
|
||||
('Predicate', '.loops/concepts/predicate'),
|
||||
('Topic', '.loops/concepts/topic'),
|
||||
('Type', '.loops/concepts/type'),
|
||||
('Unknown Type', '.loops/concepts/unknown')]
|
||||
|
||||
>>> sorted((t.title, t.token) for t in view.predicates())
|
||||
[(u'subobject', '.loops/concepts/standard')]
|
||||
[('subobject', '.loops/concepts/standard')]
|
||||
|
||||
Index attributes adapter
|
||||
------------------------
|
||||
|
@ -214,10 +214,10 @@ Index attributes adapter
|
|||
>>> from loops.concept import IndexAttributes
|
||||
>>> idx = IndexAttributes(cc2)
|
||||
>>> idx.text()
|
||||
u'cc2 Zope 3'
|
||||
'cc2 Zope 3'
|
||||
|
||||
>>> idx.title()
|
||||
u'cc2 Zope 3'
|
||||
'cc2 Zope 3'
|
||||
|
||||
|
||||
Resources and what they have to do with Concepts
|
||||
|
@ -233,20 +233,20 @@ A common type of resource is a document:
|
|||
|
||||
>>> from loops.interfaces import IDocument
|
||||
>>> from loops.resource import Document
|
||||
>>> doc1 = Document(u'Zope Info')
|
||||
>>> doc1 = Document('Zope Info')
|
||||
>>> resources['doc1'] = doc1
|
||||
>>> doc1.title
|
||||
u'Zope Info'
|
||||
'Zope Info'
|
||||
>>> doc1.data
|
||||
u''
|
||||
''
|
||||
>>> doc1.contentType
|
||||
u''
|
||||
''
|
||||
|
||||
We can also directly use Resource objects; these behave like files.
|
||||
In fact, by using resource types we can explicitly assign a resource
|
||||
the 'file' type, but we will use this feature later:
|
||||
|
||||
>>> img = Resource(u'A png Image')
|
||||
>>> img = Resource('A png Image')
|
||||
|
||||
For testing we use some simple files from the tests directory:
|
||||
|
||||
|
@ -261,7 +261,7 @@ For testing we use some simple files from the tests directory:
|
|||
>>> img.contentType
|
||||
'image/png'
|
||||
|
||||
>>> pdf = Resource(u'A pdf File')
|
||||
>>> pdf = Resource('A pdf File')
|
||||
>>> pdf.data = open(os.path.join(path, 'test.pdf')).read()
|
||||
>>> pdf.getSize()
|
||||
25862
|
||||
|
@ -287,7 +287,7 @@ from concepts to resources:
|
|||
... 'tokens': ['.loops/resources/doc1:.loops/concepts/standard']}
|
||||
>>> view = ConceptConfigureView(cc1, TestRequest(form=form))
|
||||
>>> [getName(r.context) for r in view.resources()]
|
||||
[u'doc1']
|
||||
['doc1']
|
||||
>>> view.update()
|
||||
True
|
||||
>>> len(cc1.getResources())
|
||||
|
@ -316,10 +316,10 @@ Index attributes adapter
|
|||
>>> component.provideAdapter(FileAdapter, provides=IFile)
|
||||
>>> idx = IndexAttributes(doc1)
|
||||
>>> idx.text()
|
||||
u''
|
||||
''
|
||||
|
||||
>>> idx.title()
|
||||
u'doc1 Zope Info'
|
||||
'doc1 Zope Info'
|
||||
|
||||
|
||||
Views/Nodes: Menus, Menu Items, Listings, Pages, etc
|
||||
|
@ -343,14 +343,14 @@ The view manager has already been created during setup.
|
|||
The view space is typically built up with nodes; a node may be a top-level
|
||||
menu that may contain other nodes as menu or content items:
|
||||
|
||||
>>> m1 = views['m1'] = Node(u'Menu')
|
||||
>>> m11 = m1['m11'] = Node(u'Zope')
|
||||
>>> m111 = m11['m111'] = Node(u'Zope in General')
|
||||
>>> m112 = m11['m112'] = Node(u'Zope 3')
|
||||
>>> m1 = views['m1'] = Node('Menu')
|
||||
>>> m11 = m1['m11'] = Node('Zope')
|
||||
>>> m111 = m11['m111'] = Node('Zope in General')
|
||||
>>> m112 = m11['m112'] = Node('Zope 3')
|
||||
>>> m112.title
|
||||
u'Zope 3'
|
||||
'Zope 3'
|
||||
>>> m112.description
|
||||
u''
|
||||
''
|
||||
|
||||
There are a few convienence methods for accessing parent and child nodes:
|
||||
|
||||
|
@ -359,7 +359,7 @@ There are a few convienence methods for accessing parent and child nodes:
|
|||
>>> m11.getParentNode() is m1
|
||||
True
|
||||
>>> [getName(child) for child in m11.getChildNodes()]
|
||||
[u'm111', u'm112']
|
||||
['m111', 'm112']
|
||||
|
||||
What is returned by these may be controlled by the nodeType attribute:
|
||||
|
||||
|
@ -493,14 +493,14 @@ view; these views we have to provide as multi-adapters:
|
|||
>>> len(tt)
|
||||
9
|
||||
>>> sorted((t.token, t.title) for t in view.targetTypes())[1]
|
||||
('.loops/concepts/domain', u'Domain')
|
||||
('.loops/concepts/domain', 'Domain')
|
||||
>>> view.update()
|
||||
True
|
||||
>>> sorted(resources.keys())
|
||||
[u'd001.txt', u'd002.txt', u'd003.txt', u'doc1', u'm1.m11.m111']
|
||||
['d001.txt', 'd002.txt', 'd003.txt', 'doc1', 'm1.m11.m111']
|
||||
|
||||
>>> view.target.title, view.target.token
|
||||
('New Resource', u'.loops/resources/m1.m11.m111')
|
||||
('New Resource', '.loops/resources/m1.m11.m111')
|
||||
|
||||
A node object provides the targetSchema of its target:
|
||||
|
||||
|
@ -537,28 +537,28 @@ view for rendering.)
|
|||
>>> component.provideAdapter(LoopsType)
|
||||
>>> view = NodeView(m112, TestRequest())
|
||||
>>> view.renderTarget()
|
||||
u'<pre></pre>'
|
||||
>>> doc1.data = u'Test data\n\nAnother paragraph'
|
||||
'<pre></pre>'
|
||||
>>> doc1.data = 'Test data\n\nAnother paragraph'
|
||||
>>> view.renderTarget()
|
||||
u'<pre>Test data\n\nAnother paragraph</pre>'
|
||||
'<pre>Test data\n\nAnother paragraph</pre>'
|
||||
|
||||
>>> doc1.contentType = 'text/restructured'
|
||||
>>> doc1.data = u'Test data\n\nAnother `paragraph <para>`_'
|
||||
>>> doc1.data = 'Test data\n\nAnother `paragraph <para>`_'
|
||||
|
||||
>>> from loops.wiki.base import wikiLinksActive
|
||||
>>> wikiLinksActive(loopsRoot)
|
||||
False
|
||||
|
||||
>>> view.renderTarget()
|
||||
u'<p>Test data</p>\n<p>Another <a class="reference external" href="para">paragraph</a></p>\n'
|
||||
'<p>Test data</p>\n<p>Another <a class="reference external" href="para">paragraph</a></p>\n'
|
||||
|
||||
u'<p>Test data</p>\n<p>Another <a class="reference create"
|
||||
'<p>Test data</p>\n<p>Another <a class="reference create"
|
||||
href="http://127.0.0.1/loops/wiki/create.html?linkid=0000001">?paragraph</a></p>\n'
|
||||
|
||||
>>> #links = loopsRoot.getRecordManager()['links']
|
||||
>>> #links['0000001']
|
||||
|
||||
<Link ['42', 1, '', '... ...', u'para', None]: {}>
|
||||
<Link ['42', 1, '', '... ...', 'para', None]: {}>
|
||||
|
||||
If the target object is removed from its container all references
|
||||
to it are removed as well. (To make this work we have to handle
|
||||
|
@ -632,7 +632,7 @@ Let's add some more nodes and reorder them:
|
|||
>>> m114 = Node()
|
||||
>>> m11['m114'] = m114
|
||||
>>> m11.keys()
|
||||
[u'm111', u'm112', u'm113', u'm114']
|
||||
['m111', 'm112', 'm113', 'm114']
|
||||
|
||||
A special management view provides methods for moving objects down, up,
|
||||
to the bottom, and to the top.
|
||||
|
@ -641,10 +641,10 @@ to the bottom, and to the top.
|
|||
>>> view = OrderedContainerView(m11, TestRequest())
|
||||
>>> view.move_bottom(('m113',))
|
||||
>>> m11.keys()
|
||||
[u'm111', u'm112', u'm114', u'm113']
|
||||
['m111', 'm112', 'm114', 'm113']
|
||||
>>> view.move_up(('m114',), 1)
|
||||
>>> m11.keys()
|
||||
[u'm111', u'm114', u'm112', u'm113']
|
||||
['m111', 'm114', 'm112', 'm113']
|
||||
|
||||
|
||||
Breadcrumbs
|
||||
|
@ -661,9 +661,9 @@ Breadcrumbs
|
|||
>>> view = NodeView(m114, request)
|
||||
>>> request.annotations.setdefault('loops.view', {})['nodeView'] = view
|
||||
>>> view.breadcrumbs()
|
||||
[{'url': 'http://127.0.0.1/loops/views/m1', 'label': u'Menu'},
|
||||
{'url': 'http://127.0.0.1/loops/views/m1/m11', 'label': u'Zope'},
|
||||
{'url': 'http://127.0.0.1/loops/views/m1/m11/m114', 'label': u''}]
|
||||
[{'url': 'http://127.0.0.1/loops/views/m1', 'label': 'Menu'},
|
||||
{'url': 'http://127.0.0.1/loops/views/m1/m11', 'label': 'Zope'},
|
||||
{'url': 'http://127.0.0.1/loops/views/m1/m11/m114', 'label': ''}]
|
||||
|
||||
|
||||
End-user Forms and Special Views
|
||||
|
@ -705,8 +705,8 @@ been created during setup.
|
|||
>>> custType = TypeConcept(customer)
|
||||
>>> custType.options
|
||||
[]
|
||||
>>> cust1 = concepts['cust1'] = Concept(u'Zope Corporation')
|
||||
>>> cust2 = concepts['cust2'] = Concept(u'cyberconcepts')
|
||||
>>> cust1 = concepts['cust1'] = Concept('Zope Corporation')
|
||||
>>> cust2 = concepts['cust2'] = Concept('cyberconcepts')
|
||||
>>> for c in (cust1, cust2): c.conceptType = customer
|
||||
>>> custType.options = ('qualifier:assign',)
|
||||
>>> ConceptType(cust1).qualifiers
|
||||
|
@ -714,7 +714,7 @@ been created during setup.
|
|||
|
||||
>>> form = CreateObjectForm(m112, TestRequest())
|
||||
>>> form.presetTypesForAssignment
|
||||
[{'token': 'loops:concept:customer', 'title': u'Customer'}]
|
||||
[{'token': 'loops:concept:customer', 'title': 'Customer'}]
|
||||
|
||||
If the node's target is a type concept we don't get any assignments because
|
||||
it does not make much sense to assign resources or other concepts as
|
||||
|
@ -736,18 +736,18 @@ on data provided in this form:
|
|||
>>> note_tc = concepts['note']
|
||||
|
||||
>>> component.provideAdapter(NameChooser)
|
||||
>>> request = TestRequest(form={'title': u'Test Note',
|
||||
... 'form.type': u'.loops/concepts/note',
|
||||
... 'contentType': u'text/restructured',
|
||||
... 'linkUrl': u'http://'})
|
||||
>>> request = TestRequest(form={'title': 'Test Note',
|
||||
... 'form.type': '.loops/concepts/note',
|
||||
... 'contentType': 'text/restructured',
|
||||
... 'linkUrl': 'http://'})
|
||||
>>> view = NodeView(m112, request)
|
||||
>>> cont = CreateObject(view, request)
|
||||
>>> cont.update()
|
||||
False
|
||||
>>> sorted(resources.keys())
|
||||
[...u'test_note'...]
|
||||
[...'test_note'...]
|
||||
>>> resources['test_note'].title
|
||||
u'Test Note'
|
||||
'Test Note'
|
||||
|
||||
If there is a concept selected in the combo box we assign this to the newly
|
||||
created object:
|
||||
|
@ -755,8 +755,8 @@ created object:
|
|||
>>> from loops import util
|
||||
>>> topicUid = util.getUidForObject(topic)
|
||||
>>> predicateUid = util.getUidForObject(concepts.getDefaultPredicate())
|
||||
>>> request = TestRequest(form={'title': u'Test Note',
|
||||
... 'form.type': u'.loops/concepts/note',
|
||||
>>> request = TestRequest(form={'title': 'Test Note',
|
||||
... 'form.type': '.loops/concepts/note',
|
||||
... 'form.assignments.selected':
|
||||
... [':'.join((topicUid, predicateUid))]})
|
||||
>>> view = NodeView(m112, request)
|
||||
|
@ -764,22 +764,22 @@ created object:
|
|||
>>> cont.update()
|
||||
False
|
||||
>>> sorted(resources.keys())
|
||||
[...u'test_note-2'...]
|
||||
[...'test_note-2'...]
|
||||
>>> note = resources['test_note-2']
|
||||
>>> sorted(t.__name__ for t in note.getConcepts())
|
||||
[u'note', u'topic']
|
||||
['note', 'topic']
|
||||
|
||||
When creating an object its name may be automatically generated using the title
|
||||
of the object. Let's make sure that the name chooser also handles special
|
||||
and possibly critcal cases:
|
||||
|
||||
>>> nc = NameChooser(resources)
|
||||
>>> nc.chooseName(u'', Resource(u'abc: (cde)'))
|
||||
u'abc__cde'
|
||||
>>> nc.chooseName(u'', Resource(u'\xdcml\xe4ut'))
|
||||
u'uemlaeut'
|
||||
>>> nc.chooseName(u'', Resource(u'A very very loooooong title'))
|
||||
u'a_title'
|
||||
>>> nc.chooseName('', Resource('abc: (cde)'))
|
||||
'abc__cde'
|
||||
>>> nc.chooseName('', Resource('\xdcml\xe4ut'))
|
||||
'uemlaeut'
|
||||
>>> nc.chooseName('', Resource('A very very loooooong title'))
|
||||
'a_title'
|
||||
|
||||
Editing an Object
|
||||
-----------------
|
||||
|
@ -804,22 +804,22 @@ The new technique uses the ``fields`` and ``data`` attributes...
|
|||
linkText textline False None
|
||||
|
||||
>>> view.data
|
||||
{'linkUrl': u'http://', 'contentType': u'text/restructured', 'data': u'',
|
||||
'linkText': u'', 'title': u'Test Note'}
|
||||
{'linkUrl': 'http://', 'contentType': 'text/restructured', 'data': '',
|
||||
'linkText': '', 'title': 'Test Note'}
|
||||
|
||||
The object is changed via a FormController adapter created for
|
||||
a NodeView.
|
||||
|
||||
>>> form = dict(
|
||||
... title=u'Test Note - changed',
|
||||
... contentType=u'text/plain',)
|
||||
... title='Test Note - changed',
|
||||
... contentType='text/plain',)
|
||||
>>> request = TestRequest(form=form)
|
||||
>>> view = NodeView(m112, request)
|
||||
>>> cont = EditObject(view, request)
|
||||
>>> cont.update()
|
||||
False
|
||||
>>> resources['test_note'].title
|
||||
u'Test Note - changed'
|
||||
'Test Note - changed'
|
||||
|
||||
Virtual Targets
|
||||
---------------
|
||||
|
@ -951,7 +951,7 @@ To be done...
|
|||
>>> obj = resources['test_note']
|
||||
>>> cxObj = cached(obj)
|
||||
>>> [p.object.title for p in cxObj.getAllParents()]
|
||||
[u'Note', u'Type']
|
||||
['Note', 'Type']
|
||||
|
||||
|
||||
Security
|
||||
|
|
26
loops/external/element.py
vendored
26
loops/external/element.py
vendored
|
@ -1,23 +1,6 @@
|
|||
#
|
||||
# Copyright (c) 2012 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
|
||||
#
|
||||
# loops.external.element
|
||||
|
||||
"""
|
||||
Basic implementation of the elements used for the intermediate format for export
|
||||
""" Basic implementation of the elements used for the intermediate format for export
|
||||
and import of loops objects.
|
||||
"""
|
||||
|
||||
|
@ -25,7 +8,7 @@ import os
|
|||
from zope import component
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope.dottedname.resolve import resolve
|
||||
from zope.interface import Interface, implements
|
||||
from zope.interface import Interface, implementer
|
||||
from zope.traversing.api import getName, traverse
|
||||
|
||||
from cybertools.composer.interfaces import IInstance
|
||||
|
@ -41,10 +24,9 @@ from loops.predicate import adaptedRelation
|
|||
from loops.view import Node
|
||||
|
||||
|
||||
@implementer(IElement)
|
||||
class Element(dict):
|
||||
|
||||
implements(IElement)
|
||||
|
||||
elementType = ''
|
||||
posArgs = ()
|
||||
object = None
|
||||
|
|
|
@ -25,7 +25,7 @@ from zope.security.management import setSecurityPolicy
|
|||
from zope.securitypolicy.zopepolicy import ZopeSecurityPolicy
|
||||
from zope.securitypolicy.principalrole import AnnotationPrincipalRoleManager
|
||||
from zope.securitypolicy.rolepermission import AnnotationRolePermissionManager
|
||||
from zope.session.interfaces import IClientIdManager, ISessionDataContainer
|
||||
from zope.session.interfaces import IClientId, IClientIdManager, ISessionDataContainer
|
||||
from zope.session import session
|
||||
|
||||
from cybertools.browser.controller import Controller
|
||||
|
@ -37,6 +37,7 @@ from cybertools.composer.schema.field import FieldInstance, \
|
|||
from cybertools.composer.schema.field import FileUploadFieldInstance
|
||||
from cybertools.composer.schema.grid.field import RecordsFieldInstance
|
||||
from cybertools.composer.schema.instance import Instance, Editor
|
||||
from cybertools.meta.interfaces import IOptions
|
||||
from cybertools.relation.tests import IntIdsStub
|
||||
from cybertools.relation.registry import RelationRegistry, IIndexableRelation
|
||||
from cybertools.relation.interfaces import IRelation, IRelationRegistry
|
||||
|
@ -123,7 +124,7 @@ class TestSite(object):
|
|||
component.provideAdapter(AnnotationPrincipalRoleManager, (ILoopsObject,))
|
||||
component.provideAdapter(AnnotationRolePermissionManager, (ILoopsObject,))
|
||||
component.provideUtility(principalRegistry, IAuthentication)
|
||||
component.provideAdapter(session.ClientId)
|
||||
component.provideAdapter(session.ClientId, provides=IClientId)
|
||||
component.provideAdapter(session.Session)
|
||||
component.provideUtility(session.RAMSessionDataContainer(),
|
||||
ISessionDataContainer)
|
||||
|
@ -153,11 +154,11 @@ class TestSite(object):
|
|||
component.provideAdapter(BaseSecuritySetter)
|
||||
component.provideAdapter(ConceptSecuritySetter)
|
||||
component.provideAdapter(ResourceSecuritySetter)
|
||||
component.provideAdapter(LoopsOptions)
|
||||
component.provideAdapter(PredicateOptions)
|
||||
component.provideAdapter(QueryOptions)
|
||||
component.provideAdapter(TypeOptions)
|
||||
component.provideUtility(GlobalOptions())
|
||||
component.provideAdapter(LoopsOptions, provides=IOptions)
|
||||
component.provideAdapter(PredicateOptions, provides=IOptions)
|
||||
component.provideAdapter(QueryOptions, provides=IOptions)
|
||||
component.provideAdapter(TypeOptions, provides=IOptions)
|
||||
component.provideUtility(GlobalOptions(), IOptions)
|
||||
component.provideAdapter(VersionableResource)
|
||||
|
||||
component.provideAdapter(Instance)
|
||||
|
|
|
@ -1,29 +1,12 @@
|
|||
#
|
||||
# Copyright (c) 2014 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
|
||||
#
|
||||
# loops.versioning.versionable
|
||||
|
||||
"""
|
||||
Utilities for managing version informations.
|
||||
""" Utilities for managing version informations.
|
||||
"""
|
||||
|
||||
from BTrees.OOBTree import OOBTree
|
||||
from zope import component
|
||||
from zope.component import adapts
|
||||
from zope.interface import implements, Attribute
|
||||
from zope.interface import implementer, Attribute
|
||||
from zope.cachedescriptors.property import Lazy
|
||||
from zope.schema.interfaces import IField
|
||||
from zope.traversing.api import getName, getParent
|
||||
|
@ -41,11 +24,11 @@ _not_found = object()
|
|||
attrPattern = '__version_%s__'
|
||||
|
||||
|
||||
@implementer(IVersionable)
|
||||
class VersionableResource(object):
|
||||
""" An adapter that enables a resource to store version information.
|
||||
"""
|
||||
|
||||
implements(IVersionable)
|
||||
adapts(IResource)
|
||||
|
||||
def __init__(self, context):
|
||||
|
|
Loading…
Add table
Reference in a new issue