make new vdrive work, implement convenience wrapper, passes all tests

This commit is contained in:
Brian Warner 2007-06-15 00:37:32 -07:00
parent 5e5347a1bc
commit 82c38d370a
7 changed files with 212 additions and 126 deletions

View File

@ -13,7 +13,7 @@ from allmydata.Crypto.Util.number import bytes_to_long
from allmydata.storageserver import StorageServer from allmydata.storageserver import StorageServer
from allmydata.upload import Uploader from allmydata.upload import Uploader
from allmydata.download import Downloader from allmydata.download import Downloader
#from allmydata.vdrive import VDrive from allmydata.vdrive import DirectoryNode
from allmydata.webish import WebishServer from allmydata.webish import WebishServer
from allmydata.control import ControlServer from allmydata.control import ControlServer
from allmydata.introducer import IntroducerClient from allmydata.introducer import IntroducerClient
@ -113,18 +113,15 @@ class Client(node.Node, Referenceable):
def _got_vdrive(self, vdrive_server): def _got_vdrive(self, vdrive_server):
# vdrive_server implements RIVirtualDriveServer # vdrive_server implements RIVirtualDriveServer
self.log("connected to vdrive server") self.log("connected to vdrive server")
d = vdrive_server.callRemote("get_public_root") d = vdrive_server.callRemote("get_public_root_furl")
d.addCallback(self._got_vdrive_root, vdrive_server) d.addCallback(self._got_vdrive_root_furl, vdrive_server)
def _got_vdrive_root(self, vdrive_root, vdrive_server): def _got_vdrive_root_furl(self, vdrive_root_furl, vdrive_server):
# vdrive_root implements RIMutableDirectoryNode root = DirectoryNode(vdrive_root_furl, self)
self.log("got vdrive root") self.log("got vdrive root")
self._connected_to_vdrive = True
self._vdrive_server = vdrive_server self._vdrive_server = vdrive_server
self._vdrive_root = vdrive_root self._vdrive_root = root
def _disconnected(): self._connected_to_vdrive = True
self._connected_to_vdrive = False
vdrive_root.notifyOnDisconnect(_disconnected)
#vdrive = self.getServiceNamed("vdrive") #vdrive = self.getServiceNamed("vdrive")
#vdrive.set_server(vdrive_server) #vdrive.set_server(vdrive_server)
@ -132,7 +129,7 @@ class Client(node.Node, Referenceable):
if "webish" in self.namedServices: if "webish" in self.namedServices:
webish = self.getServiceNamed("webish") webish = self.getServiceNamed("webish")
webish.set_vdrive(self.tub, vdrive_server, vdrive_root) webish.set_vdrive_root(root)
def remote_get_versions(self): def remote_get_versions(self):
return str(allmydata.__version__), str(self.OLDEST_SUPPORTED_VERSION) return str(allmydata.__version__), str(self.OLDEST_SUPPORTED_VERSION)

View File

