[Piuparts-commits] rev 216 - in trunk: . debian

Holger Levsen holger at alioth.debian.org
Wed Mar 11 17:48:30 UTC 2009


Author: holger
Date: 2009-03-11 17:48:30 +0000 (Wed, 11 Mar 2009)
New Revision: 216

Added:
   trunk/piuparts-report.conf.sample
   trunk/piuparts-report.py
Modified:
   trunk/Makefile
   trunk/debian/changelog
Log:
Re-add piuparts-reports.py which got removed/lost between 0.14 and 0.20 
without changelog entry.

(unmodified version 0.14-1 from ubuntus dapper universe)

Modified: trunk/Makefile
===================================================================
--- trunk/Makefile	2009-03-11 16:54:53 UTC (rev 215)
+++ trunk/Makefile	2009-03-11 17:48:30 UTC (rev 216)
@@ -29,7 +29,7 @@
 	gzip -9f $(man1dir)/piuparts.1
 
 	install -d $(sharedir)/piuparts
-	for file in piuparts-slave piuparts-master; do \
+	for file in piuparts-slave piuparts-master piuparts-report; do \
 	    sed "/^CONFIG_FILE = /s:\".*\":\"/etc/piuparts/$$file.conf\":" \
 	        $$file.py > $(sharedir)/piuparts/$$file.py; done
 	install piuparts-analyze.py $(sharedir)/piuparts/piuparts-analyze
