webish: add per-file upload/download status pages
authorBrian Warner <warner@allmydata.com>
Sat, 1 Mar 2008 06:03:00 +0000 (23:03 -0700)
committerBrian Warner <warner@allmydata.com>
Sat, 1 Mar 2008 06:03:00 +0000 (23:03 -0700)
src/allmydata/test/test_web.py
src/allmydata/web/download-status.xhtml [new file with mode: 0644]
src/allmydata/web/upload-status.xhtml [new file with mode: 0644]
src/allmydata/webish.py

index 30dcadcf663880b81e9b4f969a3ef722e167dbcd..7f686d2bcaffca44a1914e61402439711fff4085 100644 (file)
@@ -32,6 +32,9 @@ class FakeClient(service.MultiService):
                 }
     introducer_furl = "None"
     introducer_client = FakeIntroducerClient()
+    _all_uploads = [upload.UploadStatus()]
+    _all_downloads = [download.DownloadStatus()]
+
     def connected_to_introducer(self):
         return False
 
@@ -68,14 +71,14 @@ class FakeClient(service.MultiService):
         return d
 
     def list_all_uploads(self):
-        return [upload.UploadStatus()]
+        return self._all_uploads
     def list_all_downloads(self):
-        return [download.DownloadStatus()]
+        return self._all_downloads
 
     def list_recent_uploads(self):
-        return [upload.UploadStatus()]
+        return self._all_uploads
     def list_recent_downloads(self):
-        return [download.DownloadStatus()]
+        return self._all_downloads
 
 
 class WebMixin(object):
@@ -380,10 +383,22 @@ class Web(WebMixin, unittest.TestCase):
         return d
 
     def test_status(self):
+        dl_num = self.s.list_recent_downloads()[0].get_counter()
+        ul_num = self.s.list_recent_uploads()[0].get_counter()
         d = self.GET("/status", followRedirect=True)
         def _check(res):
             self.failUnless('Upload and Download Status' in res)
+            self.failUnless('"down-%d"' % dl_num in res)
+            self.failUnless('"up-%d"' % ul_num in res)
         d.addCallback(_check)
+        d.addCallback(lambda res: self.GET("/status/down-%d" % dl_num))
+        def _check_dl(res):
+            self.failUnless("File Download Status" in res)
+        d.addCallback(_check_dl)
+        d.addCallback(lambda res: self.GET("/status/up-%d" % ul_num))
+        def _check_ul(res):
+            self.failUnless("File Upload Status" in res)
+        d.addCallback(_check_ul)
         return d
 
     def test_GET_FILEURL(self):
diff --git a/src/allmydata/web/download-status.xhtml b/src/allmydata/web/download-status.xhtml
new file mode 100644 (file)
index 0000000..b89a68b
--- /dev/null
@@ -0,0 +1,24 @@
+<html xmlns:n="http://nevow.com/ns/nevow/0.1">
+  <head>
+    <title>AllMyData - Tahoe - File Download Status</title>
+    <!-- <link href="http://www.allmydata.com/common/css/styles.css"
+          rel="stylesheet" type="text/css"/> -->
+    <link href="/webform_css" rel="stylesheet" type="text/css"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  </head>
+  <body>
+
+<h1>File Download Status</h1>
+
+<ul>
+  <li>Storage Index: <span n:render="si"/></li>
+  <li>Helper?: <span n:render="helper"/></li>
+  <li>Total Size: <span n:render="total_size"/></li>
+  <li>Progress: <span n:render="progress"/></li>
+  <li>Status: <span n:render="status"/></li>
+</ul>
+
+<div>Return to the <a href="/">Welcome Page</a></div>
+
+  </body>
+</html>
diff --git a/src/allmydata/web/upload-status.xhtml b/src/allmydata/web/upload-status.xhtml
new file mode 100644 (file)
index 0000000..10a6e08
--- /dev/null
@@ -0,0 +1,26 @@
+<html xmlns:n="http://nevow.com/ns/nevow/0.1">
+  <head>
+    <title>AllMyData - Tahoe - File Upload Status</title>
+    <!-- <link href="http://www.allmydata.com/common/css/styles.css"
+          rel="stylesheet" type="text/css"/> -->
+    <link href="/webform_css" rel="stylesheet" type="text/css"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  </head>
+  <body>
+
+<h1>File Upload Status</h1>
+
+<ul>
+  <li>Storage Index: <span n:render="si"/></li>
+  <li>Helper?: <span n:render="helper"/></li>
+  <li>Total Size: <span n:render="total_size"/></li>
+  <li>Progress (Hash): <span n:render="progress_hash"/></li>
+  <li>Progress (Ciphertext): <span n:render="progress_ciphertext"/></li>
+  <li>Progress (Encode+Push): <span n:render="progress_encode_push"/></li>
+  <li>Status: <span n:render="status"/></li>
+</ul>
+
+<div>Return to the <a href="/">Welcome Page</a></div>
+
+  </body>
+</html>
index 4359d7f2162c9945792353f2f949100b45e903cb..31192991df999108d4d21682a98ebd9e6e5cf3d2 100644 (file)
@@ -1608,6 +1608,70 @@ class UnlinkedPOSTCreateDirectory(rend.Page):
             d.addCallback(lambda dirnode: dirnode.get_uri())
         return d
 
