mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-31 00:24:13 +00:00
webish status: distinguish active uploads/downloads from recent ones
This commit is contained in:
parent
d4bf623b87
commit
301dd3d489
@ -336,6 +336,7 @@ class DownloadStatus:
|
|||||||
self.progress = 0.0
|
self.progress = 0.0
|
||||||
self.paused = False
|
self.paused = False
|
||||||
self.stopped = False
|
self.stopped = False
|
||||||
|
self.active = True
|
||||||
|
|
||||||
def get_storage_index(self):
|
def get_storage_index(self):
|
||||||
return self.storage_index
|
return self.storage_index
|
||||||
@ -352,6 +353,8 @@ class DownloadStatus:
|
|||||||
return status
|
return status
|
||||||
def get_progress(self):
|
def get_progress(self):
|
||||||
return self.progress
|
return self.progress
|
||||||
|
def get_active(self):
|
||||||
|
return self.active
|
||||||
|
|
||||||
def set_storage_index(self, si):
|
def set_storage_index(self, si):
|
||||||
self.storage_index = si
|
self.storage_index = si
|
||||||
@ -367,7 +370,8 @@ class DownloadStatus:
|
|||||||
self.stopped = stopped
|
self.stopped = stopped
|
||||||
def set_progress(self, value):
|
def set_progress(self, value):
|
||||||
self.progress = value
|
self.progress = value
|
||||||
|
def set_active(self, value):
|
||||||
|
self.active = value
|
||||||
|
|
||||||
class FileDownloader:
|
class FileDownloader:
|
||||||
implements(IPushProducer)
|
implements(IPushProducer)
|
||||||
@ -392,6 +396,7 @@ class FileDownloader:
|
|||||||
s.set_storage_index(self._storage_index)
|
s.set_storage_index(self._storage_index)
|
||||||
s.set_size(self._size)
|
s.set_size(self._size)
|
||||||
s.set_helper(False)
|
s.set_helper(False)
|
||||||
|
s.set_active(True)
|
||||||
|
|
||||||
if IConsumer.providedBy(downloadable):
|
if IConsumer.providedBy(downloadable):
|
||||||
downloadable.registerProducer(self, True)
|
downloadable.registerProducer(self, True)
|
||||||
@ -448,6 +453,7 @@ class FileDownloader:
|
|||||||
self._stopped = True
|
self._stopped = True
|
||||||
if self._status:
|
if self._status:
|
||||||
self._status.set_stopped(True)
|
self._status.set_stopped(True)
|
||||||
|
self._status.set_active(False)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.log("starting download")
|
self.log("starting download")
|
||||||
@ -465,6 +471,7 @@ class FileDownloader:
|
|||||||
def _finished(res):
|
def _finished(res):
|
||||||
if self._status:
|
if self._status:
|
||||||
self._status.set_status("Finished")
|
self._status.set_status("Finished")
|
||||||
|
self._status.set_active(False)
|
||||||
if IConsumer.providedBy(self._downloadable):
|
if IConsumer.providedBy(self._downloadable):
|
||||||
self._downloadable.unregisterProducer()
|
self._downloadable.unregisterProducer()
|
||||||
return res
|
return res
|
||||||
@ -472,6 +479,7 @@ class FileDownloader:
|
|||||||
def _failed(why):
|
def _failed(why):
|
||||||
if self._status:
|
if self._status:
|
||||||
self._status.set_status("Failed")
|
self._status.set_status("Failed")
|
||||||
|
self._status.set_active(False)
|
||||||
self._output.fail(why)
|
self._output.fail(why)
|
||||||
return why
|
return why
|
||||||
d.addErrback(_failed)
|
d.addErrback(_failed)
|
||||||
@ -809,6 +817,7 @@ class LiteralDownloader:
|
|||||||
s.set_storage_index(None)
|
s.set_storage_index(None)
|
||||||
s.set_helper(False)
|
s.set_helper(False)
|
||||||
s.set_status("Done")
|
s.set_status("Done")
|
||||||
|
s.set_active(False)
|
||||||
s.set_progress(1.0)
|
s.set_progress(1.0)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
|
@ -1420,6 +1420,8 @@ class IUploadStatus(Interface):
|
|||||||
process has finished: for helper uploads this is dependent upon the
|
process has finished: for helper uploads this is dependent upon the
|
||||||
helper providing progress reports. It might be reasonable to add all
|
helper providing progress reports. It might be reasonable to add all
|
||||||
three numbers and report the sum to the user."""
|
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):
|
class IDownloadStatus(Interface):
|
||||||
def get_storage_index():
|
def get_storage_index():
|
||||||
@ -1439,6 +1441,8 @@ class IDownloadStatus(Interface):
|
|||||||
"""Returns a float (from 0.0 to 1.0) describing the amount of the
|
"""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
|
download that has completed. This value will remain at 0.0 until the
|
||||||
first byte of plaintext is pushed to the download target."""
|
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):
|
class NotCapableError(Exception):
|
||||||
|
@ -377,7 +377,7 @@ class Web(WebMixin, unittest.TestCase):
|
|||||||
def test_status(self):
|
def test_status(self):
|
||||||
d = self.GET("/status")
|
d = self.GET("/status")
|
||||||
def _check(res):
|
def _check(res):
|
||||||
self.failUnless('Current Uploads and Downloads' in res)
|
self.failUnless('Upload and Download Status' in res)
|
||||||
d.addCallback(_check)
|
d.addCallback(_check)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
@ -568,6 +568,7 @@ class UploadStatus:
|
|||||||
self.helper = False
|
self.helper = False
|
||||||
self.status = "Not started"
|
self.status = "Not started"
|
||||||
self.progress = [0.0, 0.0, 0.0]
|
self.progress = [0.0, 0.0, 0.0]
|
||||||
|
self.active = True
|
||||||
|
|
||||||
def get_storage_index(self):
|
def get_storage_index(self):
|
||||||
return self.storage_index
|
return self.storage_index
|
||||||
@ -579,6 +580,8 @@ class UploadStatus:
|
|||||||
return self.status
|
return self.status
|
||||||
def get_progress(self):
|
def get_progress(self):
|
||||||
return tuple(self.progress)
|
return tuple(self.progress)
|
||||||
|
def get_active(self):
|
||||||
|
return self.active
|
||||||
|
|
||||||
def set_storage_index(self, si):
|
def set_storage_index(self, si):
|
||||||
self.storage_index = si
|
self.storage_index = si
|
||||||
@ -591,6 +594,8 @@ class UploadStatus:
|
|||||||
def set_progress(self, which, value):
|
def set_progress(self, which, value):
|
||||||
# [0]: chk, [1]: ciphertext, [2]: encode+push
|
# [0]: chk, [1]: ciphertext, [2]: encode+push
|
||||||
self.progress[which] = value
|
self.progress[which] = value
|
||||||
|
def set_active(self, value):
|
||||||
|
self.active = value
|
||||||
|
|
||||||
class CHKUploader:
|
class CHKUploader:
|
||||||
peer_selector_class = Tahoe2PeerSelector
|
peer_selector_class = Tahoe2PeerSelector
|
||||||
@ -603,6 +608,7 @@ class CHKUploader:
|
|||||||
self._storage_index = None
|
self._storage_index = None
|
||||||
self._upload_status = UploadStatus()
|
self._upload_status = UploadStatus()
|
||||||
self._upload_status.set_helper(False)
|
self._upload_status.set_helper(False)
|
||||||
|
self._upload_status.set_active(True)
|
||||||
|
|
||||||
def log(self, *args, **kwargs):
|
def log(self, *args, **kwargs):
|
||||||
if "parent" not in kwargs:
|
if "parent" not in kwargs:
|
||||||
@ -629,6 +635,10 @@ class CHKUploader:
|
|||||||
d1.addCallback(lambda key: self._compute_uri(res, key))
|
d1.addCallback(lambda key: self._compute_uri(res, key))
|
||||||
return d1
|
return d1
|
||||||
d.addCallback(_uploaded)
|
d.addCallback(_uploaded)
|
||||||
|
def _done(res):
|
||||||
|
self._upload_status.set_active(False)
|
||||||
|
return res
|
||||||
|
d.addBoth(_done)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def abort(self):
|
def abort(self):
|
||||||
@ -758,6 +768,7 @@ class LiteralUploader:
|
|||||||
s.set_storage_index(None)
|
s.set_storage_index(None)
|
||||||
s.set_helper(False)
|
s.set_helper(False)
|
||||||
s.set_progress(0, 1.0)
|
s.set_progress(0, 1.0)
|
||||||
|
s.set_active(False)
|
||||||
|
|
||||||
def start(self, uploadable):
|
def start(self, uploadable):
|
||||||
uploadable = IUploadable(uploadable)
|
uploadable = IUploadable(uploadable)
|
||||||
@ -874,6 +885,7 @@ class AssistedUploader:
|
|||||||
self._storage_index = None
|
self._storage_index = None
|
||||||
self._upload_status = s = UploadStatus()
|
self._upload_status = s = UploadStatus()
|
||||||
s.set_helper(True)
|
s.set_helper(True)
|
||||||
|
s.set_active(True)
|
||||||
|
|
||||||
def log(self, msg, parent=None, **kwargs):
|
def log(self, msg, parent=None, **kwargs):
|
||||||
if parent is None:
|
if parent is None:
|
||||||
@ -900,6 +912,10 @@ class AssistedUploader:
|
|||||||
d.addCallback(self._got_storage_index)
|
d.addCallback(self._got_storage_index)
|
||||||
d.addCallback(self._contact_helper)
|
d.addCallback(self._contact_helper)
|
||||||
d.addCallback(self._build_readcap)
|
d.addCallback(self._build_readcap)
|
||||||
|
def _done(res):
|
||||||
|
self._upload_status.set_active(False)
|
||||||
|
return res
|
||||||
|
d.addBoth(_done)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def _got_size(self, size):
|
def _got_size(self, size):
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<h1>Current Uploads and Downloads</h1>
|
<h1>Upload and Download Status</h1>
|
||||||
|
|
||||||
|
|
||||||
<h2>Current Uploads:</h2>
|
<h2>Active Uploads:</h2>
|
||||||
<table n:render="sequence" n:data="uploads" border="1">
|
<table n:render="sequence" n:data="active_uploads" border="1">
|
||||||
<tr n:pattern="header">
|
<tr n:pattern="header">
|
||||||
<td>Storage Index</td>
|
<td>Storage Index</td>
|
||||||
<td>Helper?</td>
|
<td>Helper?</td>
|
||||||
@ -31,11 +31,11 @@
|
|||||||
<td><n:slot name="progress_encode"/></td>
|
<td><n:slot name="progress_encode"/></td>
|
||||||
<td><n:slot name="status"/></td>
|
<td><n:slot name="status"/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr n:pattern="empty"><td>No current uploads!</td></tr>
|
<tr n:pattern="empty"><td>No active uploads!</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h2>Current Downloads:</h2>
|
<h2>Active Downloads:</h2>
|
||||||
<table n:render="sequence" n:data="downloads" border="1">
|
<table n:render="sequence" n:data="active_downloads" border="1">
|
||||||
<tr n:pattern="header">
|
<tr n:pattern="header">
|
||||||
<td>Storage Index</td>
|
<td>Storage Index</td>
|
||||||
<td>Helper?</td>
|
<td>Helper?</td>
|
||||||
@ -50,7 +50,50 @@
|
|||||||
<td><n:slot name="progress"/></td>
|
<td><n:slot name="progress"/></td>
|
||||||
<td><n:slot name="status"/></td>
|
<td><n:slot name="status"/></td>
|
||||||
</tr>
|
</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>
|
</table>
|
||||||
|
|
||||||
<div>Return to the <a href="/">Welcome Page</a></div>
|
<div>Return to the <a href="/">Welcome Page</a></div>
|
||||||
|
@ -1567,11 +1567,14 @@ class UnlinkedPOSTCreateDirectory(rend.Page):
|
|||||||
class Status(rend.Page):
|
class Status(rend.Page):
|
||||||
docFactory = getxmlfile("status.xhtml")
|
docFactory = getxmlfile("status.xhtml")
|
||||||
|
|
||||||
def data_uploads(self, ctx, data):
|
def data_active_uploads(self, ctx, data):
|
||||||
return IClient(ctx).list_uploads()
|
return [u for u in IClient(ctx).list_uploads() if u.get_active()]
|
||||||
|
def data_active_downloads(self, ctx, data):
|
||||||
def data_downloads(self, ctx, data):
|
return [d for d in IClient(ctx).list_downloads() if d.get_active()]
|
||||||
return IClient(ctx).list_downloads()
|
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):
|
def _render_common(self, ctx, data):
|
||||||
s = data
|
s = data
|
||||||
|
Loading…
x
Reference in New Issue
Block a user