mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-04-09 03:44:23 +00:00
upload: return an UploadResults instance (with .uri) instead of just a URI
This commit is contained in:
parent
2f09b03bcc
commit
66f33ee504
@ -46,6 +46,7 @@ class ControlServer(Referenceable, service.Service, testutil.PollMixin):
|
||||
uploader = self.parent.getServiceNamed("uploader")
|
||||
u = upload.FileName(filename)
|
||||
d = uploader.upload(u)
|
||||
d.addCallback(lambda results: results.uri)
|
||||
return d
|
||||
|
||||
def remote_download_from_uri_to_file(self, uri, filename):
|
||||
@ -162,6 +163,7 @@ class SpeedTest:
|
||||
else:
|
||||
up = upload.FileName(fn)
|
||||
d1 = self.parent.upload(up)
|
||||
d1.addCallback(lambda results: results.uri)
|
||||
d1.addCallback(_record_uri, i)
|
||||
d1.addCallback(_upload_one_file, i+1)
|
||||
return d1
|
||||
|
@ -279,6 +279,7 @@ class NewDirectoryNode:
|
||||
if self.is_readonly():
|
||||
return defer.fail(NotMutableError())
|
||||
d = self._client.upload(uploadable)
|
||||
d.addCallback(lambda results: results.uri)
|
||||
d.addCallback(self._client.create_node_from_uri)
|
||||
d.addCallback(lambda node: self.set_node(name, node))
|
||||
return d
|
||||
|
@ -1207,10 +1207,19 @@ class IUploadable(Interface):
|
||||
"""The upload is finished, and whatever filehandle was in use may be
|
||||
closed."""
|
||||
|
||||
class IUploadResults(Interface):
|
||||
"""I am returned by upload() methods. I contain a number of public
|
||||
attributes which can be read to determine the results of the upload::
|
||||
|
||||
.uri : the CHK read-cap for the file
|
||||
|
||||
"""
|
||||
|
||||
class IUploader(Interface):
|
||||
def upload(uploadable):
|
||||
"""Upload the file. 'uploadable' must impement IUploadable. This
|
||||
returns a Deferred which fires with the URI of the file."""
|
||||
returns a Deferred which fires with an UploadResults instance, from
|
||||
which the URI of the file can be obtained as results.uri ."""
|
||||
|
||||
def upload_ssk(write_capability, new_version, uploadable):
|
||||
"""TODO: how should this work?"""
|
||||
@ -1278,9 +1287,10 @@ class IChecker(Interface):
|
||||
|
||||
class IClient(Interface):
|
||||
def upload(uploadable):
|
||||
"""Upload some data into a CHK, get back the URI string for it.
|
||||
"""Upload some data into a CHK, get back the UploadResults for it.
|
||||
@param uploadable: something that implements IUploadable
|
||||
@return: a Deferred that fires with the (string) URI for this file.
|
||||
@return: a Deferred that fires with the UploadResults instance.
|
||||
To get the URI for this file, use results.uri .
|
||||
"""
|
||||
|
||||
def create_mutable_file(contents=""):
|
||||
|
@ -392,6 +392,7 @@ this file are ignored.
|
||||
u = self.nodes[0].getServiceNamed("uploader")
|
||||
d = self.nodes[0].debug_wait_for_client_connections(self.numnodes+1)
|
||||
d.addCallback(lambda res: u.upload(upload.FileName(files[name])))
|
||||
d.addCallback(lambda results: results.uri)
|
||||
else:
|
||||
raise RuntimeError("unknown mode=%s" % self.mode)
|
||||
def _complete(uri):
|
||||
|
@ -44,7 +44,9 @@ class FakeClient:
|
||||
def _got_data(datav):
|
||||
data = "".join(datav)
|
||||
n = create_chk_filenode(self, data)
|
||||
return n.get_uri()
|
||||
results = upload.UploadResults()
|
||||
results.uri = n.get_uri()
|
||||
return results
|
||||
d.addCallback(_got_data)
|
||||
return d
|
||||
|
||||
|
@ -98,7 +98,8 @@ class AssistedUpload(unittest.TestCase):
|
||||
DATA = "I need help\n" * 1000
|
||||
return upload_data(u, DATA)
|
||||
d.addCallback(_ready)
|
||||
def _uploaded(uri):
|
||||
def _uploaded(results):
|
||||
uri = results.uri
|
||||
assert "CHK" in uri
|
||||
d.addCallback(_uploaded)
|
||||
|
||||
@ -141,7 +142,8 @@ class AssistedUpload(unittest.TestCase):
|
||||
assert u._helper
|
||||
return upload_data(u, DATA)
|
||||
d.addCallback(_ready)
|
||||
def _uploaded(uri):
|
||||
def _uploaded(results):
|
||||
uri = results.uri
|
||||
assert "CHK" in uri
|
||||
d.addCallback(_uploaded)
|
||||
|
||||
@ -172,7 +174,8 @@ class AssistedUpload(unittest.TestCase):
|
||||
DATA = "I need help\n" * 1000
|
||||
return upload_data(u, DATA)
|
||||
d.addCallback(_ready)
|
||||
def _uploaded(uri):
|
||||
def _uploaded(results):
|
||||
uri = results.uri
|
||||
assert "CHK" in uri
|
||||
d.addCallback(_uploaded)
|
||||
|
||||
|
@ -214,7 +214,8 @@ class SystemTest(testutil.SignalMixin, testutil.PollMixin, unittest.TestCase):
|
||||
d1 = u.upload(up)
|
||||
return d1
|
||||
d.addCallback(_do_upload)
|
||||
def _upload_done(uri):
|
||||
def _upload_done(results):
|
||||
uri = results.uri
|
||||
log.msg("upload finished: uri is %s" % (uri,))
|
||||
self.uri = uri
|
||||
dl = self.clients[1].getServiceNamed("downloader")
|
||||
@ -295,7 +296,8 @@ class SystemTest(testutil.SignalMixin, testutil.PollMixin, unittest.TestCase):
|
||||
def _upload_with_helper(res):
|
||||
u = upload.Data(HELPER_DATA, contenthashkey=contenthashkey)
|
||||
d = self.extra_node.upload(u)
|
||||
def _uploaded(uri):
|
||||
def _uploaded(results):
|
||||
uri = results.uri
|
||||
return self.downloader.download_to_data(uri)
|
||||
d.addCallback(_uploaded)
|
||||
def _check(newdata):
|
||||
@ -308,7 +310,8 @@ class SystemTest(testutil.SignalMixin, testutil.PollMixin, unittest.TestCase):
|
||||
u = upload.Data(HELPER_DATA, contenthashkey=contenthashkey)
|
||||
u.debug_stash_RemoteEncryptedUploadable = True
|
||||
d = self.extra_node.upload(u)
|
||||
def _uploaded(uri):
|
||||
def _uploaded(results):
|
||||
uri = results.uri
|
||||
return self.downloader.download_to_data(uri)
|
||||
d.addCallback(_uploaded)
|
||||
def _check(newdata):
|
||||
@ -392,7 +395,8 @@ class SystemTest(testutil.SignalMixin, testutil.PollMixin, unittest.TestCase):
|
||||
return self.extra_node.upload(u2)
|
||||
d.addCallbacks(_upload_again)
|
||||
|
||||
def _uploaded(uri):
|
||||
def _uploaded(results):
|
||||
uri = results.uri
|
||||
log.msg("Second upload complete", level=log.NOISY,
|
||||
facility="tahoe.test.test_system")
|
||||
reu = u2.debug_RemoteEncryptedUploadable
|
||||
|
@ -12,6 +12,9 @@ from foolscap import eventual
|
||||
|
||||
MiB = 1024*1024
|
||||
|
||||
def extract_uri(results):
|
||||
return results.uri
|
||||
|
||||
class Uploadable(unittest.TestCase):
|
||||
def shouldEqual(self, data, expected):
|
||||
self.failUnless(isinstance(data, list))
|
||||
@ -209,18 +212,21 @@ class GoodServer(unittest.TestCase):
|
||||
def test_data_zero(self):
|
||||
data = self.get_data(SIZE_ZERO)
|
||||
d = upload_data(self.u, data)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_small, SIZE_ZERO)
|
||||
return d
|
||||
|
||||
def test_data_small(self):
|
||||
data = self.get_data(SIZE_SMALL)
|
||||
d = upload_data(self.u, data)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_small, SIZE_SMALL)
|
||||
return d
|
||||
|
||||
def test_data_large(self):
|
||||
data = self.get_data(SIZE_LARGE)
|
||||
d = upload_data(self.u, data)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_large, SIZE_LARGE)
|
||||
return d
|
||||
|
||||
@ -230,24 +236,28 @@ class GoodServer(unittest.TestCase):
|
||||
# we want 3 segments, since that's not a power of two
|
||||
self.set_encoding_parameters(25, 75, 100, segsize)
|
||||
d = upload_data(self.u, data)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_large, SIZE_LARGE)
|
||||
return d
|
||||
|
||||
def test_filehandle_zero(self):
|
||||
data = self.get_data(SIZE_ZERO)
|
||||
d = upload_filehandle(self.u, StringIO(data))
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_small, SIZE_ZERO)
|
||||
return d
|
||||
|
||||
def test_filehandle_small(self):
|
||||
data = self.get_data(SIZE_SMALL)
|
||||
d = upload_filehandle(self.u, StringIO(data))
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_small, SIZE_SMALL)
|
||||
return d
|
||||
|
||||
def test_filehandle_large(self):
|
||||
data = self.get_data(SIZE_LARGE)
|
||||
d = upload_filehandle(self.u, StringIO(data))
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_large, SIZE_LARGE)
|
||||
return d
|
||||
|
||||
@ -258,6 +268,7 @@ class GoodServer(unittest.TestCase):
|
||||
f.write(data)
|
||||
f.close()
|
||||
d = upload_filename(self.u, fn)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_small, SIZE_ZERO)
|
||||
return d
|
||||
|
||||
@ -268,6 +279,7 @@ class GoodServer(unittest.TestCase):
|
||||
f.write(data)
|
||||
f.close()
|
||||
d = upload_filename(self.u, fn)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_small, SIZE_SMALL)
|
||||
return d
|
||||
|
||||
@ -278,6 +290,7 @@ class GoodServer(unittest.TestCase):
|
||||
f.write(data)
|
||||
f.close()
|
||||
d = upload_filename(self.u, fn)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_large, SIZE_LARGE)
|
||||
return d
|
||||
|
||||
@ -333,6 +346,7 @@ class PeerSelection(unittest.TestCase):
|
||||
data = self.get_data(SIZE_LARGE)
|
||||
self.set_encoding_parameters(25, 30, 50)
|
||||
d = upload_data(self.u, data)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_large, SIZE_LARGE)
|
||||
def _check(res):
|
||||
for p in self.node.last_peers:
|
||||
@ -350,6 +364,7 @@ class PeerSelection(unittest.TestCase):
|
||||
data = self.get_data(SIZE_LARGE)
|
||||
self.set_encoding_parameters(50, 75, 100)
|
||||
d = upload_data(self.u, data)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_large, SIZE_LARGE)
|
||||
def _check(res):
|
||||
for p in self.node.last_peers:
|
||||
@ -367,6 +382,7 @@ class PeerSelection(unittest.TestCase):
|
||||
data = self.get_data(SIZE_LARGE)
|
||||
self.set_encoding_parameters(24, 41, 51)
|
||||
d = upload_data(self.u, data)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_large, SIZE_LARGE)
|
||||
def _check(res):
|
||||
got_one = []
|
||||
@ -394,6 +410,7 @@ class PeerSelection(unittest.TestCase):
|
||||
data = self.get_data(SIZE_LARGE)
|
||||
self.set_encoding_parameters(100, 150, 200)
|
||||
d = upload_data(self.u, data)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_large, SIZE_LARGE)
|
||||
def _check(res):
|
||||
for p in self.node.last_peers:
|
||||
@ -411,6 +428,7 @@ class PeerSelection(unittest.TestCase):
|
||||
data = self.get_data(SIZE_LARGE)
|
||||
self.set_encoding_parameters(3, 5, 10)
|
||||
d = upload_data(self.u, data)
|
||||
d.addCallback(extract_uri)
|
||||
d.addCallback(self._check_large, SIZE_LARGE)
|
||||
def _check(res):
|
||||
counts = {}
|
||||
|
@ -5,7 +5,7 @@ from twisted.trial import unittest
|
||||
from twisted.internet import defer
|
||||
from twisted.web import client, error, http
|
||||
from twisted.python import failure, log
|
||||
from allmydata import interfaces, provisioning, uri, webish
|
||||
from allmydata import interfaces, provisioning, uri, webish, upload
|
||||
from allmydata.util import fileutil
|
||||
from allmydata.test.common import NonGridDirectoryNode, FakeCHKFileNode, FakeMutableFileNode, create_chk_filenode
|
||||
from allmydata.interfaces import IURI, INewDirectoryURI, IReadonlyNewDirectoryURI, IFileURI, IMutableFileURI, IMutableFileNode
|
||||
@ -61,7 +61,9 @@ class FakeClient(service.MultiService):
|
||||
def _got_data(datav):
|
||||
data = "".join(datav)
|
||||
n = create_chk_filenode(self, data)
|
||||
return n.get_uri()
|
||||
results = upload.UploadResults()
|
||||
results.uri = n.get_uri()
|
||||
return results
|
||||
d.addCallback(_got_data)
|
||||
return d
|
||||
|
||||
|
@ -15,7 +15,7 @@ from allmydata.util.hashutil import file_renewal_secret_hash, \
|
||||
from allmydata import encode, storage, hashtree, uri
|
||||
from allmydata.util import idlib, mathutil
|
||||
from allmydata.util.assertutil import precondition
|
||||
from allmydata.interfaces import IUploadable, IUploader, \
|
||||
from allmydata.interfaces import IUploadable, IUploader, IUploadResults, \
|
||||
IEncryptedUploadable, RIEncryptedUploadable
|
||||
from pycryptopp.cipher.aes import AES
|
||||
|
||||
@ -36,6 +36,9 @@ class HaveAllPeersError(Exception):
|
||||
class TooFullError(Exception):
|
||||
pass
|
||||
|
||||
class UploadResults:
|
||||
implements(IUploadResults)
|
||||
|
||||
# our current uri_extension is 846 bytes for small files, a few bytes
|
||||
# more for larger ones (since the filesize is encoded in decimal in a
|
||||
# few places). Ask for a little bit more just in case we need it. If
|
||||
@ -632,7 +635,9 @@ class CHKUploader:
|
||||
total_shares=total_shares,
|
||||
size=size,
|
||||
)
|
||||
return u.to_string()
|
||||
results = UploadResults()
|
||||
results.uri = u.to_string()
|
||||
return results
|
||||
|
||||
|
||||
def read_this_many_bytes(uploadable, size, prepend_data=[]):
|
||||
@ -666,8 +671,14 @@ class LiteralUploader:
|
||||
d.addCallback(lambda size: read_this_many_bytes(uploadable, size))
|
||||
d.addCallback(lambda data: uri.LiteralFileURI("".join(data)))
|
||||
d.addCallback(lambda u: u.to_string())
|
||||
d.addCallback(self._build_results)
|
||||
return d
|
||||
|
||||
def _build_results(self, uri):
|
||||
results = UploadResults()
|
||||
results.uri = uri
|
||||
return results
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
@ -838,7 +849,9 @@ class AssistedUploader:
|
||||
total_shares=self._total_shares,
|
||||
size=self._size,
|
||||
)
|
||||
return u.to_string()
|
||||
results = UploadResults()
|
||||
results.uri = u.to_string()
|
||||
return results
|
||||
|
||||
class NoParameterPreferencesMixin:
|
||||
max_segment_size = None
|
||||
|
@ -797,7 +797,7 @@ class POSTHandler(rend.Page):
|
||||
# SDMF: files are small, and we can only upload data.
|
||||
contents.file.seek(0)
|
||||
data = contents.file.read()
|
||||
uploadable = FileHandle(contents.file)
|
||||
#uploadable = FileHandle(contents.file)
|
||||
d = self._check_replacement(name)
|
||||
d.addCallback(lambda res: self._node.has_child(name))
|
||||
def _checked(present):
|
||||
@ -1205,6 +1205,7 @@ class URIPUTHandler(rend.Page):
|
||||
# without the associated set_uri.
|
||||
uploadable = FileHandle(req.content)
|
||||
d = IClient(ctx).upload(uploadable)
|
||||
d.addCallback(lambda results: results.uri)
|
||||
# that fires with the URI of the new file
|
||||
return d
|
||||
|
||||
@ -1231,6 +1232,7 @@ class URIPOSTHandler(rend.Page):
|
||||
fileobj = req.fields["file"].file
|
||||
uploadable = FileHandle(fileobj)
|
||||
d = IClient(ctx).upload(uploadable)
|
||||
d.addCallback(lambda results: results.uri)
|
||||
# that fires with the URI of the new file
|
||||
return d
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user