From ab4c01e88d31cc1ecb74b1be1f4e908c376d9795 Mon Sep 17 00:00:00 2001 From: helmutm Date: Mon, 15 Feb 2010 21:41:53 +0000 Subject: [PATCH] work in progress: loops site synchronization: transfer data to target system git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3732 fd906abe-77d9-0310-91a1-e0d9ade77398 --- external/base.py | 4 ++- system/sync/README.txt | 10 +++++- system/sync/browser.py | 71 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/external/base.py b/external/base.py index 1b86c29..9d920a1 100644 --- a/external/base.py +++ b/external/base.py @@ -184,8 +184,10 @@ class Extractor(Base): name = getName(obj) yield self.getConceptOrResourceElement(name, obj) elif action in ('assign', 'deassign'): - child = util.getObjectForUid(tr.data['second']) pred = util.getObjectForUid(tr.data['predicate']) + if pred == self.typePredicate: + continue + child = util.getObjectForUid(tr.data['second']) if child is None or pred is None: # may have been deleted already - can be ignored continue diff --git a/system/sync/README.txt b/system/sync/README.txt index e237ea8..640eef9 100644 --- a/system/sync/README.txt +++ b/system/sync/README.txt @@ -6,6 +6,7 @@ loops - Linked Objects for Organization and Processing Services >>> from zope import component >>> from zope.traversing.api import getName + >>> from zope.publisher.browser import TestRequest Let's set up a loops site with basic and example concepts and resources. @@ -19,11 +20,18 @@ Let's set up a loops site with basic and example concepts and resources. >>> len(concepts), len(resources), len(views) (30, 3, 1) + >>> from cybertools.tracking.btree import TrackingStorage + >>> from loops.system.job import JobRecord + >>> records = loopsRoot.getRecordManager() + >>> records['jobs'] = TrackingStorage(trackFactory=JobRecord) + Synchronize: Transfer Changes from one loops Site to Another ============================================================ - >>> from loops.system.sync.browser import SyncChanges + >>> from loops.system.sync.browser import SyncChanges, ChangesSync + >>> req = TestRequest() + >>> #view = SyncChanges() Fin de Partie diff --git a/system/sync/browser.py b/system/sync/browser.py index 97353fd..8f61d5e 100644 --- a/system/sync/browser.py +++ b/system/sync/browser.py @@ -22,6 +22,8 @@ view class(es) for import/export. $Id$ """ +from cStringIO import StringIO +from logging import getLogger import os import time from zope import component @@ -32,6 +34,7 @@ from zope.traversing.api import getName, getPath from cybertools.browser.form import FormController from cybertools.util.date import str2timeStamp, formatTimeStamp +from loops.browser.common import BaseView from loops.browser.concept import ConceptView from loops.external.base import Extractor from loops.external.interfaces import IWriter @@ -74,30 +77,82 @@ class ChangesSave(FormController): @Lazy def sitePath(self): - return getPath(self.view.virtualTargetObject)[1:].replace('/', '_') + return getPath(self.view.loopsRoot)[1:].replace('/', '_') @Lazy def exportDirectory(self): - return os.path.join(self.baseDirectory, 'export', self.sitePath) + directory = os.path.join(self.baseDirectory, 'export', + '_'.join((self.sitePath, + getName(self.targetView.context)))) + if not os.path.exists(directory): + os.makedirs(directory) + return directory @Lazy def targetView(self): return self.view.virtualTarget - def update(self): + @Lazy + def types(self): typeIds = self.targetView.options('types') - types = [self.view.conceptManager[t] for t in typeIds] + return [self.view.conceptManager[t] for t in typeIds] + + @Lazy + def changed(self): since = self.request.get('changed_since') - changed = since and str2timeStamp(since) or self.targetView.lastSyncTimeStamp + return since and str2timeStamp(since) or self.targetView.lastSyncTimeStamp + + @Lazy + def transcript(self): + return StringIO() + + def update(self): + self.export() + return True + + def export(self): + self.clearExportDirectory() extractor = Extractor(self.view.loopsRoot, self.exportDirectory) - elements = extractor.extractChanges(changed, types) + elements = extractor.extractChanges(self.changed, self.types) writer = component.getUtility(IWriter) f = open(os.path.join(self.exportDirectory, '_changes.dmp'), 'w') writer.write(elements, f) f.close() - return True + + def clearExportDirectory(self): + for fn in os.listdir(self.exportDirectory): + os.unlink(os.path.join(self.exportDirectory, fn)) class ChangesSync(ChangesSave): - pass + def update(self): + self.export() + self.transfer() + self.triggerImport() + #self.recordExecution() + return True + + def transfer(self): + targetPath = self.targetView.options('target')[0] + cmd = os.popen('scp -r %s %s' % (self.exportDirectory, targetPath)) + info = cmd.read() + result = cmd.close() + if result: + message = '*** scp output: %s, return code: %s' % (info, result) + log = getLogger('loops.system.sync') + log.warn(message) + self.transcript.write(message + '\n') + + def triggerImport(self): + pass + + def recordExecution(self): + jobs = self.view.loopsRoot.getRecordManager()['jobs'] + jobs.saveUserTrack() + + +class SyncImport(BaseView): + + def importData(self): + pass