[Git][NTPsec/ntpsec][master] ntpviz: use the Python csv module. Write tmp files instead of live ones

Gary E. Miller gitlab at mg.gitlab.com
Tue Oct 18 01:28:53 UTC 2016


Gary E. Miller pushed to branch master at NTPsec / ntpsec


Commits:
c3d6678e by Gary E. Miller at 2016-10-17T18:24:06-07:00
ntpviz: use the Python csv module. Write tmp files instead of live ones

The Python csv module is clearly less efficient, but will guard against
the csv file format breaking RFC4180.  Also, write index.html and
summary.csv to tmp files, then move them into place.  This prevents
clients reading partial files.  The plot files still have this
problem.

- - - - -


1 changed file:

- ntpstats/ntpviz


Changes:

=====================================
ntpstats/ntpviz
=====================================
--- a/ntpstats/ntpviz
+++ b/ntpstats/ntpviz
@@ -24,6 +24,7 @@ Python by ESR, concept and GNUPLOT code by Dan Drown.
 from __future__ import print_function, division
 
 import argparse
+import csv
 import re
 import atexit, binascii, collections, os, socket, sys, time
 from ntp.statfiles import *
@@ -93,10 +94,9 @@ class VizStats(NTPStats):
     multiplier  = 1
 
     # observe RFC 4180, end lines with CRLF
-    csv_head =  """\
-Name, Min, 1%, 5%, 50%, 95%, 99%, Max,, 90% Range, 98% Range, StdDev, , \
-Mean, Units\r
-"""
+    csv_head =  [
+            "Name", "Min", "1%", "5%", "50%", "95%", "99%", "Max", "",
+            "90% Range", "98% Range", "StdDev", "", "Mean", "Units"]
 
     table_head =  """\
 <table style="text-align:right;">
@@ -233,18 +233,20 @@ Mean, Units\r
 </table>
 """ % self.percs_f
 
-        s =  """\
-%(title)s, %(p0)s, %(p1)s, %(p5)s, %(p50)s, %(p95)s, %(p99)s, %(p100)s, , \
- %(r90)s, %(r98)s, %(pstd)s, , %(mu)s, %(unit)s\
-"""
+        s =  ["%(title)s", "%(p0)s", "%(p1)s", "%(p5)s", "%(p50)s", "%(p95)s",
+              " %(p99)s", "%(p100)s", "", "%(r90)s", "%(r98)s", "%(pstd)s",
+              "", "%(mu)s", "%(unit)s"]
 
-        self.csv   =  s % self.percs + '\r\n'    # RFC4180 says CRLF
-        self.table =  s % self.percs_f + '\n'
+        # csv is raw, html table is autoranged
+        self.csv   =  [ x % self.percs for x in s]
+        self.table =  [ x % self.percs_f for x in s]
+        self.table = "</td><td>".join(self.table)
 
-        self.table = '<tr style="vertical-align:top;">' + \
-                     '<td style="text-align:left;">' + \
-                            self.table.replace( ", ", "</td><td>") + \
-                           "</td></tr>\n"
+        self.table = '''\
+<tr style="vertical-align:top;">
+ <td style="text-align:left;">%s</td>
+</tr>
+''' % self.table
 
         return
 
@@ -1445,7 +1447,7 @@ ntpviz</a>, part of the <a href="https://www.ntpsec.org/">NTPsec project</a>
             index_buffer += "</div>\n"
 
     # dump stats
-    csvs = ''
+    csvs = []
     if True:
         index_buffer += '<div id="Summary"><h2>Summary</h2>\n'
         index_buffer += VizStats.table_head
@@ -1454,13 +1456,13 @@ ntpviz</a>, part of the <a href="https://www.ntpsec.org/">NTPsec project</a>
                 continue;
             for sta in stat:
                 index_buffer += str( sta.table )
-                csvs += sta.csv
+                csvs.append(sta.csv)
         # RFC4180 specifies the mime-type of a csv
         # your webserver should be programmed the same
         index_buffer += """\
 </table>
 <a href="summary.csv" target="_blank" 
-  type="text/csv; charset=UTF-8; header=present;">Summary as CSV file</a><br>
+  type="text/csv;charset=UTF-8;header=present;">Summary as CSV file</a><br>
 </div>
 """
 
@@ -1476,14 +1478,21 @@ ntpviz</a>, part of the <a href="https://www.ntpsec.org/">NTPsec project</a>
     index_buffer += index_trailer
 
     # and send the file buffer
-    with open(os.path.join(args.outdir, "index.html"), "w") as ifile:
+    index_filename = os.path.join(args.outdir, "index.html")
+    with open(index_filename + ".tmp", "wb") as ifile:
         ifile.write(index_buffer)
 
-    # create csv file
+    # create csv file, as a tmp file
     csv_filename = os.path.join(args.outdir, "summary.csv")
-    with open( csv_filename, "w" ) as csv_file:
-        csv_file.write(VizStats.csv_head)
-        csv_file.write(csvs)
+    with open( csv_filename + ".tmp", "wb" ) as csv_file:
+        csv_ob = csv.writer(csv_file)
+        csv_ob.writerow(VizStats.csv_head)
+        for row in csvs:
+            csv_ob.writerow(row)
+
+    # move new index and summary into place
+    os.rename( csv_filename + ".tmp", csv_filename)
+    os.rename( index_filename + ".tmp", index_filename)
 
 
 # end



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/c3d6678e0cab2260466f8ebdca26f072e1355740
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ntpsec.org/pipermail/vc/attachments/20161018/43edb04c/attachment.html>


More information about the vc mailing list