]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
upload: return an UploadResults instance (with .uri) instead of just a URI
authorBrian Warner <warner@allmydata.com>
Wed, 6 Feb 2008 04:01:38 +0000 (21:01 -0700)
committerBrian Warner <warner@allmydata.com>
Wed, 6 Feb 2008 04:01:38 +0000 (21:01 -0700)
src/allmydata/control.py
src/allmydata/dirnode.py
src/allmydata/interfaces.py
src/allmydata/test/check_memory.py
src/allmydata/test/test_dirnode.py
src/allmydata/test/test_helper.py
src/allmydata/test/test_system.py
src/allmydata/test/test_upload.py
src/allmydata/test/test_web.py
src/allmydata/upload.py
src/allmydata/webish.py

index 6e7fb91075f149d74a9ae88be4b28faf625925aa..8c99f0055fa995eebb03f96c90824560023a6d85 100644 (file)
@@ -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
index 392ab0418aa9693225383c100a600e9070e5b73b..569dc768f1765c2b588f8ea69b81beda28adb0f4 100644 (file)
@@ -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
index 1c7276cea4c013171cff17e204571da80f551a69..ae1fc65c7ae56cccd114829d2b2d291adb2c8853 100644 (file)
@@ -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=""):
index 6987bceaf7affc94748d95e5e9441e9316c8b332..de65de51000a98be05ac2b8df825d586ff46ee6c 100644 (file)
@@ -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):
index 0880ad6faddeb71d2d424be4b4a53904c9da04a6..ae7aacac4120fed61fad4a94d4c4815c0debdbbe 100644 (file)
@@ -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
 
index 0d80c60f5302e700a225f06cc2ec14bb951ea4b1..481664e9c701b035f6356e14d7eb5f74b1d9c62d 100644 (file)
@@ -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)
 
index 3834696bec75d97c482a5a33f06107da538af3c3..04b69eab50b8d4bca3d8b5f6045f4b2d8430ca7e 100644 (file)
@@ -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
index 88670c21ba97a289cd62ac6aae84cbd247c969b1..1e135811d33376ba6eaf483be99e49860d5bec6d 100644 (file)
@@ -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 = {}
index 374d336adeb1db2b0aa841d996ba11f643b2fa04..fa5ed141ba122f35a137f2ab9c5c34151dfb28a4 100644 (file)
@@ -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
 
index 22b85c6eeb2b8567efd6976e2c72d43a5a56ef40..659fb1b2d0baf42aa37d1a62f0b969d1f0175c91 100644 (file)
@@ -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
index bdfe2d61d75c53f70b1840e4a310a061de15fcb2..f7989a807acd6c78f0ea1db67650f198e6c8516a 100644 (file)
@@ -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