@@ -41,7 +41,7 @@
 	install -m 0644 piupartslib/*.py $(site25)/piupartslib
 
 	install -d $(etcdir)/piuparts
-	for x in master slave; do \
+	for x in master slave reports; do \
 	    install -m 0644 piuparts-$$x.conf.sample \
 	                    $(etcdir)/piuparts/piuparts-$$x.conf; done
 

Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog	2009-03-11 16:54:53 UTC (rev 215)
+++ trunk/debian/changelog	2009-03-11 17:48:30 UTC (rev 216)
@@ -4,6 +4,8 @@
   * Copy scriptsdir to chroot also when doing upgrade tests.
   * Ignore modifications of /var/lib/dpkg/triggers/*
   * Do not install recommends and suggests.
+  * Re-add piuparts-reports.py which got removed/lost between 0.14 and 0.20 
+    without changelog entry.
 
  -- Holger Levsen <holger at debian.org>  Tue, 10 Mar 2009 15:23:59 +0100
 

Added: trunk/piuparts-report.conf.sample
===================================================================
--- trunk/piuparts-report.conf.sample	                        (rev 0)
+++ trunk/piuparts-report.conf.sample	2009-03-11 17:48:30 UTC (rev 216)
@@ -0,0 +1,10 @@
+#
+# This is the configuration file for piuparts-report, the HTML report
+# creation portion of the distributed piuparts system.
+#
+# Lars Wirzenius <liw at iki.fi>
+#
+
+[report]
+output-dir = html
+index-page = index.html

Added: trunk/piuparts-report.py
===================================================================
--- trunk/piuparts-report.py	                        (rev 0)
+++ trunk/piuparts-report.py	2009-03-11 17:48:30 UTC (rev 216)
@@ -0,0 +1,330 @@
+#!/usr/bin/python
+#
+# Copyright 2005 Lars Wirzenius (liw at iki.fi)
+# 
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+# 
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+"""Create HTML reports of piuparts log files
+
+Lars Wirzenius <liw at iki.fi>
+"""
+
+
+import os
+import sys
+import time
+import logging
+import ConfigParser
+import urllib
+import shutil
+
+
+import piupartslib
+
+
+CONFIG_FILE = "piuparts-report.conf"
+
+
+LOG_LIST_PAGE_TEMPLATE = """
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html 
+     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+    <title>%(title)s</title>
+    <link rel="stylesheet" href="piuparts.css" type="text/css"/>
+</head>
+<body>
+<div class="main">
+<h1>%(title)s</h1>
+<p>%(preface)s</p>
+<p>The list has %(count)d packages, with %(versioncount)s total versions.
+This page was generated: %(time)s.</p>
+<ul>
+%(loglist)s
+</ul>
+</div>
+</body>
+</html>
+"""
+
+
+STATS_PAGE_TEMPLATE = """
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html 
+     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+    <title>Statistics of packages</title>
+    <link rel="stylesheet" href="piuparts.css" type="text/css"/>
+</head>
+<body>
+<div class="main">
+<h1>Statistics of packages</h1>
+<p>This page contains some statistics about packages piuparts is looking
+at.</p>
+%(table)s
+</div>
+</body>
+</html>
+"""
+
+
+STATE_PAGE_TEMPLATE = """
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html 
+     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+    <title>%(state)s</title>
+    <link rel="stylesheet" href="piuparts.css" type="text/css"/>
+</head>
+<body>
+<div class="main">
+<h1>Packages in state "%(state)s"</h1>
+<p>This page contains a list of package in state "%(state)s".</p>
+%(list)s
+</div>
+</body>
+</html>
+"""
+
+
+title_by_dir = {
+    "pass": "PASSED piuparts logs",
+    "fail": "Failed UNREPORTED piuparts logs",
+    "bugged": "Failed REPORTED piuparts logs",
+    "fixed": "Failed and FIXED packages",
+    "reserved": "RESERVED packages",
+    "untestable": "UNTESTABLE packages",
+}
+
+
+desc_by_dir = {
+    "pass": "Log files for packages that have PASSED testing.",
+    "fail": "Log files for packages that have FAILED testing. " +
+            "Bugs have not yet been reported.",
+    "bugged": "Log files for packages that have FAILED testing. " +
+              "Bugs have been reported, but not yet fixed.",
+    "fixed": "Log files for packages that have FAILED testing, but for " +
+             "which a fix has been made.",
+    "reserved": "Packages that are RESERVED for testing on a node in a " +
+                "distributed piuparts network.",
+    "untestable": "Log files for packages that have are UNTESTABLE with " +
+                  "piuparts at the current time.",
+}
+
+
+class Config(piupartslib.conf.Config):
+
+    def __init__(self):
+        piupartslib.conf.Config.__init__(self, "report",
+            {
+                "output-dir": "html",
+                "index-page": "index.html",
+                "packages-url": None,
+            },
+            ["output-dir", "packages-url"])
+
+
+def setup_logging(log_level, log_file_name):
+    logger = logging.getLogger()
+    logger.setLevel(log_level)
+
+    formatter = logging.Formatter(fmt="%(asctime)s %(message)s",
+                                  datefmt="%H:%M")
+
+    handler = logging.StreamHandler(sys.stderr)
+    handler.setFormatter(formatter)
+    logger.addHandler(handler)
+    
+    if log_file_name:
+        handler = logging.FileHandler(log_file_name)
+        logger.addHandler(handler)
+
+
+def html_protect(str):
+    str = "&amp;".join(str.split("&"))
+    str = "&lt;".join(str.split("<"))
+    str = "&gt;".join(str.split(">"))
+    str = "&#34;".join(str.split('"'))
+    str = "&#39;".join(str.split("'"))
+    return str
+
+
+def write_log_list_page(filename, title, preface, logs):
+    packages = {}
+    for pathname, package, version in logs:
+        packages[package] = packages.get(package, []) + [(pathname, version)]
+
+    names = packages.keys()
+    names.sort()
+    lines = []
+    version_count = 0
+    for package in names:
+        versions = []
+        for pathname, version in packages[package]:
+            version_count += 1
+            versions.append("<a href='%s'>%s</a>" % 
+                            (html_protect(pathname), 
+                             html_protect(version)))
+        line = "<li>%s %s</li>\n" % (html_protect(package), 
+                                     ", ".join(versions))
+        lines.append(line)
+
+    f = file(filename, "w")
+    f.write(LOG_LIST_PAGE_TEMPLATE % 
+            {
+                "title": html_protect(title),
+                "preface": preface,
+                "loglist": "".join(lines),
+                "count": len(logs),
+                "versioncount": version_count,
+                "time": time.strftime("%Y-%m-%d %H:%M:%S %z"),
+            })
+    f.close()
+
+
+def print_by_dir(config, logs_by_dir):
+    for dir in logs_by_dir:
+        list = []
+        for basename in logs_by_dir[dir]:
+            assert basename.endswith(".log")
+            assert "_" in basename
+            package, version = basename[:-len(".log")].split("_")
+            list.append((os.path.join(dir, basename), package, version))
+        write_log_list_page(os.path.join(config["output-dir"], dir + ".html"),
+                            title_by_dir[dir], 
+                            desc_by_dir[dir], list)
+
+
+def find_log_files(dir):
+    return [name for name in os.listdir(dir) if name.endswith(".log")]
+
+
+def update_file(source, target):
+    if os.path.exists(target):
+        aa = os.stat(source)
+        bb = os.stat(target)
+        if aa.st_size == bb.st_size and aa.st_mtime < bb.st_mtime:
+            return
+    shutil.copyfile(source, target)
+
+
+def copy_logs(logs_by_dir, output_dir):
+    for dir in logs_by_dir:
+        fulldir = os.path.join(output_dir, dir)
+        if not os.path.exists(fulldir):
+            os.makedirs(fulldir)
+        for basename in logs_by_dir[dir]:
+            source = os.path.join(dir, basename)
+            target = os.path.join(fulldir, basename)
+            update_file(source, target)
+
+
+def remove_old_logs(logs_by_dir, output_dir):
+    for dir in logs_by_dir:
+        fulldir = os.path.join(output_dir, dir)
+        if os.path.exists(fulldir):
+            for basename in os.listdir(fulldir):
+                if basename not in logs_by_dir[dir]:
+                    os.remove(os.path.join(fulldir, basename))
+
+
+def write_file(filename, contents):
+    f = file(filename, "w")
+    f.write(contents)
+    f.close()
+
+
+def main():
+    setup_logging(logging.DEBUG, None)
+    config = Config()
+    config.read(CONFIG_FILE)
+    
+    logging.debug("Finding log files")
+    dirs = ["pass", "fail", "bugged", "fixed", "reserved", "untestable"]
+    logs_by_dir = {}
+    for dir in dirs:
+        logs_by_dir[dir] = find_log_files(dir)
+
+    logging.debug("Copying log files")
+    if not os.path.exists(config["output-dir"]):
+        os.makedirs(config["output-dir"])
+    copy_logs(logs_by_dir, config["output-dir"])
+
+    logging.debug("Removing old log files")
+    remove_old_logs(logs_by_dir, config["output-dir"])
+
+    logging.debug("Writing per-dir HTML pages")
+    print_by_dir(config, logs_by_dir)
+    
+    if os.path.exists(config["index-page"]):
+        logging.debug("Writing index page")
+        update_file(config["index-page"], 
+                    os.path.join(config["output-dir"], "index.html"))
+
+    logging.debug("Loading and parsing Packages file")
+    if 1:
+        logging.info("Fetching %s" % config["packages-url"])
+        packages_file = piupartslib.open_packages_url(config["packages-url"])
+    else:
+        packages_file = file("Packages")
+    st = piupartslib.packagesdb.PackagesDB()
+    st.read_packages_file(packages_file)
+    packages_file.close()
+
+    logging.debug("Writing package statistics page")    
+    table = "<table>\n"
+    for state in st.get_states():
+        table += ("<tr><td><a href='state-%s.html'>%s</a></td>" +
+                  "<td>%d</td></tr>\n") % \
+                    (html_protect(state), html_protect(state),
+                     len(st.get_packages_in_state(state)))
+    table += "<tr> <th>Total</th> <th>%d</th></tr>\n" % \
+                st.get_total_packages()
+    table += "</table>\n"
+    write_file(os.path.join(config["output-dir"], "stats.html"),
+               STATS_PAGE_TEMPLATE % { "table": table })
+
+    for state in st.get_states():
+        logging.debug("Writing page for %s" % state)
+        list = "<ul>\n"
+        for package in st.get_packages_in_state(state):
+            list += "<li>%s (%s)" % (html_protect(package["Package"]),
+                                     html_protect(package["Maintainer"]))
+            if package.dependencies():
+                list += "\n<ul>\n"
+                for dep in package.dependencies():
+                    list += "<li>dependency %s is %s</li>\n" % \
+                            (html_protect(dep), 
+                             html_protect(st.state_by_name(dep)))
+                list += "</ul>\n"
+            list += "</li>\n"
+        list += "</ul>\n"
+        write_file(os.path.join(config["output-dir"], 
+                                "state-%s.html" % state),
+                   STATE_PAGE_TEMPLATE % {
+                       "state": html_protect(state),
+                       "list": list
+                   })
+
+
+if __name__ == "__main__":
+    main()




More information about the Piuparts-commits mailing list