more Python3 fixes: compound, knowledge, versioning
This commit is contained in:
parent
010106406d
commit
1da71c72a9
12 changed files with 99 additions and 244 deletions
|
@ -1,26 +1,9 @@
|
||||||
#
|
# loops.browser.lobo.standard
|
||||||
# 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
""" View classes for lobo (blueprint-based) layouts.
|
||||||
View classes for lobo (blueprint-based) layouts.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from cgi import parse_qs
|
from urllib.parse import parse_qs
|
||||||
from zope import interface, component
|
from zope import interface, component
|
||||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
from zope.app.pagetemplate import ViewPageTemplateFile
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
|
|
|
@ -33,13 +33,13 @@ We first create the compound type and one instance of the newly created
|
||||||
type. We also need an ``ispartof`` predicate.
|
type. We also need an ``ispartof`` predicate.
|
||||||
|
|
||||||
>>> tCompound = addAndConfigureObject(concepts, Concept, 'compound',
|
>>> tCompound = addAndConfigureObject(concepts, Concept, 'compound',
|
||||||
... title=u'Compound',
|
... title='Compound',
|
||||||
... conceptType=tType, typeInterface=ICompound)
|
... conceptType=tType, typeInterface=ICompound)
|
||||||
>>> c01 = addAndConfigureObject(concepts, Concept, 'c01',
|
>>> c01 = addAndConfigureObject(concepts, Concept, 'c01',
|
||||||
... title=u'Compound #01', conceptType=tCompound)
|
... title='Compound #01', conceptType=tCompound)
|
||||||
>>> tPredicate = concepts.getPredicateType()
|
>>> tPredicate = concepts.getPredicateType()
|
||||||
>>> isPartof = addAndConfigureObject(concepts, Concept, 'ispartof',
|
>>> isPartof = addAndConfigureObject(concepts, Concept, 'ispartof',
|
||||||
... title=u'is Part of', conceptType=tPredicate)
|
... title='is Part of', conceptType=tPredicate)
|
||||||
|
|
||||||
In order to access the compound concept's attributes we have to adapt
|
In order to access the compound concept's attributes we have to adapt
|
||||||
it.
|
it.
|
||||||
|
@ -49,31 +49,31 @@ it.
|
||||||
|
|
||||||
Now we are able to add resources to it.
|
Now we are able to add resources to it.
|
||||||
|
|
||||||
>>> aC01.add(resources[u'd003.txt'])
|
>>> aC01.add(resources['d003.txt'])
|
||||||
>>> aC01.add(resources[u'd001.txt'])
|
>>> aC01.add(resources['d001.txt'])
|
||||||
|
|
||||||
>>> [getName(p) for p in aC01.getParts()]
|
>>> [getName(p) for p in aC01.getParts()]
|
||||||
[u'd003.txt', u'd001.txt']
|
['d003.txt', 'd001.txt']
|
||||||
|
|
||||||
>>> aC01.add(resources[u'd001.txt'], 0)
|
>>> aC01.add(resources['d001.txt'], 0)
|
||||||
>>> [getName(p) for p in aC01.getParts()]
|
>>> [getName(p) for p in aC01.getParts()]
|
||||||
[u'd001.txt', u'd003.txt', u'd001.txt']
|
['d001.txt', 'd003.txt', 'd001.txt']
|
||||||
|
|
||||||
>>> aC01.add(resources[u'd002.txt'], -1)
|
>>> aC01.add(resources['d002.txt'], -1)
|
||||||
>>> [getName(p) for p in aC01.getParts()]
|
>>> [getName(p) for p in aC01.getParts()]
|
||||||
[u'd001.txt', u'd003.txt', u'd002.txt', u'd001.txt']
|
['d001.txt', 'd003.txt', 'd002.txt', 'd001.txt']
|
||||||
|
|
||||||
We can reorder the parts of a compound.
|
We can reorder the parts of a compound.
|
||||||
|
|
||||||
>>> aC01.reorder([resources[u'd002.txt'], resources[u'd001.txt'], ])
|
>>> aC01.reorder([resources['d002.txt'], resources['d001.txt'], ])
|
||||||
>>> [getName(p) for p in aC01.getParts()]
|
>>> [getName(p) for p in aC01.getParts()]
|
||||||
[u'd002.txt', u'd001.txt', u'd003.txt', u'd001.txt']
|
['d002.txt', 'd001.txt', 'd003.txt', 'd001.txt']
|
||||||
|
|
||||||
And remove a part from the compound.
|
And remove a part from the compound.
|
||||||
|
|
||||||
>>> aC01.remove(resources[u'd001.txt'], 1)
|
>>> aC01.remove(resources['d001.txt'], 1)
|
||||||
>>> [getName(p) for p in aC01.getParts()]
|
>>> [getName(p) for p in aC01.getParts()]
|
||||||
[u'd002.txt', u'd003.txt', u'd001.txt']
|
['d002.txt', 'd003.txt', 'd001.txt']
|
||||||
|
|
||||||
|
|
||||||
Blogs
|
Blogs
|
||||||
|
@ -83,23 +83,23 @@ Blogs
|
||||||
>>> from loops.compound.blog.interfaces import IBlogPost
|
>>> from loops.compound.blog.interfaces import IBlogPost
|
||||||
>>> component.provideAdapter(BlogPost, provides=IBlogPost)
|
>>> component.provideAdapter(BlogPost, provides=IBlogPost)
|
||||||
|
|
||||||
>>> tBlog = addAndConfigureObject(concepts, Concept, 'blog', title=u'Blog',
|
>>> tBlog = addAndConfigureObject(concepts, Concept, 'blog', title='Blog',
|
||||||
... conceptType=tType)
|
... conceptType=tType)
|
||||||
>>> tBlogPost = addAndConfigureObject(concepts, Concept, 'blogpost',
|
>>> tBlogPost = addAndConfigureObject(concepts, Concept, 'blogpost',
|
||||||
... title=u'Blog Post', conceptType=tType,
|
... title='Blog Post', conceptType=tType,
|
||||||
... typeInterface=IBlogPost)
|
... typeInterface=IBlogPost)
|
||||||
|
|
||||||
>>> myBlog = addAndConfigureObject(concepts, Concept, 'myblog', title=u'My Blog',
|
>>> myBlog = addAndConfigureObject(concepts, Concept, 'myblog', title='My Blog',
|
||||||
... conceptType=tBlog)
|
... conceptType=tBlog)
|
||||||
|
|
||||||
>>> firstPost = addAndConfigureObject(concepts, Concept, 'firstpost',
|
>>> firstPost = addAndConfigureObject(concepts, Concept, 'firstpost',
|
||||||
... title=u'My first post', conceptType=tBlogPost)
|
... title='My first post', conceptType=tBlogPost)
|
||||||
|
|
||||||
>>> aFirstPost = adapted(firstPost)
|
>>> aFirstPost = adapted(firstPost)
|
||||||
>>> aFirstPost.date
|
>>> aFirstPost.date
|
||||||
>>> aFirstPost.text = u'My first blog post.'
|
>>> aFirstPost.text = 'My first blog post.'
|
||||||
>>> aFirstPost.text
|
>>> aFirstPost.text
|
||||||
u'My first blog post.'
|
'My first blog post.'
|
||||||
>>> aFirstPost.creator
|
>>> aFirstPost.creator
|
||||||
|
|
||||||
Blog and BlogPost views
|
Blog and BlogPost views
|
||||||
|
@ -114,7 +114,7 @@ a new post.
|
||||||
|
|
||||||
>>> view = BlogView(myBlog, TestRequest())
|
>>> view = BlogView(myBlog, TestRequest())
|
||||||
>>> for act in view.getActions('portlet'):
|
>>> for act in view.getActions('portlet'):
|
||||||
... print act.name
|
... print(act.name)
|
||||||
createBlogPost
|
createBlogPost
|
||||||
|
|
||||||
>>> view = BlogPostView(firstPost, TestRequest())
|
>>> view = BlogPostView(firstPost, TestRequest())
|
||||||
|
@ -143,13 +143,13 @@ and a corresponding person.
|
||||||
>>> auth = setupData.auth
|
>>> auth = setupData.auth
|
||||||
>>> tPerson = concepts['person']
|
>>> tPerson = concepts['person']
|
||||||
|
|
||||||
>>> userJohn = auth.definePrincipal('users.john', u'John', login='john')
|
>>> userJohn = auth.definePrincipal('users.john', 'John', login='john')
|
||||||
>>> persJohn = addAndConfigureObject(concepts, Concept, 'person.john',
|
>>> persJohn = addAndConfigureObject(concepts, Concept, 'person.john',
|
||||||
... title=u'John Smith', conceptType=tPerson,
|
... title='John Smith', conceptType=tPerson,
|
||||||
... userId='users.john')
|
... userId='users.john')
|
||||||
|
|
||||||
>>> blogJohn = addAndConfigureObject(concepts, Concept, 'blog.john',
|
>>> blogJohn = addAndConfigureObject(concepts, Concept, 'blog.john',
|
||||||
... title=u'John\'s Blog', conceptType=tBlog)
|
... title='John\'s Blog', conceptType=tBlog)
|
||||||
>>> persJohn.assignChild(blogJohn)
|
>>> persJohn.assignChild(blogJohn)
|
||||||
|
|
||||||
Let's now login as the newly defined user.
|
Let's now login as the newly defined user.
|
||||||
|
@ -178,9 +178,9 @@ used for creating the blog post.
|
||||||
>>> home.target = myBlog
|
>>> home.target = myBlog
|
||||||
|
|
||||||
>>> from loops.compound.blog.browser import CreateBlogPostForm, CreateBlogPost
|
>>> from loops.compound.blog.browser import CreateBlogPostForm, CreateBlogPost
|
||||||
>>> input = {'title': u'John\'s first post', 'text': u'Text of John\'s post',
|
>>> input = {'title': 'John\'s first post', 'text': 'Text of John\'s post',
|
||||||
... 'date': '2008-02-02T15:54:11',
|
... 'date': '2008-02-02T15:54:11',
|
||||||
... 'privateComment': u'John\'s private comment',
|
... 'privateComment': 'John\'s private comment',
|
||||||
... 'form.type': '.loops/concepts/blogpost'}
|
... 'form.type': '.loops/concepts/blogpost'}
|
||||||
>>> cbpForm = CreateBlogPostForm(home, TestRequest(form=input))
|
>>> cbpForm = CreateBlogPostForm(home, TestRequest(form=input))
|
||||||
>>> cbpController = CreateBlogPost(cbpForm, cbpForm.request)
|
>>> cbpController = CreateBlogPost(cbpForm, cbpForm.request)
|
||||||
|
@ -192,11 +192,11 @@ used for creating the blog post.
|
||||||
1
|
1
|
||||||
>>> postJohn0 = posts[0]
|
>>> postJohn0 = posts[0]
|
||||||
>>> postJohn0.title
|
>>> postJohn0.title
|
||||||
u"John's first post"
|
"John's first post"
|
||||||
|
|
||||||
>>> postJohn0Text = adapted(postJohn0.getResources()[0])
|
>>> postJohn0Text = adapted(postJohn0.getResources()[0])
|
||||||
>>> postJohn0Text.data
|
>>> postJohn0Text.data
|
||||||
u"Text of John's post"
|
"Text of John's post"
|
||||||
|
|
||||||
|
|
||||||
Security
|
Security
|
||||||
|
@ -269,7 +269,7 @@ So let's now switch to another user. On a global level, Martha also has
|
||||||
the ContentManager role, i.e. she is allowed to edit content objects.
|
the ContentManager role, i.e. she is allowed to edit content objects.
|
||||||
Nevertheless she is not allowed to change John's blog post.
|
Nevertheless she is not allowed to change John's blog post.
|
||||||
|
|
||||||
>>> userMartha = auth.definePrincipal('users.martha', u'Martha', login='martha')
|
>>> userMartha = auth.definePrincipal('users.martha', 'Martha', login='martha')
|
||||||
>>> assignRole('zope.Member', 'users.martha')
|
>>> assignRole('zope.Member', 'users.martha')
|
||||||
>>> assignRole('zope.ContentManager', 'users.martha')
|
>>> assignRole('zope.ContentManager', 'users.martha')
|
||||||
|
|
||||||
|
@ -322,29 +322,29 @@ Micro Articles
|
||||||
>>> component.provideAdapter(MicroArt, provides=IMicroArt)
|
>>> component.provideAdapter(MicroArt, provides=IMicroArt)
|
||||||
|
|
||||||
>>> tMicroArt = addAndConfigureObject(concepts, Concept, 'microart',
|
>>> tMicroArt = addAndConfigureObject(concepts, Concept, 'microart',
|
||||||
... title=u'MicroArt', conceptType=tType,
|
... title='MicroArt', conceptType=tType,
|
||||||
... typeInterface=IMicroArt)
|
... typeInterface=IMicroArt)
|
||||||
|
|
||||||
>>> ma01 = addAndConfigureObject(concepts, Concept, 'ma01',
|
>>> ma01 = addAndConfigureObject(concepts, Concept, 'ma01',
|
||||||
... conceptType=tMicroArt,
|
... conceptType=tMicroArt,
|
||||||
... title=u'Organizational Knowledge',
|
... title='Organizational Knowledge',
|
||||||
... story=u'Systemic KM talks about organizational knowledge.',
|
... story='Systemic KM talks about organizational knowledge.',
|
||||||
... insight=u'Organizational knowledge is not visible.',
|
... insight='Organizational knowledge is not visible.',
|
||||||
... consequences=u'Use examples. Look for strucure and rules. '
|
... consequences='Use examples. Look for strucure and rules. '
|
||||||
... u'Knowledge shows itself in actions.',
|
... 'Knowledge shows itself in actions.',
|
||||||
... followUps=u'What about collective intelligence? '
|
... followUps='What about collective intelligence? '
|
||||||
... u'How does an organization express itself?')
|
... 'How does an organization express itself?')
|
||||||
|
|
||||||
>>> ma01._insight
|
>>> ma01._insight
|
||||||
u'Organizational knowledge is not visible.'
|
'Organizational knowledge is not visible.'
|
||||||
>>> list(resources)
|
>>> list(resources)
|
||||||
[..., u'ma01_story']
|
[..., 'ma01_story']
|
||||||
|
|
||||||
>>> adMa01 = adapted(ma01)
|
>>> adMa01 = adapted(ma01)
|
||||||
>>> adMa01.insight
|
>>> adMa01.insight
|
||||||
u'Organizational knowledge is not visible.'
|
'Organizational knowledge is not visible.'
|
||||||
>>> adMa01.story
|
>>> adMa01.story
|
||||||
u'Systemic KM talks about organizational knowledge.'
|
'Systemic KM talks about organizational knowledge.'
|
||||||
|
|
||||||
|
|
||||||
Books, Sections, and Pages
|
Books, Sections, and Pages
|
||||||
|
|
|
@ -1,37 +1,19 @@
|
||||||
#
|
# loops.compound.base
|
||||||
# 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
""" Compound objects like articles, blog posts, storyboard items, ...
|
||||||
Compound objects like articles, blog posts, storyboard items, ...
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
from zope.interface import implements
|
from zope.interface import implementer
|
||||||
from zope.traversing.api import getName
|
from zope.traversing.api import getName
|
||||||
|
|
||||||
from loops.common import AdapterBase
|
from loops.common import AdapterBase
|
||||||
from loops.compound.interfaces import ICompound, compoundPredicateNames
|
from loops.compound.interfaces import ICompound, compoundPredicateNames
|
||||||
|
|
||||||
|
|
||||||
|
@implementer(ICompound)
|
||||||
class Compound(AdapterBase):
|
class Compound(AdapterBase):
|
||||||
|
|
||||||
implements(ICompound)
|
|
||||||
|
|
||||||
compoundPredicateNames = compoundPredicateNames
|
compoundPredicateNames = compoundPredicateNames
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
|
|
@ -1,28 +1,11 @@
|
||||||
#
|
# loops.compound.blog.post
|
||||||
# Copyright (c) 2013 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
""" Blogs and blog posts.
|
||||||
Blogs and blog posts.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
from zope.dublincore.interfaces import IZopeDublinCore
|
from zope.dublincore.interfaces import IZopeDublinCore
|
||||||
from zope.interface import implements
|
from zope.interface import implementer
|
||||||
from zope.event import notify
|
from zope.event import notify
|
||||||
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
|
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
|
||||||
from zope import schema
|
from zope import schema
|
||||||
|
@ -40,10 +23,9 @@ from loops.type import TypeInterfaceSourceList
|
||||||
TypeInterfaceSourceList.typeInterfaces += (ISimpleBlogPost, IBlogPost,)
|
TypeInterfaceSourceList.typeInterfaces += (ISimpleBlogPost, IBlogPost,)
|
||||||
|
|
||||||
|
|
||||||
|
@implementer(ISimpleBlogPost)
|
||||||
class SimpleBlogPost(Compound):
|
class SimpleBlogPost(Compound):
|
||||||
|
|
||||||
implements(ISimpleBlogPost)
|
|
||||||
|
|
||||||
textContentType = 'text/html'
|
textContentType = 'text/html'
|
||||||
|
|
||||||
_adapterAttributes = Compound._adapterAttributes + ('creator',)
|
_adapterAttributes = Compound._adapterAttributes + ('creator',)
|
||||||
|
@ -57,10 +39,9 @@ class SimpleBlogPost(Compound):
|
||||||
return cr and cr[0] or None
|
return cr and cr[0] or None
|
||||||
|
|
||||||
|
|
||||||
|
@implementer(IBlogPost)
|
||||||
class BlogPost(Compound):
|
class BlogPost(Compound):
|
||||||
|
|
||||||
implements(IBlogPost)
|
|
||||||
|
|
||||||
_adapterAttributes = Compound._adapterAttributes + ('text', 'private', 'creator',)
|
_adapterAttributes = Compound._adapterAttributes + ('text', 'private', 'creator',)
|
||||||
_contextAttributes = Compound._contextAttributes + ['date', 'privateComment']
|
_contextAttributes = Compound._contextAttributes + ['date', 'privateComment']
|
||||||
_noexportAttributes = ('creator', 'text', 'private')
|
_noexportAttributes = ('creator', 'text', 'private')
|
||||||
|
|
|
@ -1,28 +1,10 @@
|
||||||
#
|
# loops.compound.blog.security
|
||||||
# Copyright (c) 2013 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
""" Security settings for blogs and blog posts.
|
||||||
Security settings for blogs and blog posts.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
from zope.component import adapts
|
from zope.component import adapts
|
||||||
from zope.interface import implements
|
|
||||||
from zope.traversing.api import getName
|
from zope.traversing.api import getName
|
||||||
|
|
||||||
from loops.compound.blog.interfaces import IBlogPost
|
from loops.compound.blog.interfaces import IBlogPost
|
||||||
|
|
|
@ -1,28 +1,11 @@
|
||||||
#
|
# loops.compound.book.browser
|
||||||
# Copyright (c) 2017 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
""" View class(es) book/section/page structures.
|
||||||
View class(es) book/section/page structures.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from cgi import parse_qs
|
from urllib.parse import parse_qs
|
||||||
from zope import interface, component
|
from zope import interface, component
|
||||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
from zope.browserpage import ViewPageTemplateFile
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
from zope.traversing.api import getName
|
from zope.traversing.api import getName
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,11 @@
|
||||||
#
|
# loops.compound.microart.base
|
||||||
# Copyright (c) 2011 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
""" Micro articles (MicroArt).
|
||||||
Micro articles (MicroArt).
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
from zope.dublincore.interfaces import IZopeDublinCore
|
from zope.dublincore.interfaces import IZopeDublinCore
|
||||||
from zope.interface import implements
|
from zope.interface import implementer
|
||||||
from zope.event import notify
|
from zope.event import notify
|
||||||
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
|
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
|
||||||
from zope import schema
|
from zope import schema
|
||||||
|
@ -39,10 +22,9 @@ from loops.type import TypeInterfaceSourceList
|
||||||
TypeInterfaceSourceList.typeInterfaces += (IMicroArt,)
|
TypeInterfaceSourceList.typeInterfaces += (IMicroArt,)
|
||||||
|
|
||||||
|
|
||||||
|
@implementer(IMicroArt)
|
||||||
class MicroArt(Compound):
|
class MicroArt(Compound):
|
||||||
|
|
||||||
implements(IMicroArt)
|
|
||||||
|
|
||||||
_contextAttributes = list(IMicroArt)
|
_contextAttributes = list(IMicroArt)
|
||||||
_adapterAttributes = Compound._adapterAttributes + ('story',)
|
_adapterAttributes = Compound._adapterAttributes + ('story',)
|
||||||
_noexportAttributes = ('story',)
|
_noexportAttributes = ('story',)
|
||||||
|
|
|
@ -54,12 +54,12 @@ from their typeInterface adapters we here append a 'C' to the name of
|
||||||
the variables:
|
the variables:
|
||||||
|
|
||||||
>>> from loops.concept import Concept
|
>>> from loops.concept import Concept
|
||||||
>>> progLangC = concepts['progLang'] = Concept(u'Programming Language')
|
>>> progLangC = concepts['progLang'] = Concept('Programming Language')
|
||||||
>>> ooProgC = concepts['ooProg'] = Concept(u'Object-oriented Programming')
|
>>> ooProgC = concepts['ooProg'] = Concept('Object-oriented Programming')
|
||||||
>>> pythonC = concepts['python'] = Concept(u'Python')
|
>>> pythonC = concepts['python'] = Concept('Python')
|
||||||
>>> pyBasicsC = concepts['pyBasics'] = Concept(u'Python Basics')
|
>>> pyBasicsC = concepts['pyBasics'] = Concept('Python Basics')
|
||||||
>>> pyOoC = concepts['pyOo'] = Concept(u'OO Programming with Python')
|
>>> pyOoC = concepts['pyOo'] = Concept('OO Programming with Python')
|
||||||
>>> pySpecialsC = concepts['pySpecials'] = Concept(u'Python Specials')
|
>>> pySpecialsC = concepts['pySpecials'] = Concept('Python Specials')
|
||||||
|
|
||||||
>>> topicConcepts = (progLangC, ooProgC, pythonC, pyBasicsC, pyOoC, pySpecialsC)
|
>>> topicConcepts = (progLangC, ooProgC, pythonC, pyBasicsC, pyOoC, pySpecialsC)
|
||||||
|
|
||||||
|
@ -78,13 +78,13 @@ the variables:
|
||||||
|
|
||||||
We now create a person and assign some knowledge to it:
|
We now create a person and assign some knowledge to it:
|
||||||
|
|
||||||
>>> johnC = concepts['john'] = Concept(u'John')
|
>>> johnC = concepts['john'] = Concept('John')
|
||||||
>>> johnC.conceptType = person
|
>>> johnC.conceptType = person
|
||||||
|
|
||||||
>>> john = IPerson(johnC)
|
>>> john = IPerson(johnC)
|
||||||
>>> john.knows(pyBasics)
|
>>> john.knows(pyBasics)
|
||||||
>>> list(john.getKnowledge())[0].title
|
>>> list(john.getKnowledge())[0].title
|
||||||
u'Python Basics'
|
'Python Basics'
|
||||||
|
|
||||||
Now let's get to tasks - a task is used as a requirement profile, i.e.
|
Now let's get to tasks - a task is used as a requirement profile, i.e.
|
||||||
it requires a certain set of knowledge elements:
|
it requires a certain set of knowledge elements:
|
||||||
|
@ -100,7 +100,7 @@ a position with the requirement profile:
|
||||||
|
|
||||||
>>> missing = john.getMissingKnowledge(task01)
|
>>> missing = john.getMissingKnowledge(task01)
|
||||||
>>> [m.title for m in missing]
|
>>> [m.title for m in missing]
|
||||||
[u'Object-oriented Programming', u'OO Programming with Python']
|
['Object-oriented Programming', 'OO Programming with Python']
|
||||||
|
|
||||||
Luckily there are a few elearning content objects out there that
|
Luckily there are a few elearning content objects out there that
|
||||||
provide some of the knowledge needed:
|
provide some of the knowledge needed:
|
||||||
|
@ -155,7 +155,7 @@ For testing, we first have to provide the needed utilities and settings
|
||||||
>>> principalAnnotations = PrincipalAnnotationUtility()
|
>>> principalAnnotations = PrincipalAnnotationUtility()
|
||||||
>>> component.provideUtility(principalAnnotations, IPrincipalAnnotationUtility)
|
>>> component.provideUtility(principalAnnotations, IPrincipalAnnotationUtility)
|
||||||
|
|
||||||
>>> principal = auth.definePrincipal('users.john', u'John', login='john')
|
>>> principal = auth.definePrincipal('users.john', 'John', login='john')
|
||||||
>>> john.userId = 'users.john'
|
>>> john.userId = 'users.john'
|
||||||
|
|
||||||
>>> from zope.publisher.browser import TestRequest
|
>>> from zope.publisher.browser import TestRequest
|
||||||
|
|
|
@ -1,30 +1,13 @@
|
||||||
#
|
# loops.knowledge.survey.browser
|
||||||
# Copyright (c) 2016 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
""" Definition of view classes and other browser related stuff for
|
||||||
Definition of view classes and other browser related stuff for
|
|
||||||
surveys and self-assessments.
|
surveys and self-assessments.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
from cStringIO import StringIO
|
from io import StringIO
|
||||||
import math
|
import math
|
||||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
from zope.browserpage import ViewPageTemplateFile
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
from zope.i18n import translate
|
from zope.i18n import translate
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,10 @@
|
||||||
#
|
# loops.knowledge.survey.response
|
||||||
# Copyright (c) 2016 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
""" Handling survey responses.
|
||||||
Handling survey responses.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope.component import adapts
|
from zope.component import adapts
|
||||||
from zope.interface import implements
|
from zope.interface import implementer
|
||||||
|
|
||||||
from cybertools.tracking.btree import Track
|
from cybertools.tracking.btree import Track
|
||||||
from cybertools.tracking.interfaces import ITrackingStorage
|
from cybertools.tracking.interfaces import ITrackingStorage
|
||||||
|
@ -29,10 +12,9 @@ from loops.knowledge.survey.interfaces import IResponse, IResponses
|
||||||
from loops.organize.tracking.base import BaseRecordManager
|
from loops.organize.tracking.base import BaseRecordManager
|
||||||
|
|
||||||
|
|
||||||
|
@implementer(IResponses)
|
||||||
class Responses(BaseRecordManager):
|
class Responses(BaseRecordManager):
|
||||||
|
|
||||||
implements(IResponses)
|
|
||||||
|
|
||||||
storageName = 'survey_responses'
|
storageName = 'survey_responses'
|
||||||
personId = None
|
personId = None
|
||||||
institutionId = None
|
institutionId = None
|
||||||
|
@ -84,9 +66,8 @@ class Responses(BaseRecordManager):
|
||||||
return self.storage.query(taskId=self.uid)
|
return self.storage.query(taskId=self.uid)
|
||||||
|
|
||||||
|
|
||||||
|
@implementer(IResponse)
|
||||||
class Response(Track):
|
class Response(Track):
|
||||||
|
|
||||||
implements(IResponse)
|
|
||||||
|
|
||||||
typeName = 'Response'
|
typeName = 'Response'
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@ loops - Linked Objects for Organization and Processing Services
|
||||||
|
|
||||||
Managing versions of resources.
|
Managing versions of resources.
|
||||||
|
|
||||||
($Id$)
|
|
||||||
|
|
||||||
|
|
||||||
Setting up a loops Site and Utilities
|
Setting up a loops Site and Utilities
|
||||||
=====================================
|
=====================================
|
||||||
|
@ -45,7 +43,7 @@ adapter on the object.
|
||||||
|
|
||||||
>>> d001 = resources['d001.txt']
|
>>> d001 = resources['d001.txt']
|
||||||
>>> d001.title
|
>>> d001.title
|
||||||
u'Doc 001'
|
'Doc 001'
|
||||||
>>> vD001 = IVersionable(d001)
|
>>> vD001 = IVersionable(d001)
|
||||||
>>> vD001.versionLevels
|
>>> vD001.versionLevels
|
||||||
['major', 'minor']
|
['major', 'minor']
|
||||||
|
@ -68,9 +66,9 @@ Now we can create a new version for our document:
|
||||||
|
|
||||||
>>> d001v1_2 = vD001.createVersion()
|
>>> d001v1_2 = vD001.createVersion()
|
||||||
>>> getName(d001v1_2)
|
>>> getName(d001v1_2)
|
||||||
u'd001_1.2.txt'
|
'd001_1.2.txt'
|
||||||
>>> d001v1_2.title
|
>>> d001v1_2.title
|
||||||
u'Doc 001'
|
'Doc 001'
|
||||||
|
|
||||||
>>> vD001v1_2 = IVersionable(d001v1_2)
|
>>> vD001v1_2 = IVersionable(d001v1_2)
|
||||||
>>> vD001v1_2.versionId
|
>>> vD001v1_2.versionId
|
||||||
|
@ -91,14 +89,14 @@ a major version change, the lower levels are reset to 1:
|
||||||
|
|
||||||
>>> d001v2_1 = vD001.createVersion(0)
|
>>> d001v2_1 = vD001.createVersion(0)
|
||||||
>>> getName(d001v2_1)
|
>>> getName(d001v2_1)
|
||||||
u'd001_2.1.txt'
|
'd001_2.1.txt'
|
||||||
|
|
||||||
The name of the new version is always derived from the name of the master
|
The name of the new version is always derived from the name of the master
|
||||||
even if we create a new version from another one:
|
even if we create a new version from another one:
|
||||||
|
|
||||||
>>> d001v2_2 = IVersionable(d001v1_2).createVersion()
|
>>> d001v2_2 = IVersionable(d001v1_2).createVersion()
|
||||||
>>> getName(d001v2_2)
|
>>> getName(d001v2_2)
|
||||||
u'd001_2.2.txt'
|
'd001_2.2.txt'
|
||||||
|
|
||||||
|
|
||||||
Providing the Correct Version
|
Providing the Correct Version
|
||||||
|
@ -151,7 +149,7 @@ derived from it are deleted as well.
|
||||||
|
|
||||||
>>> del resources['d001.txt']
|
>>> del resources['d001.txt']
|
||||||
>>> sorted(resources)
|
>>> sorted(resources)
|
||||||
[u'd002.txt', u'd003.txt']
|
['d002.txt', 'd003.txt']
|
||||||
|
|
||||||
|
|
||||||
Fin de partie
|
Fin de partie
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
"""
|
# loops.versioning.testsetup
|
||||||
Set up a loops site for testing.
|
|
||||||
|
|
||||||
$Id$
|
""" Set up a loops site for testing.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zope import component
|
from zope import component
|
||||||
from zope.annotation.attribute import AttributeAnnotations
|
from zope.annotation.attribute import AttributeAnnotations
|
||||||
from zope.annotation.interfaces import IAnnotatable
|
from zope.annotation.interfaces import IAnnotatable
|
||||||
from zope.app.catalog.catalog import Catalog
|
from zope.authentication.interfaces import IAuthentication
|
||||||
from zope.app.catalog.interfaces import ICatalog
|
from zope.catalog.catalog import Catalog
|
||||||
from zope.app.catalog.field import FieldIndex
|
from zope.catalog.interfaces import ICatalog
|
||||||
from zope.app.catalog.text import TextIndex
|
from zope.catalog.field import FieldIndex
|
||||||
from zope.app.container.interfaces import IObjectRemovedEvent
|
from zope.catalog.text import TextIndex
|
||||||
from zope.app.security.interfaces import IAuthentication
|
from zope.container.interfaces import IObjectRemovedEvent
|
||||||
from zope.app.security.principalregistry import principalRegistry
|
|
||||||
from zope.dublincore.annotatableadapter import ZDCAnnotatableAdapter
|
from zope.dublincore.annotatableadapter import ZDCAnnotatableAdapter
|
||||||
from zope.dublincore.interfaces import IZopeDublinCore
|
from zope.dublincore.interfaces import IZopeDublinCore
|
||||||
|
from zope.principalregistry.principalregistry import principalRegistry
|
||||||
|
|
||||||
|
from cybertools.meta.interfaces import IOptions
|
||||||
from cybertools.relation.tests import IntIdsStub
|
from cybertools.relation.tests import IntIdsStub
|
||||||
from cybertools.relation.registry import RelationRegistry
|
from cybertools.relation.registry import RelationRegistry
|
||||||
from cybertools.relation.interfaces import IRelationRegistry
|
from cybertools.relation.interfaces import IRelationRegistry
|
||||||
|
@ -56,7 +56,7 @@ class TestSite(object):
|
||||||
component.provideAdapter(ZDCAnnotatableAdapter, (ILoopsObject,), IZopeDublinCore)
|
component.provideAdapter(ZDCAnnotatableAdapter, (ILoopsObject,), IZopeDublinCore)
|
||||||
component.provideAdapter(AttributeAnnotations, (ILoopsObject,))
|
component.provideAdapter(AttributeAnnotations, (ILoopsObject,))
|
||||||
component.provideAdapter(LoopsDCAdapter, (IConcept,), IZopeDublinCore)
|
component.provideAdapter(LoopsDCAdapter, (IConcept,), IZopeDublinCore)
|
||||||
component.provideAdapter(LoopsOptions)
|
component.provideAdapter(LoopsOptions, provides=IOptions)
|
||||||
|
|
||||||
component.provideAdapter(ConceptType)
|
component.provideAdapter(ConceptType)
|
||||||
component.provideAdapter(ResourceType)
|
component.provideAdapter(ResourceType)
|
||||||
|
|
Loading…
Add table
Reference in a new issue