mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-25 07:31:07 +00:00
make new vdrive work, implement convenience wrapper, passes all tests
This commit is contained in:
parent
5e5347a1bc
commit
82c38d370a
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user