self.progress = 0.0
self.paused = False
self.stopped = False
+ self.active = True
def get_storage_index(self):
return self.storage_index
return status
def get_progress(self):
return self.progress
+ def get_active(self):
+ return self.active
def set_storage_index(self, si):
self.storage_index = si
self.stopped = stopped
def set_progress(self, value):
self.progress = value
-
+ def set_active(self, value):
+ self.active = value
class FileDownloader:
implements(IPushProducer)
s.set_storage_index(self._storage_index)
s.set_size(self._size)
s.set_helper(False)
+ s.set_active(True)
if IConsumer.providedBy(downloadable):
downloadable.registerProducer(self, True)
self._stopped = True
if self._status:
self._status.set_stopped(True)
+ self._status.set_active(False)
def start(self):
self.log("starting download")
def _finished(res):
if self._status:
self._status.set_status("Finished")
+ self._status.set_active(False)
if IConsumer.providedBy(self._downloadable):
self._downloadable.unregisterProducer()
return res
def _failed(why):
if self._status:
self._status.set_status("Failed")
+ self._status.set_active(False)
self._output.fail(why)
return why
d.addErrback(_failed)
s.set_storage_index(None)
s.set_helper(False)
s.set_status("Done")
+ s.set_active(False)
s.set_progress(1.0)
def start(self):
process has finished: for helper uploads this is dependent upon the
helper providing progress reports. It might be reasonable to add all
three numbers and report the sum to the user."""
+ def get_active():
+ """Return True if the upload is currently active, False if not."""
class IDownloadStatus(Interface):
def get_storage_index():
"""Returns a float (from 0.0 to 1.0) describing the amount of the
download that has completed. This value will remain at 0.0 until the
first byte of plaintext is pushed to the download target."""
+ def get_active():
+ """Return True if the download is currently active, False if not."""
class NotCapableError(Exception):
def test_status(self):
d = self.GET("/status")
def _check(res):
- self.failUnless('Current Uploads and Downloads' in res)
+ self.failUnless('Upload and Download Status' in res)
d.addCallback(_check)
return d
self.helper = False
self.status = "Not started"
self.progress = [0.0, 0.0, 0.0]
+ self.active = True
def get_storage_index(self):
return self.storage_index
return self.status
def get_progress(self):
return tuple(self.progress)
+ def get_active(self):
+ return self.active
def set_storage_index(self, si):
self.storage_index = si
def set_progress(self, which, value):
# [0]: chk, [1]: ciphertext, [2]: encode+push
self.progress[which] = value
+ def set_active(self, value):
+ self.active = value
class CHKUploader:
peer_selector_class = Tahoe2PeerSelector
self._storage_index = None
self._upload_status = UploadStatus()
self._upload_status.set_helper(False)
+ self._upload_status.set_active(True)
def log(self, *args, **kwargs):
if "parent" not in kwargs:
d1.addCallback(lambda key: self._compute_uri(res, key))
return d1
d.addCallback(_uploaded)
+ def _done(res):
+ self._upload_status.set_active(False)
+ return res
+ d.addBoth(_done)
return d
def abort(self):
s.set_storage_index(None)
s.set_helper(False)
s.set_progress(0, 1.0)
+ s.set_active(False)
def start(self, uploadable):
uploadable = IUploadable(uploadable)
self._storage_index = None
self._upload_status = s = UploadStatus()
s.set_helper(True)
+ s.set_active(True)
def log(self, msg, parent=None, **kwargs):
if parent is None:
d.addCallback(self._got_storage_index)
d.addCallback(self._contact_helper)
d.addCallback(self._build_readcap)
+ def _done(res):
+ self._upload_status.set_active(False)
+ return res
+ d.addBoth(_done)
return d
def _got_size(self, size):
</head>
<body>
-<h1>Current Uploads and Downloads</h1>
+<h1>Upload and Download Status</h1>
-<h2>Current Uploads:</h2>
-<table n:render="sequence" n:data="uploads" border="1">
+<h2>Active Uploads:</h2>
+<table n:render="sequence" n:data="active_uploads" border="1">
<tr n:pattern="header">
<td>Storage Index</td>
<td>Helper?</td>
<td><n:slot name="progress_encode"/></td>
<td><n:slot name="status"/></td>
</tr>
- <tr n:pattern="empty"><td>No current uploads!</td></tr>
+ <tr n:pattern="empty"><td>No active uploads!</td></tr>
</table>
-<h2>Current Downloads:</h2>
-<table n:render="sequence" n:data="downloads" border="1">
+<h2>Active Downloads:</h2>
+<table n:render="sequence" n:data="active_downloads" border="1">
<tr n:pattern="header">
<td>Storage Index</td>
<td>Helper?</td>
<td><n:slot name="progress"/></td>
<td><n:slot name="status"/></td>
</tr>
- <tr n:pattern="empty"><td>No current downloads!</td></tr>
+ <tr n:pattern="empty"><td>No active downloads!</td></tr>
+</table>
+
+
+<h2>Recent Uploads:</h2>
+<table n:render="sequence" n:data="recent_uploads" border="1">
+ <tr n:pattern="header">
+ <td>Storage Index</td>
+ <td>Helper?</td>
+ <td>Total Size</td>
+ <td>Progress (Hash)</td>
+ <td>Progress (Ciphertext)</td>
+ <td>Progress (Encode+Push)</td>
+ <td>Status</td>
+ </tr>
+ <tr n:pattern="item" n:render="row_upload">
+ <td><n:slot name="si"/></td>
+ <td><n:slot name="helper"/></td>
+ <td><n:slot name="total_size"/></td>
+ <td><n:slot name="progress_hash"/></td>
+ <td><n:slot name="progress_ciphertext"/></td>
+ <td><n:slot name="progress_encode"/></td>
+ <td><n:slot name="status"/></td>
+ </tr>
+ <tr n:pattern="empty"><td>No recent uploads!</td></tr>
+</table>
+
+<h2>Recent Downloads:</h2>
+<table n:render="sequence" n:data="recent_downloads" border="1">
+ <tr n:pattern="header">
+ <td>Storage Index</td>
+ <td>Helper?</td>
+ <td>Total Size</td>
+ <td>Progress</td>
+ <td>Status</td>
+ </tr>
+ <tr n:pattern="item" n:render="row_download">
+ <td><n:slot name="si"/></td>
+ <td><n:slot name="helper"/></td>
+ <td><n:slot name="total_size"/></td>
+ <td><n:slot name="progress"/></td>
+ <td><n:slot name="status"/></td>
+ </tr>
+ <tr n:pattern="empty"><td>No recent downloads!</td></tr>
</table>
<div>Return to the <a href="/">Welcome Page</a></div>
class Status(rend.Page):
docFactory = getxmlfile("status.xhtml")
- def data_uploads(self, ctx, data):
- return IClient(ctx).list_uploads()
-
- def data_downloads(self, ctx, data):
- return IClient(ctx).list_downloads()
+ def data_active_uploads(self, ctx, data):
+ return [u for u in IClient(ctx).list_uploads() if u.get_active()]
+ def data_active_downloads(self, ctx, data):
+ return [d for d in IClient(ctx).list_downloads() if d.get_active()]
+ def data_recent_uploads(self, ctx, data):
+ return [u for u in IClient(ctx).list_uploads() if not u.get_active()]
+ def data_recent_downloads(self, ctx, data):
+ return [d for d in IClient(ctx).list_downloads() if not d.get_active()]
def _render_common(self, ctx, data):
s = data