From ca1a1762e2bf4a77d792d290043286101b3a8e8a Mon Sep 17 00:00:00 2001
From: Brian Warner <warner@allmydata.com>
Date: Tue, 4 Mar 2008 18:50:44 -0700
Subject: [PATCH] web: status: add 'started' timestamps to all operations

---
 src/allmydata/download.py               |  3 +++
 src/allmydata/interfaces.py             |  6 +++++
 src/allmydata/mutable.py                |  6 +++++
 src/allmydata/upload.py                 |  3 +++
 src/allmydata/web/download-status.xhtml |  1 +
 src/allmydata/web/publish-status.xhtml  |  1 +
 src/allmydata/web/retrieve-status.xhtml |  1 +
 src/allmydata/web/status.xhtml          |  2 ++
 src/allmydata/web/upload-status.xhtml   |  1 +
 src/allmydata/webish.py                 | 32 +++++++++++++++++++++++++
 10 files changed, 56 insertions(+)

diff --git a/src/allmydata/download.py b/src/allmydata/download.py
index 53b268e7..66c399c5 100644
--- a/src/allmydata/download.py
+++ b/src/allmydata/download.py
@@ -364,7 +364,10 @@ class DownloadStatus:
         self.active = True
         self.results = None
         self.counter = self.statusid_counter.next()
+        self.started = time.time()
 
+    def get_started(self):
+        return self.started
     def get_storage_index(self):
         return self.storage_index
     def get_size(self):
diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py
index b9ff96f4..91757856 100644
--- a/src/allmydata/interfaces.py
+++ b/src/allmydata/interfaces.py
@@ -1453,6 +1453,9 @@ class IClientStatus(Interface):
         started downloads."""
 
 class IUploadStatus(Interface):
+    def get_started():
+        """Return a timestamp (float with seconds since epoch) indicating
+        when the operation was started."""
     def get_storage_index():
         """Return a string with the (binary) storage index in use on this
         upload. Returns None if the storage index has not yet been