@ -2,7 +2,8 @@
import os import os
from zope.interface import implements from zope.interface import implements
from foolscap import Referenceable from foolscap import Referenceable
from allmydata.interfaces import RIVirtualDriveServer, RIMutableDirectoryNode, FileNode, DirectoryNode from allmydata.interfaces import RIVirtualDriveServer, RIMutableDirectoryNode
from allmydata.vdrive import FileNode, DirectoryNode
from allmydata.util import bencode, idlib from allmydata.util import bencode, idlib
from twisted.application import service from twisted.application import service
from twisted.python import log from twisted.python import log
@ -61,7 +62,7 @@ class MutableDirectoryNode(Referenceable):
elif isinstance(v, DirectoryNode): elif isinstance(v, DirectoryNode):
child_nodes[k] = ("subdir", v.furl) child_nodes[k] = ("subdir", v.furl)
else: else:
raise RuntimeError("unknown child node '%s'" % (v,)) raise RuntimeError("unknown child[%s] node '%s'" % (k,v))
data = bencode.bencode(child_nodes) data = bencode.bencode(child_nodes)
f = open(os.path.join(self._basedir, self._name), "wb") f = open(os.path.join(self._basedir, self._name), "wb")
f.write(data) f.write(data)
@ -143,6 +144,7 @@ class VirtualDriveServer(service.MultiService, Referenceable):
# all callers. In addition, we must register any new ones that we # all callers. In addition, we must register any new ones that we
# create later on. # create later on.
tub = self.parent.tub tub = self.parent.tub
self._root_furl = tub.registerReference(self._root, "root")
self._register_all_dirnodes(tub) self._register_all_dirnodes(tub)
def _register_all_dirnodes(self, tub): def _register_all_dirnodes(self, tub):
@ -150,14 +152,14 @@ class VirtualDriveServer(service.MultiService, Referenceable):
node = MutableDirectoryNode(self._vdrive_dir, name) node = MutableDirectoryNode(self._vdrive_dir, name)
ignored_furl = tub.registerReference(node, name) ignored_furl = tub.registerReference(node, name)
def get_public_root(self): def get_public_root_furl(self):
if self._root: if self._root:
return self._root return self._root_furl
raise NoPublicRootError raise NoPublicRootError
remote_get_public_root = get_public_root remote_get_public_root_furl = get_public_root_furl
def create_directory(self): def create_directory(self):
node = MutableDirectoryNode(self._vdrive_dir) node = MutableDirectoryNode(self._vdrive_dir)
furl = self.parent.tub.registerReference(node, node._name) furl = self.parent.tub.registerReference(node, node._name)
return furl return DirectoryNode(furl)
remote_create_directory = create_directory remote_create_directory = create_directory

View File

