loops/agent/transport/base.py
helmutm 57a5f126b5 upload of resources from loops.agent via HTTP PUT basically working
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1955 fd906abe-77d9-0310-91a1-e0d9ade77398
2007-08-23 16:27:03 +00:00

135 lines
4.2 KiB
Python

#
# Copyright (c) 2007 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
#
"""
Transporter base classes.
$Id$
"""
from base64 import b64encode
from twisted.internet import reactor
from twisted.internet.defer import Deferred, fail
from twisted.web.client import getPage
from zope.interface import implements
from loops.agent.interfaces import ITransporter, ITransportJob
from loops.agent.schedule import Job
class TransportJob(Job):
implements(ITransportJob)
def __init__(self, transporter):
super(TransportJob, self).__init__()
self.transporter = transporter
self.resources = []
self.deferred = None
def execute(self):
result = self.params.get('result')
if result is None:
return fail('No data available.')
self.resources = result
self.deferred = Deferred()
d = self.transporter.transfer(self.resources.pop())
d.addCallback(self.transferDone).addErrback(self.logError)
return self.deferred
def transferDone(self, result):
self.logTransfer(result)
if self.resources:
d = self.transporter.transfer(self.resources.pop())
d.addCallback(self.transferDone).addErrback(self.logError)
else:
self.deferred.callback('OK')
def logTransfer(self, result, err=None):
#print 'transfer successful; remaining:', len(self.resources)
# TODO: logging
# self.transporter.agent.logger.log(...)
pass
def logError(self, error):
print '*** error on transfer', self.transporter.serverURL, error
self.deferred.errback(error)
class Transporter(object):
implements(ITransporter)
jobFactory = TransportJob
serverURL = 'http://localhost:8080'
method = 'PUT'
machineName = 'unknown'
userName = 'nobody'
password = 'secret'
def __init__(self, agent, **params):
self.agent = agent
for k, v in params.items():
setattr(self, k ,v)
self.deferred = None
def createJob(self):
return self.jobFactory(self)
def transfer(self, resource):
data = resource.data
if type(data) is file:
text = data.read()
data.close()
else:
text = data
path = resource.path
app = resource.application
metadata = resource.metadata
auth = b64encode(self.userName + ':' + self.password)
headers = {'Authorization': 'Basic ' + auth}
url = self.makePath('.data', app, path)
d = getPage(url, method=self.method, headers=headers, postdata=text)
if metadata is None:
d.addCallback(self.finished)
else:
d.addCallback(self.transferMeta, app, path, headers, metadata.asXML())
self.deferred = Deferred()
return self.deferred
def transferMeta(self, result, app, path, headers, text):
url = self.makePath('.meta', app, path)
d = getPage(url, method=self.method, headers=headers, postdata=text)
d.addCallback(self.finished)
def finished(self, result):
self.deferred.callback(result)
def makePath(self, infoType, app, path, extension=None):
if path.startswith('/'):
path = path[1:]
url = self.serverURL
if url.endswith('/'):
url = url[:-1]
fullPath = '/'.join((url, infoType,
self.machineName, self.userName, app, path))
if extension:
fullPath += '.' + extension
return fullPath