@@ -1489,6 +1492,9 @@ class IUploadStatus(Interface):
         page can generate a suitable hyperlink."""
 
 class IDownloadStatus(Interface):
+    def get_started():
+        """Return a timestamp (float with seconds since epoch) indicating
+        when the operation was started."""
     def get_storage_index():
         """Return a string with the (binary) storage index in use on this
         download. This may be None if there is no storage index (i.e. LIT
diff --git a/src/allmydata/mutable.py b/src/allmydata/mutable.py
index 925a286a..f983d3b7 100644
--- a/src/allmydata/mutable.py
+++ b/src/allmydata/mutable.py
@@ -211,7 +211,10 @@ class RetrieveStatus:
         self.status = "Not started"
         self.progress = 0.0
         self.counter = self.statusid_counter.next()
+        self.started = time.time()
 
+    def get_started(self):
+        return self.started
     def get_storage_index(self):
         return self.storage_index
     def using_helper(self):
@@ -783,7 +786,10 @@ class PublishStatus:
         self.status = "Not started"
         self.progress = 0.0
         self.counter = self.statusid_counter.next()
+        self.started = time.time()
 
+    def get_started(self):
+        return self.started
     def get_storage_index(self):
         return self.storage_index
     def using_helper(self):
diff --git a/src/allmydata/upload.py b/src/allmydata/upload.py
index c3dd29df..015a74a5 100644
--- a/src/allmydata/upload.py
+++ b/src/allmydata/upload.py
@@ -575,7 +575,10 @@ class UploadStatus:
         self.active = True
         self.results = None
         self.counter = self.statusid_counter.next()
+        self.started = time.time()
 
+    def get_started(self):
+        return self.started
     def get_storage_index(self):
         return self.storage_index
     def get_size(self):
diff --git a/src/allmydata/web/download-status.xhtml b/src/allmydata/web/download-status.xhtml
index 5e563acf..5a3d47e2 100644
--- a/src/allmydata/web/download-status.xhtml
+++ b/src/allmydata/web/download-status.xhtml
@@ -11,6 +11,7 @@
 <h1>File Download Status</h1>
 
 <ul>
+  <li>Started: <span n:render="started"/></li>
   <li>Storage Index: <span n:render="si"/></li>
   <li>Helper?: <span n:render="helper"/></li>
   <li>Total Size: <span n:render="total_size"/></li>
diff --git a/src/allmydata/web/publish-status.xhtml b/src/allmydata/web/publish-status.xhtml
index 657bde3c..f6b862c3 100644
--- a/src/allmydata/web/publish-status.xhtml
+++ b/src/allmydata/web/publish-status.xhtml
@@ -11,6 +11,7 @@
 <h1>Mutable File Publish Status</h1>
 
 <ul>
+  <li>Started: <span n:render="started"/></li>
   <li>Storage Index: <span n:render="si"/></li>
   <li>Helper?: <span n:render="helper"/></li>
   <li>Current Size: <span n:render="current_size"/></li>
diff --git a/src/allmydata/web/retrieve-status.xhtml b/src/allmydata/web/retrieve-status.xhtml
index 1d2bb554..422cdcd8 100644
--- a/src/allmydata/web/retrieve-status.xhtml
+++ b/src/allmydata/web/retrieve-status.xhtml
@@ -11,6 +11,7 @@
 <h1>Mutable File Retrieve Status</h1>
 
 <ul>
+  <li>Started: <span n:render="started"/></li>
   <li>Storage Index: <span n:render="si"/></li>
   <li>Helper?: <span n:render="helper"/></li>
   <li>Current Size: <span n:render="current_size"/></li>
diff --git a/src/allmydata/web/status.xhtml b/src/allmydata/web/status.xhtml
index f0a24247..4c478b97 100644
--- a/src/allmydata/web/status.xhtml
+++ b/src/allmydata/web/status.xhtml
@@ -36,6 +36,7 @@
 <h2>Recent Operations:</h2>
 <table n:render="sequence" n:data="recent_operations" border="1">
   <tr n:pattern="header">
+    <td>Started</td>
     <td>Type</td>
     <td>Storage Index</td>
     <td>Helper?</td>
@@ -44,6 +45,7 @@
     <td>Status</td>
   </tr>
   <tr n:pattern="item" n:render="row">
+    <td><n:slot name="started"/></td>
     <td><n:slot name="type"/></td>
     <td><n:slot name="si"/></td>
     <td><n:slot name="helper"/></td>
diff --git a/src/allmydata/web/upload-status.xhtml b/src/allmydata/web/upload-status.xhtml
index 1d8c7e0f..90e676ff 100644
--- a/src/allmydata/web/upload-status.xhtml
+++ b/src/allmydata/web/upload-status.xhtml
@@ -11,6 +11,7 @@
 <h1>File Upload Status</h1>
 
 <ul>
+  <li>Started: <span n:render="started"/></li>
   <li>Storage Index: <span n:render="si"/></li>
   <li>Helper?: <span n:render="helper"/></li>
   <li>Total Size: <span n:render="total_size"/></li>
diff --git a/src/allmydata/webish.py b/src/allmydata/webish.py
index bdbce443..bae3d7d1 100644
--- a/src/allmydata/webish.py
+++ b/src/allmydata/webish.py
@@ -1638,6 +1638,12 @@ class UploadStatusPage(UploadResultsRendererMixin, rend.Page):
         d.addCallback(_got_results)
         return d
 
+    def render_started(self, ctx, data):
+        TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
+        started_s = time.strftime(TIME_FORMAT,
+                                  time.localtime(data.get_started()))
+        return started_s
+
     def render_si(self, ctx, data):
         si_s = base32.b2a_or_none(data.get_storage_index())
         if si_s is None:
@@ -1841,6 +1847,12 @@ class DownloadStatusPage(DownloadResultsRendererMixin, rend.Page):
         d.addCallback(_got_results)
         return d
 
+    def render_started(self, ctx, data):
+        TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
+        started_s = time.strftime(TIME_FORMAT,
+                                  time.localtime(data.get_started()))
+        return started_s
+
     def render_si(self, ctx, data):
         si_s = base32.b2a_or_none(data.get_storage_index())
         if si_s is None:
@@ -1868,6 +1880,12 @@ class DownloadStatusPage(DownloadResultsRendererMixin, rend.Page):
 class RetrieveStatusPage(rend.Page):
     docFactory = getxmlfile("retrieve-status.xhtml")
 
+    def render_started(self, ctx, data):
+        TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
+        started_s = time.strftime(TIME_FORMAT,
+                                  time.localtime(data.get_started()))
+        return started_s
+
     def render_si(self, ctx, data):
         si_s = base32.b2a_or_none(data.get_storage_index())
         if si_s is None:
@@ -1895,6 +1913,12 @@ class RetrieveStatusPage(rend.Page):
 class PublishStatusPage(rend.Page):
     docFactory = getxmlfile("publish-status.xhtml")
 
+    def render_started(self, ctx, data):
+        TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
+        started_s = time.strftime(TIME_FORMAT,
+                                  time.localtime(data.get_started()))
+        return started_s
+
     def render_si(self, ctx, data):
         si_s = base32.b2a_or_none(data.get_storage_index())
         if si_s is None:
@@ -1936,10 +1960,18 @@ class Status(rend.Page):
                             IClient(ctx).list_recent_publish() +
                             IClient(ctx).list_recent_retrieve())
                   if not o.get_active()]
+        recent.sort(lambda a,b: cmp(a.get_started(), b.get_started()))
+        recent.reverse()
         return recent
 
     def render_row(self, ctx, data):
         s = data
+
+        TIME_FORMAT = "%H:%M:%S %d-%b-%Y"
+        started_s = time.strftime(TIME_FORMAT,
+                                  time.localtime(s.get_started()))
+        ctx.fillSlots("started", started_s)
+
         si_s = base32.b2a_or_none(s.get_storage_index())
         if si_s is None:
             si_s = "(None)"
-- 
2.45.2