+class UploadStatusPage(rend.Page):
+    docFactory = getxmlfile("upload-status.xhtml")
+
+    def render_si(self, ctx, data):
+        si_s = base32.b2a_or_none(data.get_storage_index())
+        if si_s is None:
+            si_s = "(None)"
+        return si_s
+
+    def render_helper(self, ctx, data):
+        return {True: "Yes",
+                False: "No"}[data.using_helper()]
+
+    def render_total_size(self, ctx, data):
+        size = data.get_size()
+        if size is None:
+            size = "(unknown)"
+        return size
+
+    def render_progress_hash(self, ctx, data):
+        progress = data.get_progress()[0]
+        # TODO: make an ascii-art bar
+        return "%.1f%%" % (100.0 * progress)
+
+    def render_progress_ciphertext(self, ctx, data):
+        progress = data.get_progress()[1]
+        # TODO: make an ascii-art bar
+        return "%.1f%%" % (100.0 * progress)
+
+    def render_progress_encode_push(self, ctx, data):
+        progress = data.get_progress()[2]
+        # TODO: make an ascii-art bar
+        return "%.1f%%" % (100.0 * progress)
+
+    def render_status(self, ctx, data):
+        return data.get_status()
+
+class DownloadStatusPage(rend.Page):
+    docFactory = getxmlfile("download-status.xhtml")
+
+    def render_si(self, ctx, data):
+        si_s = base32.b2a_or_none(data.get_storage_index())
+        if si_s is None:
+            si_s = "(None)"
+        return si_s
+
+    def render_helper(self, ctx, data):
+        return {True: "Yes",
+                False: "No"}[data.using_helper()]
+
+    def render_total_size(self, ctx, data):
+        size = data.get_size()
+        if size is None:
+            size = "(unknown)"
+        return size
+
+    def render_progress(self, ctx, data):
+        progress = data.get_progress()
+        # TODO: make an ascii-art bar
+        return "%.1f%%" % (100.0 * progress)
+
+    def render_status(self, ctx, data):
+        return data.get_status()
+
 class Status(rend.Page):
     docFactory = getxmlfile("status.xhtml")
     addSlash = True
@@ -1625,6 +1689,25 @@ class Status(rend.Page):
         return [d for d in IClient(ctx).list_recent_downloads()
                 if not d.get_active()]
 
+    def childFactory(self, ctx, name):
+        client = IClient(ctx)
+        stype,count_s = name.split("-")
+        count = int(count_s)
+        if stype == "up":
+            for s in client.list_recent_uploads():
+                if s.get_counter() == count:
+                    return UploadStatusPage(s)
+            for s in client.list_all_uploads():
+                if s.get_counter() == count:
+                    return UploadStatusPage(s)
+        if stype == "down":
+            for s in client.list_recent_downloads():
+                if s.get_counter() == count:
+                    return DownloadStatusPage(s)
+            for s in client.list_all_downloads():
+                if s.get_counter() == count:
+                    return DownloadStatusPage(s)
+
     def _render_common(self, ctx, data):
         s = data
         si_s = base32.b2a_or_none(s.get_storage_index())
@@ -1642,8 +1725,7 @@ class Status(rend.Page):
         else:
             assert IDownloadStatus.providedBy(data)
             link = "down-%d" % data.get_counter()
-        #ctx.fillSlots("status", T.a(href=link)[s.get_status()])
-        ctx.fillSlots("status", s.get_status())
+        ctx.fillSlots("status", T.a(href=link)[s.get_status()])
 
     def render_row_upload(self, ctx, data):
         self._render_common(ctx, data)