diff --git a/external/README.txt b/external/README.txt
index 78bc117..5d62d92 100644
--- a/external/README.txt
+++ b/external/README.txt
@@ -17,7 +17,7 @@ Let's set up a loops site with basic and example concepts and resources.
>>> concepts, resources, views = t.setup()
>>> loopsRoot = site['loops']
>>> len(concepts), len(resources), len(views)
- (30, 3, 0)
+ (30, 3, 1)
Importing loops Objects
@@ -44,7 +44,7 @@ Creating the corresponding objects
>>> loader = Loader(loopsRoot)
>>> loader.load(elements)
>>> len(concepts), len(resources), len(views)
- (31, 3, 0)
+ (31, 3, 1)
>>> from loops.common import adapted
>>> adMyquery = adapted(concepts['myquery'])
@@ -138,7 +138,7 @@ Writing object information to the external storage
child(u'projects', u'customer', u'standard')...
resource(u'doc04.txt', u'Document 4', u'textdocument', contentType='text/restructured')...
resourceRelation(u'myquery', u'doc04.txt', u'standard')
- node('home', u'Home', '', u'menu', body=u'Welcome')
+ node('home', u'Home', '', u'menu')
node('myquery', u'My Query', 'home', u'page', target=u'concepts/myquery')...
Writing sub-elements
diff --git a/layout/base.py b/layout/base.py
index 162a212..0e36c85 100644
--- a/layout/base.py
+++ b/layout/base.py
@@ -66,7 +66,6 @@ class NodeLayoutInstance(LayoutInstance):
li = ILayoutInstance(n)
li.template = layout
result.append(li)
- # if not result: get layouts from parent node(s)
return result
@Lazy
diff --git a/organize/personal/README.txt b/organize/personal/README.txt
index b50b551..56af6f5 100644
--- a/organize/personal/README.txt
+++ b/organize/personal/README.txt
@@ -83,8 +83,7 @@ So we are now ready to query the favorites.
User interface
--------------
- >>> from loops.view import Node
- >>> home = views['home'] = Node()
+ >>> home = views['home']
>>> from loops.tests.auth import TestRequest
>>> from loops.organize.personal.browser.configurator import PortletConfigurator
diff --git a/organize/tracking/README.txt b/organize/tracking/README.txt
index 1b08688..4694982 100644
--- a/organize/tracking/README.txt
+++ b/organize/tracking/README.txt
@@ -74,10 +74,47 @@ Recording assignment changes
Tracking Object Access
======================
- >>> from loops.organize.tracking.access import record
+Access records are not directly stored in the ZODB (in order to avoid
+conflict errors) but first stored to a log file.
+
+ >>> from loops.organize.tracking.access import logfile_option, record, logAccess
+ >>> from loops.organize.tracking.access import AccessRecordManager
+ >>> from loops.organize.tracking.tests import testDir
+ >>> from loops.browser.node import NodeView
+ >>> from loops.browser.resource import ResourceView
+ >>> from loops import util
+ >>> from zope.app.publication.interfaces import EndRequestEvent
+ >>> from zope.publisher.browser import TestRequest
+
+ >>> loopsRoot.options = [logfile_option + ':test.log']
+
+ >>> request = TestRequest()
+ >>> home = views['home']
+ >>> record(request, principal='users.john', view='render',
+ ... node=util.getUidForObject(home),
+ ... target=util.getUidForObject(resources['d001.txt']),
+ ... )
+ >>> record(request, principal='users.john', view='render',
+ ... node=util.getUidForObject(home),
+ ... target=util.getUidForObject(resources['d002.txt']),
+ ... )
+
+ >>> logAccess(EndRequestEvent(NodeView(home, request), request), testDir)
+
+They can then be read in via an AccessRecordManager object, i.e. a view
+that may be called via ``wget`` using a crontab entry or some other kind
+of job control.
+
+ >>> rm = AccessRecordManager(loopsRoot, TestRequest())
+ >>> rm.baseDir = testDir
+ >>> rm.loadRecordsFromLog()
Fin de partie
=============
+ >>> import os
+ >>> for fn in os.listdir(testDir):
+ ... if '.log' in fn:
+ ... os.unlink(os.path.join(testDir, fn))
>>> placefulTearDown()
diff --git a/organize/tracking/access.py b/organize/tracking/access.py
index 38f926b..c4955ef 100644
--- a/organize/tracking/access.py
+++ b/organize/tracking/access.py
@@ -59,7 +59,7 @@ def record(request, **kw):
@adapter(IEndRequestEvent)
-def logAccess(event):
+def logAccess(event, baseDir=None):
object = removeSecurityProxy(event.object)
context = getattr(object, 'context', None)
if context is None:
@@ -79,7 +79,7 @@ def logAccess(event):
fn = logfileOption[0]
logger = loggers.get(fn)
if not logger:
- path = os.path.join(util.getVarDirectory(), fn)
+ path = os.path.join(baseDir or util.getVarDirectory(), fn)
logger = loggers[fn] = Logger(fn, path)
logger.log(marshall(data))
@@ -101,6 +101,7 @@ class AccessRecordManager(BaseRecordManager):
def __init__(self, context, request):
self.context = context
self.request = request
+ self.baseDir = util.getVarDirectory()
@Lazy
def logfile(self):
@@ -115,7 +116,7 @@ class AccessRecordManager(BaseRecordManager):
if not self.valid:
return
fn = self.logfile
- path = os.path.join(util.getVarDirectory(), fn)
+ path = os.path.join(self.baseDir, fn)
logger = loggers.get(fn)
if not logger:
logger = loggers[fn] = Logger(fn, path)
diff --git a/organize/tracking/browser.py b/organize/tracking/browser.py
index b269d79..94d5f03 100644
--- a/organize/tracking/browser.py
+++ b/organize/tracking/browser.py
@@ -39,7 +39,10 @@ class ChangeView(TrackView):
@Lazy
def taskTitle(self):
- return getattr(self.task, 'title', getName(self.task))
+ task = self.task
+ if task is None:
+ return self.metadata['taskId']
+ return getattr(task, 'title', getName(task))
@Lazy
def taskUrl(self):
@@ -67,3 +70,8 @@ class ChangeView(TrackView):
user = self.user
if user is not None and not isinstance(user, basestring):
return '%s/@@introspector.html' % absoluteURL(user, self.request)
+
+
+class AccessView(ChangeView):
+
+ pass
diff --git a/organize/tracking/configure.zcml b/organize/tracking/configure.zcml
index 567501c..d465d4a 100644
--- a/organize/tracking/configure.zcml
+++ b/organize/tracking/configure.zcml
@@ -7,11 +7,27 @@
+ interface="loops.organize.tracking.change.IChangeRecord" />
+ set_schema="loops.organize.tracking.change.IChangeRecord" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+