@ -2,7 +2,7 @@
from zope.interface import Interface from zope.interface import Interface
from foolscap.schema import StringConstraint, ListOf, TupleOf, SetOf, DictOf, \ from foolscap.schema import StringConstraint, ListOf, TupleOf, SetOf, DictOf, \
ChoiceOf ChoiceOf
from foolscap import RemoteInterface, Referenceable, Copyable, RemoteCopy from foolscap import RemoteInterface, Referenceable
HASH_SIZE=32 HASH_SIZE=32
@ -123,46 +123,6 @@ class RIStorageServer(RemoteInterface):
from foolscap.schema import Any from foolscap.schema import Any
RIMutableDirectoryNode_ = Any() # TODO: how can we avoid this? RIMutableDirectoryNode_ = Any() # TODO: how can we avoid this?
class DirectoryNode(Copyable, RemoteCopy):
"""I have either a .furl attribute or a .get(tub) method."""
typeToCopy = "allmydata.com/tahoe/interfaces/DirectoryNode/v1"
copytype = typeToCopy
def __init__(self, furl=None):
# RemoteCopy subclasses are always called without arguments
self.furl = furl
def getStateToCopy(self):
return {"furl": self.furl }
def setCopyableState(self, state):
self.furl = state['furl']
def __hash__(self):
return hash((self.__class__, self.furl))
def __cmp__(self, them):
if cmp(type(self), type(them)):
return cmp(type(self), type(them))
if cmp(self.__class__, them.__class__):
return cmp(self.__class__, them.__class__)
return cmp(self.furl, them.furl)
class FileNode(Copyable, RemoteCopy):
"""I have a .uri attribute."""
typeToCopy = "allmydata.com/tahoe/interfaces/FileNode/v1"
copytype = typeToCopy
def __init__(self, uri=None):
# RemoteCopy subclasses are always called without arguments
self.uri = uri
def getStateToCopy(self):
return {"uri": self.uri }
def setCopyableState(self, state):
self.uri = state['uri']
def __hash__(self):
return hash((self.__class__, self.uri))
def __cmp__(self, them):
if cmp(type(self), type(them)):
return cmp(type(self), type(them))
if cmp(self.__class__, them.__class__):
return cmp(self.__class__, them.__class__)
return cmp(self.uri, them.uri)
FileNode_ = Any() # TODO: foolscap needs constraints on copyables FileNode_ = Any() # TODO: foolscap needs constraints on copyables
DirectoryNode_ = Any() # TODO: same DirectoryNode_ = Any() # TODO: same
AnyNode_ = ChoiceOf(FileNode_, DirectoryNode_) AnyNode_ = ChoiceOf(FileNode_, DirectoryNode_)
@ -186,14 +146,62 @@ class RIMutableDirectoryNode(RemoteInterface):
class RIVirtualDriveServer(RemoteInterface): class RIVirtualDriveServer(RemoteInterface):
def get_public_root(): def get_public_root_furl():
"""If this vdrive server does not offer a public root, this will """If this vdrive server does not offer a public root, this will
raise an exception.""" raise an exception."""
return DirectoryNode_ return FURL
def create_directory(): def create_directory():
return DirectoryNode_ return DirectoryNode_
class IFileNode(Interface):
def download(target):
"""Download the file's contents to a given IDownloadTarget"""
def download_to_data():
pass
class IDirectoryNode(Interface):
def list():
"""I return a Deferred that fires with a"""
pass
def get(name):
"""I return a Deferred that fires with a specific named child."""
pass
def add(name, child):
"""I add a child at the specific name. I return a Deferred that fires
when the operation finishes."""
def add_file(name, uploadable):
"""I upload a file (using the given IUploadable), then attach the
resulting FileNode to the directory at the given name."""
def remove(name):
"""I remove the child at the specific name. I return a Deferred that
fires when the operation finishes."""
def create_empty_directory(name):
"""I create and attach an empty directory at the given name. I return
a Deferred that fires when the operation finishes."""
def attach_shared_directory(name, furl):
"""I attach a directory that was shared (possibly by someone else)
with IDirectoryNode.get_furl to this parent at the given name. I
return a Deferred that fires when the operation finishes."""
def get_shared_directory_furl():
"""I return a FURL that can be used to attach this directory to
somewhere else. The FURL is just a string, so it can be passed
through email or other out-of-band protocol. Use it by passing it in
to attach_shared_directory(). I return a Deferred that fires when the
operation finishes."""
def move_child_to(current_child_name, new_parent, new_child_name=None):
"""I take one of my children and move them to a new parent. The child
is referenced by name. On the new parent, the child will live under
'new_child_name', which defaults to 'current_child_name'. I return a
Deferred that fires when the operation finishes."""
class ICodecEncoder(Interface): class ICodecEncoder(Interface):

View File

@ -2,8 +2,8 @@
import os import os
from twisted.trial import unittest from twisted.trial import unittest
from allmydata.filetable import (MutableDirectoryNode, from allmydata.filetable import (MutableDirectoryNode,
BadDirectoryError, BadFileError, BadNameError) BadFileError, BadNameError)
from allmydata.interfaces import FileNode, DirectoryNode from allmydata.vdrive import FileNode, DirectoryNode
class FileTable(unittest.TestCase): class FileTable(unittest.TestCase):

View File

