extend base.Transporter class to full-blown HTTP transporter, thus eliminating the httpput module
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1901 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
f0676ad208
commit
f4449162a1
8 changed files with 64 additions and 112 deletions
|
@ -73,6 +73,8 @@ class FileResource(object):
|
||||||
self.path = path
|
self.path = path
|
||||||
self.metadata = metadata
|
self.metadata = metadata
|
||||||
|
|
||||||
|
application = 'filesystem'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def data(self):
|
def data(self):
|
||||||
return open(self.path, 'r')
|
return open(self.path, 'r')
|
||||||
|
|
|
@ -27,7 +27,7 @@ transferred.
|
||||||
|
|
||||||
>>> from loops.agent.testing import transport
|
>>> from loops.agent.testing import transport
|
||||||
>>> transporter = transport.Transporter(agent)
|
>>> transporter = transport.Transporter(agent)
|
||||||
>>> transportJob = transporter.jobFactory(transporter)
|
>>> transportJob = transporter.createJob()
|
||||||
>>> crawlJob.successors.append(transportJob)
|
>>> crawlJob.successors.append(transportJob)
|
||||||
|
|
||||||
We are now ready to schedule the job and let the reactor execute it.
|
We are now ready to schedule the job and let the reactor execute it.
|
||||||
|
|
|
@ -30,7 +30,9 @@ class IAgent(Interface):
|
||||||
and transfers these to its server.
|
and transfers these to its server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
scheduler = Attribute('IScheduler instance')
|
scheduler = Attribute('IScheduler instance.')
|
||||||
|
transporter = Attribute('The transporter to be used for transferring '
|
||||||
|
'objects.')
|
||||||
|
|
||||||
|
|
||||||
class IScheduler(Interface):
|
class IScheduler(Interface):
|
||||||
|
@ -111,13 +113,17 @@ class IResource(Interface):
|
||||||
|
|
||||||
data = Attribute("A string, file, or similar representation of the "
|
data = Attribute("A string, file, or similar representation of the "
|
||||||
"resource's content")
|
"resource's content")
|
||||||
|
path = Attribute('A filesystem path or some other information '
|
||||||
|
'uniquely identifying the resource on the client '
|
||||||
|
'machine for the current user.')
|
||||||
|
application = Attribute('The name of the application that provided '
|
||||||
|
'the resource.')
|
||||||
metadata = Attribute('Information describing this resource; '
|
metadata = Attribute('Information describing this resource; '
|
||||||
'should be an IMetadataSet object.')
|
'should be an IMetadataSet object.')
|
||||||
|
|
||||||
|
|
||||||
class IMetadataSet(Interface):
|
class IMetadataSet(Interface):
|
||||||
""" Metadata associated with a resource; sort of a mapping.
|
""" Metadata associated with a resource; a mapping.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def asXML():
|
def asXML():
|
||||||
|
@ -148,9 +154,13 @@ class ITransporter(Interface):
|
||||||
userName = Attribute('User name for logging in to the server.')
|
userName = Attribute('User name for logging in to the server.')
|
||||||
password = Attribute('Password for logging in to the server.')
|
password = Attribute('Password for logging in to the server.')
|
||||||
|
|
||||||
|
def createJob():
|
||||||
|
""" Return a transport job for this transporter.
|
||||||
|
"""
|
||||||
|
|
||||||
def transfer(resource):
|
def transfer(resource):
|
||||||
""" Transfer the resource (an object providing IResource)
|
""" Transfer the resource (an object providing IResource)
|
||||||
to the server.
|
to the server and return a Deferred.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -185,6 +195,8 @@ class IConfigurator(Interface):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# future extensions
|
||||||
|
|
||||||
class IPackageManager(Interface):
|
class IPackageManager(Interface):
|
||||||
""" Allows to install, update, or remove software packages (plugins,
|
""" Allows to install, update, or remove software packages (plugins,
|
||||||
typically as Python eggs) from a server.
|
typically as Python eggs) from a server.
|
||||||
|
|
|
@ -26,7 +26,7 @@ from twisted.internet import reactor
|
||||||
from twisted.internet.defer import Deferred
|
from twisted.internet.defer import Deferred
|
||||||
from zope.interface import implements
|
from zope.interface import implements
|
||||||
|
|
||||||
from loops.agent.interfaces import ICrawlingJob, IResource
|
from loops.agent.interfaces import IResource
|
||||||
from loops.agent.crawl.base import CrawlingJob as BaseCrawlingJob
|
from loops.agent.crawl.base import CrawlingJob as BaseCrawlingJob
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,4 +47,6 @@ class DummyResource(object):
|
||||||
implements(IResource)
|
implements(IResource)
|
||||||
|
|
||||||
data = 'Dummy resource data for testing purposes.'
|
data = 'Dummy resource data for testing purposes.'
|
||||||
|
path = '/dummy/data'
|
||||||
|
application = 'dummy'
|
||||||
metadata = None
|
metadata = None
|
||||||
|
|
|
@ -27,28 +27,11 @@ from twisted.internet.defer import Deferred
|
||||||
from zope.interface import implements
|
from zope.interface import implements
|
||||||
|
|
||||||
from loops.agent.interfaces import ITransportJob, ITransporter
|
from loops.agent.interfaces import ITransportJob, ITransporter
|
||||||
from loops.agent.schedule import Job
|
|
||||||
from loops.agent.transport.base import TransportJob as BaseJob
|
|
||||||
from loops.agent.transport.base import Transporter as BaseTransporter
|
from loops.agent.transport.base import Transporter as BaseTransporter
|
||||||
|
|
||||||
|
|
||||||
class TransportJob(BaseJob):
|
|
||||||
|
|
||||||
def execute(self):
|
|
||||||
kw = self.params
|
|
||||||
result = kw.get('result')
|
|
||||||
if result is None:
|
|
||||||
print 'No data available.'
|
|
||||||
else:
|
|
||||||
for resource in result:
|
|
||||||
d = self.transporter.transfer(resource)
|
|
||||||
return Deferred()
|
|
||||||
|
|
||||||
|
|
||||||
class Transporter(BaseTransporter):
|
class Transporter(BaseTransporter):
|
||||||
|
|
||||||
jobFactory = TransportJob
|
|
||||||
|
|
||||||
def transfer(self, resource):
|
def transfer(self, resource):
|
||||||
data = resource.data
|
data = resource.data
|
||||||
if type(data) is file:
|
if type(data) is file:
|
||||||
|
|
|
@ -23,7 +23,7 @@ $Id$
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from twisted.internet.defer import Deferred
|
from twisted.internet.defer import Deferred, DeferredList, fail
|
||||||
from zope.interface import implements
|
from zope.interface import implements
|
||||||
|
|
||||||
from loops.agent.interfaces import ITransporter, ITransportJob
|
from loops.agent.interfaces import ITransporter, ITransportJob
|
||||||
|
@ -38,6 +38,22 @@ class TransportJob(Job):
|
||||||
super(TransportJob, self).__init__()
|
super(TransportJob, self).__init__()
|
||||||
self.transporter = transporter
|
self.transporter = transporter
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
result = self.params.get('result')
|
||||||
|
if result is None:
|
||||||
|
return fail('No data available.')
|
||||||
|
transfers = []
|
||||||
|
for resource in result:
|
||||||
|
d = self.transporter.transfer(resource)
|
||||||
|
transfers.append(d)
|
||||||
|
d.addCallback(self.logTransfer)
|
||||||
|
return DeferredList(transfers)
|
||||||
|
|
||||||
|
def logTransfer(self, result):
|
||||||
|
# TODO: logging
|
||||||
|
# self.transporter.agent.logger.log(...)
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Transporter(object):
|
class Transporter(object):
|
||||||
|
|
||||||
|
@ -45,21 +61,37 @@ class Transporter(object):
|
||||||
|
|
||||||
jobFactory = TransportJob
|
jobFactory = TransportJob
|
||||||
|
|
||||||
|
serverURL = None
|
||||||
|
method = None
|
||||||
|
machineName = None
|
||||||
|
userName = None
|
||||||
|
password = None
|
||||||
|
|
||||||
def __init__(self, agent):
|
def __init__(self, agent):
|
||||||
self.agent = agent
|
self.agent = agent
|
||||||
|
|
||||||
|
def createJob(self):
|
||||||
|
return self.jobFactory(self)
|
||||||
|
|
||||||
def transfer(self, resource):
|
def transfer(self, resource):
|
||||||
""" Should be overridden by subclass - this is just an example
|
|
||||||
how it may look like.
|
|
||||||
"""
|
|
||||||
data = resource.data
|
data = resource.data
|
||||||
if type(data) is file:
|
if type(data) is file:
|
||||||
text = data.read()
|
text = resource.read()
|
||||||
data.close()
|
resource.close()
|
||||||
else:
|
else:
|
||||||
text = data
|
text = data
|
||||||
|
path = resource.path
|
||||||
|
app = resource.application
|
||||||
|
deferreds = []
|
||||||
metadata = resource.metadata
|
metadata = resource.metadata
|
||||||
d = Deferred() # or call something that returns a deferred
|
if metadata is not None:
|
||||||
return d
|
url = self.makePath('meta', app, path)
|
||||||
|
deferreds.append(
|
||||||
|
getPage(url, method=self.method, postData=metadata.asXML()))
|
||||||
|
url = self.makePath('data', app, path)
|
||||||
|
deferreds.append(getPage(url, method=self.method, postData=text))
|
||||||
|
return DeferredList(deferreds)
|
||||||
|
|
||||||
|
def makePath(self, infoType, app, path):
|
||||||
|
return '/'.join((self.serverURL, infoType, app, path))
|
||||||
|
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
#
|
|
||||||
# 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
|
|
||||||
#
|
|
||||||
|
|
||||||
"""
|
|
||||||
Transferring of data/files to the server.
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
"""
|
|
||||||
|
|
||||||
from twisted.internet import reactor
|
|
||||||
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
|
|
||||||
|
|
||||||
def execute(self):
|
|
||||||
result = kw.get('result')
|
|
||||||
if result is None:
|
|
||||||
print 'No data available.'
|
|
||||||
else:
|
|
||||||
for resource, metadata in result:
|
|
||||||
d = self.transporter.transfer(resource.data, metadata)
|
|
||||||
return Deferred()
|
|
||||||
|
|
||||||
|
|
||||||
class Transporter(object):
|
|
||||||
|
|
||||||
implements(ITransporter)
|
|
||||||
|
|
||||||
jobFactory = TransportJob
|
|
||||||
|
|
||||||
serverURL = None
|
|
||||||
method = None
|
|
||||||
machineName = None
|
|
||||||
userName = None
|
|
||||||
password = None
|
|
||||||
|
|
||||||
def __init__(self, agent):
|
|
||||||
self.agent = agent
|
|
||||||
conf = agent.config
|
|
||||||
# TODO: get settings from conf
|
|
||||||
|
|
||||||
def transfer(self, resource):
|
|
||||||
data = resource.data
|
|
||||||
if type(data) is file:
|
|
||||||
text = resource.read()
|
|
||||||
resource.close()
|
|
||||||
else:
|
|
||||||
text = data
|
|
||||||
metadata = resource.metadata
|
|
||||||
url = self.serverURL + self.makePath(metadata)
|
|
||||||
d = getPage(url, method='PUT', postData=text)
|
|
||||||
return d
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ loops.agent.transport.httpput - The HTTP PUT Transport
|
||||||
>>> from time import time
|
>>> from time import time
|
||||||
|
|
||||||
>>> from loops.agent.core import Agent
|
>>> from loops.agent.core import Agent
|
||||||
>>> from loops.agent.transport.httpput import Transporter, TransportJob
|
>>> from loops.agent.transport.base import Transporter
|
||||||
|
|
||||||
>>> agent = Agent()
|
>>> agent = Agent()
|
||||||
>>> transporter = Transporter(agent)
|
>>> transporter = Transporter(agent)
|
||||||
>>> job = TransportJob(transporter)
|
>>> job = transporter.createJob()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue