[gnome-ostree] Add qa/repoweb



commit 921b551833a1fd3a051d44810f68bea35eeb2bec
Author: Colin Walters <walters verbum org>
Date:   Thu Jun 14 17:39:55 2012 -0400

    Add qa/repoweb
    
    This is a basic web page that can load current status data via AJAX.
    The data is generated via "ostbuild repoweb-data data.json".

 Makefile-ostbuild.am                            |    1 +
 qa/repoweb/index.html                           |   46 +++
 qa/repoweb/repoweb.css                          |  360 +++++++++++++++++++++++
 qa/repoweb/repoweb.js                           |   64 ++++
 src/ostbuild/pyostbuild/builtin_repoweb_json.py |   70 +++++
 src/ostbuild/pyostbuild/main.py                 |    1 +
 6 files changed, 542 insertions(+), 0 deletions(-)
---
diff --git a/Makefile-ostbuild.am b/Makefile-ostbuild.am
index a08441f..4f966df 100644
--- a/Makefile-ostbuild.am
+++ b/Makefile-ostbuild.am
@@ -35,6 +35,7 @@ pyostbuild_PYTHON =					\
 	src/ostbuild/pyostbuild/builtin_privhelper_run_qemu.py	\
 	src/ostbuild/pyostbuild/builtin_git_mirror.py	\
 	src/ostbuild/pyostbuild/builtin_prefix.py	\
+	src/ostbuild/pyostbuild/builtin_repoweb_json.py	\
 	src/ostbuild/pyostbuild/builtin_resolve.py	\
 	src/ostbuild/pyostbuild/builtin_init.py	\
 	src/ostbuild/pyostbuild/builtin_source_diff.py	\
