work in progress: loops site synchronization: export (and subsequent import) of changes

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3729 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2010-02-14 09:51:49 +00:00
parent d0d53d6eb2
commit eddf4287ec
14 changed files with 268 additions and 9 deletions

3
external/base.py vendored
View file

@ -194,9 +194,6 @@ class Extractor(Base):
element = self.getDeassignmentElement(obj, child, pred)
if element is not None:
yield element
# TODO: include new parent and child relations
# TODO: include statements for removal of relations if necessary
# (or remove relations not in import file upon import)
# TODO: include children and resources if corresponding flags are set.
def extractForParents(self, parents, predicates=None,

View file

@ -37,4 +37,4 @@ class JobManager(object):
self.context = context
def process(self):
raise NotImplementedError("Method 'process' has to be implementd by subclass.")
raise NotImplementedError("Method 'process' has to be implemented by subclass.")

View file

@ -42,6 +42,9 @@ In addition to the application site we need a loops system management site.
[u'domain', u'file', u'hasType', u'job', u'note', u'predicate',
u'standard', u'textdocument', u'type']
>>> list(systemRoot.getRecordManager().keys())
[u'jobs']
Agents and Jobs
===============

42
system/browser.py Normal file
View file

@ -0,0 +1,42 @@
#
# Copyright (c) 2010 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
#
"""
Views for loops system management.
$Id$
"""
from cybertools.tracking.btree import TrackingStorage
from loops.system.job import JobRecord
class SetupActions(object):
""" Collection of methods for manually setting up system objects
within a loops site.
"""
def __init__(self, context, request):
self.context = context
self.request = request
def setupJobRecords(self):
records = self.context.getRecordManager()
if 'jobs' not in records:
records['jobs'] = TrackingStorage(trackFactory=JobRecord)
return 'Done'

View file

@ -3,11 +3,19 @@
<configure
xmlns:zope="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
i18n_domain="zope">
i18n_domain="loops">
<zope:adapter factory="loops.system.setup.SetupManager"
name="system" />
<!--<zope:adapter factory="loops.system.setup.SetupManager"
name="system" />-->
<browser:page
name="setup_jobrecords.html"
for="loops.interfaces.ILoops"
class="loops.system.browser.SetupActions"
attribute="setupJobRecords"
permission="loops.ManageSite" />
<include package=".site" />
<include package=".sync" />
</configure>

View file

@ -25,10 +25,23 @@ $Id$
from zope.interface import Interface, Attribute
from zope import interface, component, schema
from cybertools.tracking.interfaces import ITrack
from loops.interfaces import IConceptSchema
from loops.util import _
class IJobRecords(Interface):
pass
class IJobRecord(ITrack):
pass
# agent-based job control - not used at the moment.
class IJob(IConceptSchema):
""" Specifies/represents a job to be executed by a cybertools.agent
instance.
@ -43,7 +56,8 @@ class IJob(IConceptSchema):
title=_(u'Agent Identifier'),
description=_(u'The identifier of the agent that will '
'execute the job; this identifies also the type '
'of job, e.g. a crawling or transport job.')
'of job, e.g. a crawling or transport job.'),
required=False,)
startTime = schema.Date(
title=_(u'Start Date/Time'),
description=_(u'Date/time at which the job should be '
@ -63,3 +77,4 @@ class IJobManager(IConceptSchema):
""" A container/manager for jobs to be executed by a cybertools.agent
instance.
"""

51
system/job.py Normal file
View file

@ -0,0 +1,51 @@
#
# Copyright (c) 2010 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
#
"""
Recording changes to loops objects.
$Id$
"""
from zope.interface import implements
from zope.cachedescriptors.property import Lazy
from zope.component import adapter
from cybertools.meta.interfaces import IOptions
from cybertools.tracking.btree import Track, getTimeStamp
from loops.organize.tracking.base import BaseRecordManager
from loops.system.interfaces import IJobRecord, IJobRecords
from loops import util
class JobRecords(BaseRecordManager):
implements(IJobRecords)
storageName = 'jobs'
def __init__(self, context):
self.context = context
class JobRecord(Track):
implements(IJobRecord)
typeName = 'JobRecord'

View file

@ -1,5 +1,5 @@
#
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
# Copyright (c) 2010 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
@ -25,9 +25,11 @@ $Id$
from zope.component import adapts
from zope.interface import implements, Interface
from cybertools.tracking.btree import TrackingStorage
from loops.concept import Concept
from loops.interfaces import ITypeConcept
from loops.setup import SetupManager as BaseSetupManager
from loops.system.job import JobRecord
class SetupManager(BaseSetupManager):
@ -39,4 +41,8 @@ class SetupManager(BaseSetupManager):
# type concepts:
job = self.addAndConfigureObject(concepts, Concept, 'job', title=u'Job',
conceptType=type)
# job records:
records = self.context.getRecordManager()
if 'jobs' not in records:
records['jobs'] = TrackingStorage(trackFactory=JobRecord)

32
system/sync/README.txt Normal file
View file

@ -0,0 +1,32 @@
===============================================================
loops - Linked Objects for Organization and Processing Services
===============================================================
($Id$)
>>> from zope import component
>>> from zope.traversing.api import getName
Let's set up a loops site with basic and example concepts and resources.
>>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
>>> site = placefulSetUp(True)
>>> from loops.expert.testsetup import TestSite
>>> t = TestSite(site)
>>> concepts, resources, views = t.setup()
>>> loopsRoot = site['loops']
>>> len(concepts), len(resources), len(views)
(30, 3, 1)
Synchronize: Transfer Changes from one loops Site to Another
============================================================
>>> from loops.system.sync.browser import SyncChanges
Fin de Partie
=============
>>> placefulTearDown()

3
system/sync/__init__.py Normal file
View file

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

49
system/sync/browser.py Normal file
View file

@ -0,0 +1,49 @@
#
# Copyright (c) 2010 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) for import/export.
$Id$
"""
from cStringIO import StringIO
import os
import time
from zope import component
from zope.interface import Interface, implements
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from zope.traversing.api import getName, getPath
from loops.organize.tracking.report import RecentChanges
from loops import util
control_macros = ViewPageTemplateFile('control.pt')
class SyncChanges(RecentChanges):
""" View for controlling the transfer of changes from a loops site
to another one.
"""
@Lazy
def macro(self):
return control_macros.macros['main']

View file

@ -0,0 +1,16 @@
<!-- $Id$ -->
<configure
xmlns:zope="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
i18n_domain="loops">
<!-- views -->
<browser:page
name="sync_changes.html"
for="loops.interfaces.IConcept"
class="loops.system.sync.browser.SyncChanges"
permission="zope.ManageContent" />
</configure>

10
system/sync/control.pt Normal file
View file

@ -0,0 +1,10 @@
<!-- $Id$ -->
<metal:main define-macro="main"
tal:define="info item/getData">
<metal:title use-macro="item/conceptMacros/concepttitle" />
<br />
<metal:listing use-macro="info/macro" />
<input type="submit" value="Synchronize Changes" />
</metal:main>

27
system/sync/tests.py Executable file
View file

@ -0,0 +1,27 @@
# $Id$
import unittest, doctest
import os
from zope.testing.doctestunit import DocFileSuite
from zope.interface.verify import verifyClass
dataDirectory = os.path.join(os.path.dirname(__file__), 'testdata')
class Test(unittest.TestCase):
"Basic tests for the loops.system.sync package."
def testSomething(self):
pass
def test_suite():
flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
return unittest.TestSuite((
unittest.makeSuite(Test),
DocFileSuite('README.txt', optionflags=flags),
))
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')