diff --git a/src/allmydata/client.py b/src/allmydata/client.py index c8c1b1832..c20d422b7 100644 --- a/src/allmydata/client.py +++ b/src/allmydata/client.py @@ -267,6 +267,7 @@ class Client(node.Node, testutil.PollMixin): uploader = self.getServiceNamed("uploader") return uploader.upload(uploadable) + def list_all_uploads(self): uploader = self.getServiceNamed("uploader") return uploader.list_all_uploads() @@ -275,6 +276,16 @@ class Client(node.Node, testutil.PollMixin): downloader = self.getServiceNamed("downloader") return downloader.list_all_downloads() + + def list_active_uploads(self): + uploader = self.getServiceNamed("uploader") + return uploader.list_active_uploads() + + def list_active_downloads(self): + downloader = self.getServiceNamed("downloader") + return downloader.list_active_downloads() + + def list_recent_uploads(self): uploader = self.getServiceNamed("uploader") return uploader.list_recent_uploads() diff --git a/src/allmydata/download.py b/src/allmydata/download.py index 83bebb376..907f9387e 100644 --- a/src/allmydata/download.py +++ b/src/allmydata/download.py @@ -949,5 +949,8 @@ class Downloader(service.MultiService): def list_all_downloads(self): return self._all_downloads.keys() + def list_active_downloads(self): + return [d.get_download_status() for d in self._all_downloads.keys() + if d.get_download_status().get_active()] def list_recent_downloads(self): return self._recent_download_status diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py index 35bf0a341..2d7f71ede 100644 --- a/src/allmydata/interfaces.py +++ b/src/allmydata/interfaces.py @@ -1389,19 +1389,21 @@ class IClient(Interface): class IClientStatus(Interface): def list_all_uploads(): - """Return a list of IUploadStatus objects, one for each upload which - currently has an object available. This uses weakrefs to track the - objects, so it may report uploads which have already finished. Use - get_active() to filter these out.""" + """Return a list of uploader objects, one for each upload which + currently has an object available (tracked with weakrefs). This is + intended for debugging purposes.""" + def list_active_uploads(): + """Return a list of active IUploadStatus objects.""" def list_recent_uploads(): """Return a list of IUploadStatus objects for the most recently started uploads.""" def list_all_downloads(): - """Return a list of IDownloadStatus objects, one for each download - which currently has an object available. This uses weakrefs to track - the objects, so it may report downloadswhich have already finished. - Use get_active() to filter these out.""" + """Return a list of downloader objects, one for each download which + currently has an object available (tracked with weakrefs). This is + intended for debugging purposes.""" + def list_active_downloads(): + """Return a list of active IDownloadStatus objects.""" def list_recent_downloads(): """Return a list of IDownloadStatus objects for the most recently started downloads.""" @@ -1433,6 +1435,10 @@ class IUploadStatus(Interface): three numbers and report the sum to the user.""" def get_active(): """Return True if the upload is currently active, False if not.""" + def get_results(): + """Return an instance of UploadResults (which contains timing and + sharemap information). Might return None if the upload is not yet + finished.""" def get_counter(): """Each upload status gets a unique number: this method returns that number. This provides a handle to this particular upload, so a web diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index 7f686d2bc..9678ae52e 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -32,8 +32,8 @@ class FakeClient(service.MultiService): } introducer_furl = "None" introducer_client = FakeIntroducerClient() - _all_uploads = [upload.UploadStatus()] - _all_downloads = [download.DownloadStatus()] + _all_upload_status = [upload.UploadStatus()] + _all_download_status = [download.DownloadStatus()] def connected_to_introducer(self): return False @@ -71,14 +71,18 @@ class FakeClient(service.MultiService): return d def list_all_uploads(self): - return self._all_uploads + return [] def list_all_downloads(self): - return self._all_downloads + return [] + def list_active_uploads(self): + return self._all_upload_status + def list_active_downloads(self): + return self._all_download_status def list_recent_uploads(self): - return self._all_uploads + return self._all_upload_status def list_recent_downloads(self): - return self._all_downloads + return self._all_download_status class WebMixin(object): @@ -1331,7 +1335,7 @@ class Web(WebMixin, unittest.TestCase): "ctime": 1002777696.7564139, "mtime": 1002777696.7564139 } - } ], + } ], "atomic_added_2": [ "filenode", { "rw_uri": "%s", "size": 1, "metadata": { diff --git a/src/allmydata/upload.py b/src/allmydata/upload.py index 04cc9317d..c3dd29dfa 100644 --- a/src/allmydata/upload.py +++ b/src/allmydata/upload.py @@ -573,6 +573,7 @@ class UploadStatus: self.status = "Not started" self.progress = [0.0, 0.0, 0.0] self.active = True + self.results = None self.counter = self.statusid_counter.next() def get_storage_index(self): @@ -587,6 +588,8 @@ class UploadStatus: return tuple(self.progress) def get_active(self): return self.active + def get_results(self): + return self.results def get_counter(self): return self.counter @@ -603,6 +606,8 @@ class UploadStatus: self.progress[which] = value def set_active(self, value): self.active = value + def set_results(self, value): + self.results = value class CHKUploader: peer_selector_class = Tahoe2PeerSelector @@ -616,6 +621,7 @@ class CHKUploader: self._upload_status = UploadStatus() self._upload_status.set_helper(False) self._upload_status.set_active(True) + self._upload_status.set_results(self._results) def log(self, *args, **kwargs): if "parent" not in kwargs: @@ -776,6 +782,7 @@ class LiteralUploader: s.set_helper(False) s.set_progress(0, 1.0) s.set_active(False) + s.set_results(self._results) def start(self, uploadable): uploadable = IUploadable(uploadable) @@ -971,6 +978,7 @@ class AssistedUploader: return d self.log("helper says file is already uploaded") self._upload_status.set_progress(1, 1.0) + self._upload_status.set_results(upload_results) return upload_results def _build_readcap(self, upload_results): @@ -996,6 +1004,7 @@ class AssistedUploader: r.timings["helper_total"] = r.timings["total"] r.timings["total"] = now - self._started self._upload_status.set_status("Done") + self._upload_status.set_results(r) return r def get_upload_status(self): @@ -1200,5 +1209,8 @@ class Uploader(service.MultiService): def list_all_uploads(self): return self._all_uploads.keys() + def list_active_uploads(self): + return [u.get_upload_status() for u in self._all_uploads.keys() + if u.get_upload_status().get_active()] def list_recent_uploads(self): return self._recent_upload_status diff --git a/src/allmydata/web/unlinked-upload.xhtml b/src/allmydata/web/upload-results.xhtml similarity index 100% rename from src/allmydata/web/unlinked-upload.xhtml rename to src/allmydata/web/upload-results.xhtml diff --git a/src/allmydata/web/upload-status.xhtml b/src/allmydata/web/upload-status.xhtml index 10a6e08a4..1d8c7e0fd 100644 --- a/src/allmydata/web/upload-status.xhtml +++ b/src/allmydata/web/upload-status.xhtml @@ -20,6 +20,42 @@