diff --git a/qa/repoweb/index.html b/qa/repoweb/index.html
new file mode 100644
index 0000000..3111a9b
--- /dev/null
+++ b/qa/repoweb/index.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html> 
+<html> 
+  <head> 
+    <title>GNOME-OSTree</title> 
+    <meta name="viewport" content="width=device-width, initial-scale=1"> 
+    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css"; />
+    <link rel="stylesheet" href="repoweb.css"/>
+    <script src="http://code.jquery.com/jquery-1.7.1.min.js";></script>
+    <script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js";></script>
+    <script src="repoweb.js"></script>
+  </head> 
+  <body onload="$(document).ready(function(){repoweb_index_init();})">
+
+    <div data-role="page" class="type-interior">
+      <div data-role="header">
+        <h1>GNOME-OSTree build server</h1>
+      </div>
+
+      <div data-role="content"> 
+        <div class="content-primary">
+          <p>This is
+            the <a href="https://live.gnome.org/OSTree/GnomeOSTree";>GNOME-OSTree</a>
+            build server.  It builds from
+            the <a href="http://git.gnome.org/browse/gnome-ostree";>gnome-ostree</a>
+            git module.</p>
+        
+          <h3>Summary</h3>
+          <div id="repoweb-summary">Loading...</div>
+        </div>
+        <div class="content-secondary">
+	  <ul data-role="listview" data-theme="c" data-dividertheme="d">
+	    <li data-role="list-divider">Tools</li>
+	    <li><a href="logs" rel="external">Build logs</a></li>
+	    <li><a href="src" rel="external">Source code</a></li>
+          </ul>
+        </div>
+      </div> <!-- content -->
+    </div>
+  </body>
+</html>
+
+<!-- 
+  Local Variables:
+  indent-tabs-mode: nil
+  End:
+-->
diff --git a/qa/repoweb/repoweb.css b/qa/repoweb/repoweb.css
new file mode 100644
index 0000000..b1c657d
--- /dev/null
+++ b/qa/repoweb/repoweb.css
@@ -0,0 +1,360 @@
+/* taken from  http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.css */
+/* jqm docs css
+
+Beware: lots of last-minute CSS going on in here 
+cobblers, shoes, 
+*/
+
+body { background: #dddddd; }
+.ui-mobile .type-home .ui-content { margin: 0; background: #e5e5e5 url(../images/jqm-sitebg.png) top center repeat-x; }
+.ui-mobile #jqm-homeheader { padding: 40px 10px 0; text-align: center;  margin: 0 auto; }
+.ui-mobile #jqm-homeheader h1 { margin: 0 0 ; }
+.ui-mobile #jqm-homeheader p { margin: .3em 0 0; line-height: 1.3; font-size: .9em; font-weight: bold; color: #666; }
+.ui-mobile #jqm-version { text-indent: -99999px; background: url(../images/version.png) top right no-repeat; width: 119px; height: 122px; overflow: hidden; position: absolute; z-index: 50; top: -11px; right: 0; }
+.ui-mobile .jqm-themeswitcher { margin: 10px 25px 10px 10px;  }
+
+h2 { margin:1.2em 0 .4em 0; }
+p code { font-size:1.2em; font-weight:bold; } 
+h4 code {font-size:1.2em; font-weight:bold; }
+
+dt { font-weight: bold; margin: 2em 0 .5em; }
+dt code, dd code { font-size:1.3em; line-height:150%; }
+pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
+
+#jqm-homeheader img { width: 235px; }
+img { max-width: 100%; }
+
+/* fluid images moved from jquery.mobile.core.css*/
+.ui-mobile img {
+	max-width: 100%;
+}
+
+.ui-header .jqm-home { top: 0; }
+nav { margin: 0; }
+
+
+
+p.intro {
+	font-size: .96em;
+	line-height: 1.3;
+		border-top: 1px solid #75ae18;
+		border-bottom: 0;
+		background: none;
+		margin: 1.5em 0;
+		padding: 1.5em 15px 0;
+
+}
+p.intro strong {
+	color:  #558e08;
+}
+.footer-docs {
+	padding: 5px 0;
+}
+.footer-docs p {
+	margin-left:15px;
+	font-weight: normal;
+	font-size: .9em;
+}
+
+.type-interior .content-secondary {
+	border-right: 0;
+	border-left: 0;
+	margin: 10px -15px 0;
+	background: #fff;
+	border-top: 1px solid #ccc;
+}
+.type-home .ui-content {
+	margin-top: 5px;
+}
+.type-interior .ui-content {
+	padding-bottom: 0;
+}
+.content-secondary .ui-collapsible {
+	padding: 0 15px 10px;
+
+}
+.content-secondary .ui-collapsible-content {
+	padding: 0;
+	background: none;
+	border-bottom: none;
+}
+.content-secondary .ui-listview {
+	margin: 0;
+}
+/* new API additions */
+
+dt {  
+	margin: 35px 0 15px 0; 
+	background-color:#ddd; 
+	font-weight:normal;
+}
+dt code { 
+	display:inline-block; 
+	font-weight:bold;
+	color:#56A00E; 
+	padding:3px 7px; 
+	margin-right:10px; 
+	background-color:#fff; 
+}
+dd { 
+	margin-bottom:10px; 
+}
+dd .default { font-weight:bold; }
+dd pre { 
+	margin:0 0 0 0; 
+}
+dd code { font-weight: normal; }
+dd pre code { 
+	margin:0; 
+	border:none; 
+	font-weight:normal; 
+	font-size:100%; 
+	background-color:transparent; 
+}
+dd h4 { margin:15px 0 0 0; }
+		
+.localnav {
+	margin:0 0 20px 0;
+	overflow:hidden;
+}
+.localnav li {
+	float:left;
+}
+.localnav .ui-btn-inner { 
+	padding: .6em 10px; 
+	font-size:80%; 
+}
+
+/* custom dialog for the photos sharing */
+.ui-dialog.dialog-actionsheet .ui-dialog-contain {
+	margin-top: 0;
+}
+
+
+
+/* F bar theme - just for the docs overview headers */
+.ui-bar-f {
+	border: 1px solid #56A00E;
+	background: 			#74b042;
+	color: 					#fff;
+	font-weight: bold;
+	text-shadow: 0 1px 1px #335413;	
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#74b042), to(#56A00E)); /* Saf4+, Chrome */
+	background-image: -webkit-linear-gradient(#74b042, #56A00E); /* Chrome 10+, Saf5.1+ */
+	background-image:    -moz-linear-gradient(#74b042, #56A00E); /* FF3.6 */
+	background-image:     -ms-linear-gradient(#74b042, #56A00E); /* IE10 */
+	background-image:      -o-linear-gradient(#74b042, #56A00E); /* Opera 11.10+ */
+	background-image:         linear-gradient(#74b042, #56A00E);		
+}
+.ui-bar-f, 
+.ui-bar-f input, 
+.ui-bar-f select, 
+.ui-bar-f textarea, 
+.ui-bar-f button {
+	font-family: Helvetica, Arial, sans-serif /*{global-font-family}*/;
+}
+
+.ui-bar-f,
+.ui-bar-f .ui-link-inherit {
+	color: 					#fff;
+}
+.ui-bar-f .ui-link {
+	color: 					#fff;
+	font-weight: bold;
+}
+.ui-btn-up-f {
+	border: 1px solid 		#3B6F07;
+	background: 			#56A00E;
+	font-weight: bold;
+	color: 					#fff;
+	text-shadow: 0 1px 1px #234403;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#74b042), to(#56A00E)); /* Saf4+, Chrome */
+	background-image: -webkit-linear-gradient(#74b042, #56A00E); /* Chrome 10+, Saf5.1+ */
+	background-image:    -moz-linear-gradient(#74b042, #56A00E); /* FF3.6 */
+	background-image:     -ms-linear-gradient(#74b042, #56A00E); /* IE10 */
+	background-image:      -o-linear-gradient(#74b042, #56A00E); /* Opera 11.10+ */
+	background-image:         linear-gradient(#74b042, #56A00E);
+}
+.ui-btn-up-f a.ui-link-inherit {
+	color: 					#fff;
+}
+.ui-btn-hover-f {
+	border: 1px solid 		#3B6F07;
+	background: 			#6EBC1F;
+	font-weight: bold;
+	color: 					#fff;
+	text-shadow: 0 1px 1px #234403;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#8FC963), to(#6EBC1F)); /* Saf4+, Chrome */
+	background-image: -webkit-linear-gradient(#8FC963, #6EBC1F); /* Chrome 10+, Saf5.1+ */
+	background-image:    -moz-linear-gradient(#8FC963, #6EBC1F); /* FF3.6 */
+	background-image:     -ms-linear-gradient(#8FC963, #6EBC1F); /* IE10 */
+	background-image:      -o-linear-gradient(#8FC963, #6EBC1F); /* Opera 11.10+ */
+	background-image:         linear-gradient(#8FC963, #6EBC1F);
+}
+.ui-btn-hover-f a.ui-link-inherit {
+	color: 					#fff;
+}
+.ui-btn-down-f {
+	border: 1px solid 		#3B6F07;
+	background: 			#3d3d3d;
+	font-weight: bold;
+	color: 					#fff;
+	text-shadow: 0 1px 1px #234403;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#56A00E), to(#64A234)); /* Saf4+, Chrome */
+	background-image: -webkit-linear-gradient(#56A00E, #64A234); /* Chrome 10+, Saf5.1+ */
+	background-image:    -moz-linear-gradient(#56A00E, #64A234); /* FF3.6 */
+	background-image:     -ms-linear-gradient(#56A00E, #64A234); /* IE10 */
+	background-image:      -o-linear-gradient(#56A00E, #64A234); /* Opera 11.10+ */
+	background-image:         linear-gradient(#56A00E, #64A234);
+}
+.ui-btn-down-f a.ui-link-inherit {
+	color: 					#fff;
+}
+.ui-btn-up-f,
+.ui-btn-hover-f,
+.ui-btn-down-f {
+	font-family: Helvetica, Arial, sans-serif;
+	text-decoration: none;
+}
+
+
+
+
+/* docs site layout */
+
+ media all and (min-width: 650px){
+	
+
+	.type-home .ui-content {
+		margin-top: 5px;
+	}
+	.ui-mobile #jqm-homeheader {
+		max-width: 340px;
+	}
+	.ui-mobile .jqm-themeswitcher {
+		float: right;
+	}
+	p.intro {
+		margin: 2em 0;
+	}
+	.type-home .ui-content,
+	.type-interior .ui-content {
+		padding: 0;
+		background: url(../images/px-ccc.gif) 50% 0 repeat-y;
+	}
+	.type-interior .ui-content {
+		background-position: 45%;
+		overflow: hidden;
+	}
+	.content-secondary {
+		text-align: left;
+		float: left;
+		width: 45%;
+		background: none;
+	}
+	.content-secondary,
+	.type-interior .content-secondary {
+		margin: 30px 0 20px 2%;
+		padding: 20px 4% 0 0;
+			background: none;
+					border-top: none;
+	}
+	.type-index .content-secondary {
+		padding: 0;
+	}
+	.content-secondary .ui-collapsible {
+		margin: 0;
+		padding: 0;
+	}
+	.content-secondary .ui-collapsible-content {
+		border: none;
+	}
+	.type-index .content-secondary .ui-listview {
+		margin: 0;
+	}
+
+	.ui-mobile #jqm-homeheader {
+		padding: 0;
+	}
+	.content-primary {
+		width: 45%;
+		float: right;
+		margin-top: 30px;
+		margin-right: 1%;
+		padding-right: 1%;
+	}
+	.content-primary ul:first-child {
+		margin-top: 0;
+	}
+	.content-secondary h2 {
+		position: absolute;
+		left: -9999px;
+	}
+	.type-interior .content-primary {
+		padding: 1.5em 6% 3em 0;
+		margin: 0;
+	}
+	/* fix up the collapsibles - expanded on desktop */
+	.content-secondary .ui-collapsible-heading {
+		display: none;
+	}
+	.content-secondary .ui-collapsible-contain {
+		margin:0;
+	}
+	.content-secondary .ui-collapsible-content {
+		display: block;
+		margin: 0;
+		padding: 0;
+	}
+	.type-interior  .content-secondary .ui-li-divider {
+		padding-top: 1em;
+		padding-bottom: 1em;
+	}
+	.type-interior .content-secondary {
+		margin: 0;
+		padding: 0;
+	}
+	
+}
+ media all and (min-width: 750px){
+	.type-home .ui-content,
+	.type-interior .ui-content {
+		background-position: 39%;
+	}
+	.content-secondary {
+		width: 34%;
+	}
+	.content-primary {
+		width: 56%;
+		padding-right: 1%;
+	}	
+	.type-interior .ui-content {
+		background-position: 34%;
+	}
+}
+
+ media all and (min-width: 1200px){
+	.type-home .ui-content{
+		background-position: 38.5%;
+	}
+	.type-interior .ui-content {
+		background-position: 30%;
+	}
+	.content-secondary {
+		width: 30%;
+		padding-right:6%;
+		margin: 30px 0 20px 5%;
+	}
+	.type-interior .content-secondary {
+		margin: 0;
+		padding: 0;
+	}
+	.content-primary {
+		width: 50%;
+		margin-right: 5%;
+		padding-right: 3%;
+	}
+	.type-interior .content-primary {
+		width: 60%;
+	}
+}
diff --git a/qa/repoweb/repoweb.js b/qa/repoweb/repoweb.js
new file mode 100644
index 0000000..81e2bf4
--- /dev/null
+++ b/qa/repoweb/repoweb.js
@@ -0,0 +1,64 @@
+// -*- indent-tabs-mode: nil -*-
+
+function htmlescape(str) {
+    var pre = document.createElement('pre');
+    var text = document.createTextNode(str);
+    pre.appendChild(text);
+    return pre.innerHTML.replace(/"/g, "&quot;").replace(/'/g, "&#39;");;
+}
+
+var repoDataSignal = {};
+var repoData = null;
+
+function repoweb_on_data_loaded(data) {
+    console.log("data loaded");
+    repoData = data;
+    $(repoDataSignal).trigger("loaded");
+}
+
+function repoweb_init() {
+    $.getJSON("data.json", repoweb_on_data_loaded);
+}
+
+function repoweb_index_init() {
+    repoweb_init();
+    $(repoDataSignal).on("loaded", function () {
+	$("#repoweb-summary").empty();
+	var summary = $("#repoweb-summary").get(0);
+	var targets = repoData['targets'];
+	for (var name in targets) {
+	    var elt;
+	    var targetData = targets[name];
+	    var div = document.createElement("div");
+	    summary.appendChild(div);
+
+	    elt = document.createElement("h3")
+	    elt.appendChild(document.createTextNode(name));
+	    div.appendChild(elt);
+	    elt = document.createTextNode(targetData['revision']);
+	    div.appendChild(elt);
+	} 
+    });
+}
+
+function repoweb_files_init() {
+    repoweb_init();
+    $(repoDataSignal).on("loaded", function () {
+	$("#repoweb-files").empty();
+	var files = $("#repoweb-files").get(0);
+	var targets = repoData['targets'];
+	for (var name in targets) {
+	    var elt;
+	    var targetData = targets[name];
+	    var div = document.createElement("div");
+	    files.appendChild(div);
+
+	    elt = document.createElement("h3")
+	    elt.appendChild(document.createTextNode(name));
+	    div.appendChild(elt);
+	    elt = document.createElement("pre");
+	    elt.appendChild(document.createTextNode(targetData['files']));
+	    div.appendChild(elt);
+	} 
+    });
+}
diff --git a/src/ostbuild/pyostbuild/builtin_repoweb_json.py b/src/ostbuild/pyostbuild/builtin_repoweb_json.py
new file mode 100755
index 0000000..0fab3bc
--- /dev/null
+++ b/src/ostbuild/pyostbuild/builtin_repoweb_json.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2012 Colin Walters <walters verbum org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+import os,sys,json
+import argparse
+import json
+
+from . import builtins
+from .ostbuildlog import log, fatal
+from .subprocess_helpers import run_sync, run_sync_get_output
+
+class OstbuildRepoWebJson(builtins.Builtin):
+    name = "repoweb-json"
+    short_description = "Dump tree status as JSON"
+
+    def __init__(self):
+        builtins.Builtin.__init__(self)
+
+    def _snapshot_from_rev(self, rev):
+        self.init_repo()
+        text = run_sync_get_output(['ostree', '--repo=' + self.repo,
+                                    'cat', rev, '/contents.json'],
+                                   log_initiation=False)
+        return json.loads(text)
+
+    def execute(self, argv):
+        parser = argparse.ArgumentParser(description=self.short_description)
+        parser.add_argument('--prefix')
+        parser.add_argument('--src-snapshot')
+        parser.add_argument('output', help="Output filename")
+
+        args = parser.parse_args(argv)
+        self.parse_config()
+        self.parse_snapshot(args.prefix, args.src_snapshot)
+
+        output = {'00ostbuild-repoweb-json-version': 0}
+
+        targets_list = []
+        for target_component_type in ['runtime', 'devel']:
+            for architecture in self.snapshot['architectures']:
+                name = 'trees/%s-%s-%s' % (self.snapshot['prefix'], architecture, target_component_type)
+                targets_list.append(name)
+
+        output['targets'] = {}
+        for target in targets_list:
+            target_data = {}
+            output['targets'][target] = target_data
+            target_data['revision'] = run_sync_get_output(['ostree', '--repo=' + self.repo, 'rev-parse', target])
+            
+        f = open(args.output, 'w')
+        json.dump(output, f, indent=4, sort_keys=True)
+        f.close()
+
+        print "Wrote %r" % (args.output, )
+
+builtins.register(OstbuildRepoWebJson)
diff --git a/src/ostbuild/pyostbuild/main.py b/src/ostbuild/pyostbuild/main.py
index 0adccd6..c71ddef 100755
--- a/src/ostbuild/pyostbuild/main.py
+++ b/src/ostbuild/pyostbuild/main.py
@@ -35,6 +35,7 @@ from . import builtin_run_qemu
 from . import builtin_prefix
 from . import builtin_privhelper_deploy_qemu
 from . import builtin_privhelper_run_qemu
+from . import builtin_repoweb_json
 from . import builtin_resolve
 from . import builtin_source_diff
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]