@ -3,7 +3,7 @@ import os
from twisted.trial import unittest from twisted.trial import unittest
from twisted.internet import defer, reactor from twisted.internet import defer, reactor
from twisted.application import service from twisted.application import service
from allmydata import client, uri, download, vdrive from allmydata import client, uri, download, upload
from allmydata.introducer_and_vdrive import IntroducerAndVdrive from allmydata.introducer_and_vdrive import IntroducerAndVdrive
from allmydata.util import idlib, fileutil, testutil from allmydata.util import idlib, fileutil, testutil
from foolscap.eventual import flushEventualQueue from foolscap.eventual import flushEventualQueue
@ -234,32 +234,24 @@ class SystemTest(testutil.SignalMixin, unittest.TestCase):
d = self.set_up_nodes() d = self.set_up_nodes()
def _do_publish(res): def _do_publish(res):
log.msg("PUBLISHING") log.msg("PUBLISHING")
ut = upload.Data(DATA)
c0 = self.clients[0] c0 = self.clients[0]
d1 = vdrive.mkdir(c0._vdrive_server, c0._vdrive_root, d1 = c0._vdrive_root.create_empty_directory("subdir1")
"subdir1")
d1.addCallback(lambda subdir1_node: d1.addCallback(lambda subdir1_node:
c0.tub.getReference(subdir1_node.furl)) subdir1_node.add_file("mydata567", ut))
def _put_file(subdir1): def _stash_uri(filenode):
uploader = c0.getServiceNamed("uploader") self.uri = filenode.uri
d2 = uploader.upload_data(DATA) return filenode
def _stash_uri(uri): d1.addCallback(_stash_uri)
self.uri = uri
return uri
d2.addCallback(_stash_uri)
d2.addCallback(lambda uri: vdrive.add_file(subdir1, "mydata567", uri))
return d2
d1.addCallback(_put_file)
return d1 return d1
d.addCallback(_do_publish) d.addCallback(_do_publish)
def _publish_done(filenode): def _publish_done(filenode):
log.msg("publish finished") log.msg("publish finished")
c1 = self.clients[1] c1 = self.clients[1]
d1 = c1._vdrive_root.callRemote("get", "subdir1") d1 = c1._vdrive_root.get("subdir1")
d1.addCallback(lambda subdir1_dirnode: d1.addCallback(lambda subdir1: subdir1.get("mydata567"))
c1.tub.getReference(subdir1_dirnode.furl)) d1.addCallback(lambda filenode: filenode.download_to_data())
d1.addCallback(lambda subdir1: subdir1.callRemote("get", "mydata567"))
d1.addCallback(lambda filenode: c1.getServiceNamed("downloader").download_to_data(filenode.uri))
return d1 return d1
d.addCallback(_publish_done) d.addCallback(_publish_done)
def _get_done(data): def _get_done(data):

View File

