
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3734 fd906abe-77d9-0310-91a1-e0d9ade77398
166 lines
4.8 KiB
Python
166 lines
4.8 KiB
Python
#
|
|
# 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
|
|
from logging import getLogger
|
|
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 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
|
|
from loops.system.job import JobRecords
|
|
from loops import util
|
|
|
|
|
|
control_macros = ViewPageTemplateFile('control.pt')
|
|
|
|
|
|
class SyncChanges(ConceptView):
|
|
""" View for controlling the transfer of changes from a loops site
|
|
to another one.
|
|
"""
|
|
|
|
@Lazy
|
|
def macro(self):
|
|
return control_macros.macros['main']
|
|
|
|
@Lazy
|
|
def changed(self):
|
|
return (self.request.get('changed_since') or
|
|
formatTimeStamp(self.lastSyncTimeStamp))
|
|
|
|
@Lazy
|
|
def lastSyncTime(self):
|
|
if self.lastSyncTimeStamp is None:
|
|
return u'-'
|
|
return formatTimeStamp(self.lastSyncTimeStamp)
|
|
|
|
@Lazy
|
|
def lastSyncTimeStamp(self):
|
|
jobs = JobRecords(self.view.loopsRoot)
|
|
rec = jobs.getLastRecordFor(self.nodeView.virtualTargetObject)
|
|
if rec is not None:
|
|
return rec.timeStamp
|
|
return None
|
|
|
|
|
|
class ChangesSave(FormController):
|
|
|
|
@Lazy
|
|
def baseDirectory(self):
|
|
return util.getVarDirectory(self.request)
|
|
|
|
@Lazy
|
|
def sitePath(self):
|
|
return getPath(self.view.loopsRoot)[1:].replace('/', '_')
|
|
|
|
@Lazy
|
|
def exportDirectory(self):
|
|
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
|
|
|
|
@Lazy
|
|
def types(self):
|
|
typeIds = self.targetView.options('types')
|
|
return [self.view.conceptManager[t] for t in typeIds]
|
|
|
|
@Lazy
|
|
def changed(self):
|
|
since = self.request.get('changed_since')
|
|
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(self.changed, self.types)
|
|
writer = component.getUtility(IWriter)
|
|
f = open(os.path.join(self.exportDirectory, '_changes.dmp'), 'w')
|
|
writer.write(elements, f)
|
|
f.close()
|
|
|
|
def clearExportDirectory(self):
|
|
for fn in os.listdir(self.exportDirectory):
|
|
os.unlink(os.path.join(self.exportDirectory, fn))
|
|
|
|
|
|
class ChangesSync(ChangesSave):
|
|
|
|
state = 'ok'
|
|
|
|
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 = JobRecords(self.view.loopsRoot)
|
|
jobs.recordExecution(self.view.virtualTargetObject,
|
|
self.state, self.transcript.getvalue())
|
|
|
|
|
|
class SyncImport(BaseView):
|
|
|
|
def importData(self):
|
|
pass
|