@ -5,7 +5,7 @@ from twisted.application import service
from twisted.internet import defer from twisted.internet import defer
from twisted.python import log from twisted.python import log
from allmydata import upload, download from allmydata import upload, download
from allmydata.interfaces import FileNode, DirectoryNode from foolscap import Copyable, RemoteCopy
class VDrive(service.MultiService): class VDrive(service.MultiService):
name = "vdrive" name = "vdrive"
@ -181,23 +181,113 @@ class VDrive(service.MultiService):
return self.get_file(from_where, download.FileHandle(filehandle)) return self.get_file(from_where, download.FileHandle(filehandle))
# utility stuff class DirectoryNode(Copyable, RemoteCopy):
def add_file(parent_node, child_name, uri): """I have either a .furl attribute or a .get(tub) method."""
child_node = FileNode(uri) typeToCopy = "allmydata.com/tahoe/interfaces/DirectoryNode/v1"
d = parent_node.callRemote("add", child_name, child_node) copytype = typeToCopy
return d def __init__(self, furl=None, client=None):
# RemoteCopy subclasses are always called without arguments
self.furl = furl
self._set_client(client)
def _set_client(self, client):
self._client = client
return self
def getStateToCopy(self):
return {"furl": self.furl }
def setCopyableState(self, state):
self.furl = state['furl']
def __hash__(self):
return hash((self.__class__, self.furl))
def __cmp__(self, them):
if cmp(type(self), type(them)):
return cmp(type(self), type(them))
if cmp(self.__class__, them.__class__):
return cmp(self.__class__, them.__class__)
return cmp(self.furl, them.furl)
def mkdir(vdrive_server, parent_node, child_name): def list(self):
d = vdrive_server.callRemote("create_directory") d = self._client.tub.getReference(self.furl)
d.addCallback(lambda newdir_furl: d.addCallback(lambda node: node.callRemote("list"))
parent_node.callRemote("add", child_name, DirectoryNode(newdir_furl))) d.addCallback(lambda children:
return d [(name,child._set_client(self._client))
for name,child in children])
return d
def add_shared_directory_furl(parent_node, child_name, furl): def get(self, name):
child_node = DirectoryNode(furl) d = self._client.tub.getReference(self.furl)
d = parent_node.callRemote("add", child_name, child_node) d.addCallback(lambda node: node.callRemote("get", name))
return d d.addCallback(lambda child: child._set_client(self._client))
return d
def add(self, name, child):
d = self._client.tub.getReference(self.furl)
d.addCallback(lambda node: node.callRemote("add", name, child))
d.addCallback(lambda newnode: newnode._set_client(self._client))
return d
def add_file(self, name, uploadable):
uploader = self._client.getServiceNamed("uploader")
d = uploader.upload(uploadable)
d.addCallback(lambda uri: self.add(name, FileNode(uri, self._client)))
return d
def remove(self, name):
d = self._client.tub.getReference(self.furl)
d.addCallback(lambda node: node.callRemote("remove", name))
d.addCallback(lambda newnode: newnode._set_client(self._client))
return d
def create_empty_directory(self, name):
vdrive_server = self._client._vdrive_server
d = vdrive_server.callRemote("create_directory")
d.addCallback(lambda node: self.add(name, node))
return d
def attach_shared_directory(self, name, furl):
d = self.add(name, DirectoryNode(furl))
return d
def get_shared_directory_furl(self):
return defer.succeed(self.furl)
def move_child_to(self, current_child_name,
new_parent, new_child_name=None):
if new_child_name is None:
new_child_name = current_child_name
d = self.get(current_child_name)
d.addCallback(lambda child: new_parent.add(new_child_name, child))
d.addCallback(lambda child: self.remove(current_child_name))
return d
class FileNode(Copyable, RemoteCopy):
"""I have a .uri attribute."""
typeToCopy = "allmydata.com/tahoe/interfaces/FileNode/v1"
copytype = typeToCopy
def __init__(self, uri=None, client=None):
# RemoteCopy subclasses are always called without arguments
self.uri = uri
self._set_client(client)
def _set_client(self, client):
self._client = client
return self
def getStateToCopy(self):
return {"uri": self.uri }
def setCopyableState(self, state):
self.uri = state['uri']
def __hash__(self):
return hash((self.__class__, self.uri))
def __cmp__(self, them):
if cmp(type(self), type(them)):
return cmp(type(self), type(them))
if cmp(self.__class__, them.__class__):
return cmp(self.__class__, them.__class__)
return cmp(self.uri, them.uri)
def download(self, target):
downloader = self._client.getServiceNamed("downloader")
return downloader.download(self.uri, target)
def download_to_data(self):
downloader = self._client.getServiceNamed("downloader")
return downloader.download_to_data(self.uri)
def create_anonymous_directory(vdrive_server):
d = vdrive_server.callRemote("create_directory")
return d

View File

@ -5,8 +5,9 @@ from twisted.python import util, log
from nevow import inevow, rend, loaders, appserver, url, tags as T from nevow import inevow, rend, loaders, appserver, url, tags as T
from allmydata.util import idlib from allmydata.util import idlib
from allmydata.uri import unpack_uri from allmydata.uri import unpack_uri
from allmydata.interfaces import IDownloadTarget, FileNode, DirectoryNode from allmydata.interfaces import IDownloadTarget
from allmydata import upload, vdrive from allmydata.vdrive import FileNode, DirectoryNode
from allmydata import upload
from zope.interface import implements, Interface from zope.interface import implements, Interface
import urllib import urllib
from formless import annotate, webform from formless import annotate, webform
@ -97,9 +98,7 @@ class Directory(rend.Page):
addSlash = True addSlash = True
docFactory = getxmlfile("directory.xhtml") docFactory = getxmlfile("directory.xhtml")
def __init__(self, tub, vdrive_server, dirnode, dirname): def __init__(self, dirnode, dirname):
self._tub = tub
self._vdrive_server = vdrive_server
self._dirnode = dirnode self._dirnode = dirnode
self._dirname = dirname self._dirname = dirname
@ -110,16 +109,13 @@ class Directory(rend.Page):
dirname = "/" + name dirname = "/" + name
else: else:
dirname = self._dirname + "/" + name dirname = self._dirname + "/" + name
d = self._dirnode.callRemote("get", name) d = self._dirnode.get(name)
def _got_child(res): def _got_child(res):
if isinstance(res, FileNode): if isinstance(res, FileNode):
dl = get_downloader_service(ctx) dl = get_downloader_service(ctx)
return Downloader(dl, name, res) return Downloader(dl, name, res)
elif isinstance(res, DirectoryNode): elif isinstance(res, DirectoryNode):
d2 = self._tub.getReference(res.furl) return Directory(res, dirname)
d2.addCallback(lambda dirnode:
Directory(self._tub, self._vdrive_server, dirnode, dirname))
return d2
else: else:
raise RuntimeError("what is this %s" % res) raise RuntimeError("what is this %s" % res)
d.addCallback(_got_child) d.addCallback(_got_child)
@ -132,18 +128,18 @@ class Directory(rend.Page):
return "Directory of '%s':" % self._dirname return "Directory of '%s':" % self._dirname
def data_children(self, ctx, data): def data_children(self, ctx, data):
d = self._dirnode.callRemote("list") d = self._dirnode.list()
return d return d
def render_row(self, ctx, data): def render_row(self, ctx, data):
name, target = data name, target = data
if isinstance(target, str): if isinstance(target, FileNode):
# file # file
dlurl = urllib.quote(name) dlurl = urllib.quote(name)
ctx.fillSlots("filename", ctx.fillSlots("filename",
T.a(href=dlurl)[html.escape(name)]) T.a(href=dlurl)[html.escape(name)])
ctx.fillSlots("type", "FILE") ctx.fillSlots("type", "FILE")
uri = target uri = target.uri
dl_uri_url = url.root.child("download_uri").child(uri) dl_uri_url = url.root.child("download_uri").child(uri)
# add a filename= query argument to give it a Content-Type # add a filename= query argument to give it a Content-Type
dl_uri_url = dl_uri_url.add("filename", name) dl_uri_url = dl_uri_url.add("filename", name)
@ -156,13 +152,13 @@ class Directory(rend.Page):
# to be invoked, which deletes the file and then redirects the # to be invoked, which deletes the file and then redirects the
# browser back to this directory # browser back to this directory
del_url = url.here.child("_delete") del_url = url.here.child("_delete")
#del_url = del_url.add("uri", target) #del_url = del_url.add("uri", target.uri)
del_url = del_url.add("name", name) del_url = del_url.add("name", name)
delete = T.form(action=del_url, method="post")[ delete = T.form(action=del_url, method="post")[
T.input(type='submit', value='del', name="del"), T.input(type='submit', value='del', name="del"),
] ]
ctx.fillSlots("delete", delete) ctx.fillSlots("delete", delete)
else: elif isinstance(target, DirectoryNode):
# directory # directory
subdir_url = urllib.quote(name) subdir_url = urllib.quote(name)
ctx.fillSlots("filename", ctx.fillSlots("filename",
@ -171,6 +167,8 @@ class Directory(rend.Page):
ctx.fillSlots("size", "-") ctx.fillSlots("size", "-")
ctx.fillSlots("uri", "-") ctx.fillSlots("uri", "-")
ctx.fillSlots("delete", "-") ctx.fillSlots("delete", "-")
else:
raise RuntimeError("unknown thing %s" % (target,))
return ctx.tag return ctx.tag
def render_forms(self, ctx, data): def render_forms(self, ctx, data):
@ -224,7 +222,8 @@ class Directory(rend.Page):
def _uploaded(uri): def _uploaded(uri):
if privateupload: if privateupload:
return self.uploadprivate(name, uri) return self.uploadprivate(name, uri)
return vdrive.add_file(self._dirnode, name, uri) else:
return self._dirnode.add(name, FileNode(uri))
d.addCallback(_uploaded) d.addCallback(_uploaded)
def _done(res): def _done(res):
log.msg("webish upload complete") log.msg("webish upload complete")
@ -244,7 +243,7 @@ class Directory(rend.Page):
def mkdir(self, name): def mkdir(self, name):
"""mkdir2""" """mkdir2"""
log.msg("making new webish directory") log.msg("making new webish directory")
d = vdrive.mkdir(self._vdrive_server, self._dirnode, name) d = self._dirnode.create_empty_directory(name)
def _done(res): def _done(res):
log.msg("webish mkdir complete") log.msg("webish mkdir complete")
return res return res
@ -255,7 +254,7 @@ class Directory(rend.Page):
# perform the delete, then redirect back to the directory page # perform the delete, then redirect back to the directory page
args = inevow.IRequest(ctx).args args = inevow.IRequest(ctx).args
name = args["name"][0] name = args["name"][0]
d = self._dirnode.callRemote("remove", name) d = self._dirnode.remove(name)
def _deleted(res): def _deleted(res):
return url.here.up() return url.here.up()
d.addCallback(_deleted) d.addCallback(_deleted)
@ -291,10 +290,11 @@ class TypedFile(static.File):
self.defaultType) self.defaultType)
class Downloader(resource.Resource): class Downloader(resource.Resource):
def __init__(self, downloader, name, uri): def __init__(self, downloader, name, filenode):
self._downloader = downloader self._downloader = downloader
self._name = name self._name = name
self._uri = uri assert isinstance(filenode, FileNode)
self._filenode = filenode
def render(self, ctx): def render(self, ctx):
req = inevow.IRequest(ctx) req = inevow.IRequest(ctx)
@ -307,10 +307,7 @@ class Downloader(resource.Resource):
if encoding: if encoding:
req.setHeader('content-encoding', encoding) req.setHeader('content-encoding', encoding)
t = WebDownloadTarget(req) self._filenode.download(WebDownloadTarget(req))
#dl = IDownloader(ctx)
dl = self._downloader
dl.download(self._uri, t)
return server.NOT_DONE_YET return server.NOT_DONE_YET
@ -331,7 +328,7 @@ class Root(rend.Page):
uri = req.args["uri"][0] uri = req.args["uri"][0]
else: else:
return rend.NotFound return rend.NotFound
child = Downloader(dl, filename, uri) child = Downloader(dl, filename, FileNode(uri, IClient(ctx)))
return child, () return child, ()
return rend.Page.locateChild(self, ctx, segments) return rend.Page.locateChild(self, ctx, segments)
@ -366,8 +363,8 @@ class WebishServer(service.MultiService):
# apparently 'ISite' does not exist # apparently 'ISite' does not exist
#self.site._client = self.parent #self.site._client = self.parent
def set_vdrive(self, tub, vdrive_server, dirnode): def set_vdrive_root(self, root):
self.root.putChild("vdrive", Directory(tub, vdrive_server, dirnode, "/")) self.root.putChild("vdrive", Directory(root, "/"))
# I tried doing it this way and for some reason it didn't seem to work # I tried doing it this way and for some reason it didn't seem to work
#print "REMEMBERING", self.site, dl, IDownloader #print "REMEMBERING", self.site, dl, IDownloader
#self.site.remember(dl, IDownloader) #self.site.remember(dl, IDownloader)