]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Fix for bug 156548: XUL implementation of duplicates report.
authormyk%mozilla.org <>
Tue, 5 Nov 2002 09:53:59 +0000 (09:53 +0000)
committermyk%mozilla.org <>
Tue, 5 Nov 2002 09:53:59 +0000 (09:53 +0000)
CGI.pl
checksetup.pl
collectstats.pl
css/duplicates.css [new file with mode: 0644]
duplicates.cgi
duplicates.xul [new file with mode: 0644]
js/duplicates.js [new file with mode: 0644]
skins/standard/duplicates.css [new file with mode: 0644]
template/en/default/reports/duplicates.rdf.tmpl [new file with mode: 0644]

diff --git a/CGI.pl b/CGI.pl
index d6dca3a39138911104b5c060c232b4131d0ac341..2069d9235f585f250de36665aa1ce7db3d0b4a4b 100644 (file)
--- a/CGI.pl
+++ b/CGI.pl
@@ -206,7 +206,7 @@ sub get_netaddr {
     my ($ipaddr) = @_;
 
     # Check for a valid IPv4 addr which we know how to parse
-    if ($ipaddr !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
+    if (!$ipaddr || $ipaddr !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
         return undef;
     }
 
index 3a60a393786908c701161fc4a3402d8310473b89..aa91c3a34da3dafc965954864ce8cc316d894d41 100755 (executable)
@@ -837,8 +837,12 @@ END
     open HTACCESS, ">data/.htaccess";
     print HTACCESS <<'END';
 # nothing in this directory is retrievable unless overriden by an .htaccess
-# in a subdirectory
+# in a subdirectory; the only exception is duplicates.rdf, which is used by
+# duplicates.xul and must be loadable over the web
 deny from all
+<Files duplicates.rdf>
+  allow from all
+</Files>
 END
     close HTACCESS;
     chmod $fileperm, "data/.htaccess";
index 8caf92d7788a8a8699c0421b4e7bba274da48b68..61e7cf2044e00adcce45dda70d74860d7b5f6bf2 100755 (executable)
@@ -53,6 +53,23 @@ foreach (@myproducts) {
 
 &calculate_dupes();
 
+# Generate a static RDF file containing the default view of the duplicates data.
+open(CGI, "REQUEST_METHOD=GET QUERY_STRING=ctype=rdf ./duplicates.cgi |")
+  || die "can't fork duplicates.cgi: $!";
+open(RDF, ">data/duplicates.tmp")
+  || die "can't write to data/duplicates.tmp: $!";
+my $headers_done = 0;
+while (<CGI>) {
+  print RDF if $headers_done;
+  $headers_done = 1 if $_ eq "\n";
+}
+close CGI;
+close RDF;
+if (-s "data/duplicates.tmp") {
+    rename("data/duplicates.rdf", "data/duplicates-old.rdf");
+    rename("data/duplicates.tmp", "data/duplicates.rdf");
+}
+
 sub check_data_dir {
     my $dir = shift;
 
diff --git a/css/duplicates.css b/css/duplicates.css
new file mode 100644 (file)
index 0000000..aab36fb
--- /dev/null
@@ -0,0 +1,27 @@
+/* The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is the Bugzilla Bug Tracking System.
+ * 
+ * The Initial Developer of the Original Code is Netscape Communications
+ * Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All
+ * Rights Reserved.
+ * 
+ * Contributor(s): Myk Melez <myk@mozilla.org>
+ */
+
+treechildren:-moz-tree-cell-text(resolution-FIXED) { 
+  text-decoration: line-through;
+}
+
+treecol#id_column { width: 6em; }
+treecol#duplicate_count_column { width: 5em; }
+treecol#duplicate_delta_column { width: 5em; }
index 643a54423ee171d7fd61291439abd2ab76945253..e95d4b02c5a900f3f54dfcb36f04b11aa481f9d4 100755 (executable)
@@ -32,6 +32,18 @@ use lib qw(.);
 require "globals.pl";
 require "CGI.pl";
 
+use vars qw($buffer);
+
+# Go directly to the XUL version of the duplicates report (duplicates.xul)
+# if the user specified ctype=xul.  Adds params if they exist, and directs
+# the user to a signed copy of the script in duplicates.jar if it exists.
+if ($::FORM{'ctype'} eq "xul") {
+    my $params = CanonicaliseParams($::buffer, ["format", "ctype"]);
+    print "Location: " . (-e "duplicates.jar" ? "duplicates.jar!/" : "") . 
+          "duplicates.xul" . ($params ? "?$params" : "") . "\n\n";
+    exit;
+}
+
 # Use global templatisation variables.
 use vars qw($template $vars);
 
diff --git a/duplicates.xul b/duplicates.xul
new file mode 100644 (file)
index 0000000..be647c1
--- /dev/null
@@ -0,0 +1,133 @@
+<?xml version="1.0"?>
+<!--
+   -
+   - The contents of this file are subject to the Mozilla Public
+   - License Version 1.1 (the "License"); you may not use this file
+   - except in compliance with the License. You may obtain a copy of
+   - the License at http://www.mozilla.org/MPL/
+   -
+   - Software distributed under the License is distributed on an "AS
+   - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+   - implied. See the License for the specific language governing
+   - rights and limitations under the License.
+   -
+   - The Original Code is the Bugzilla Bug Tracking System.
+   -
+   - The Initial Developer of the Original Code is Netscape Communications
+   - Corporation. Portions created by Netscape are
+   - Copyright (C) 1998 Netscape Communications Corporation. All
+   - Rights Reserved.
+   -
+   - Contributor(s): Myk Melez <myk@mozilla.org>
+   -
+   -->
+
+<!DOCTYPE window [
+  <!ENTITY idColumn.label               "ID">
+  <!ENTITY duplicateCountColumn.label   "Count">
+  <!ENTITY duplicateDeltaColumn.label   "Delta">
+  <!ENTITY componentColumn.label        "Component">
+  <!ENTITY severityColumn.label         "Severity">
+  <!ENTITY osColumn.label               "OS">
+  <!ENTITY targetMilestoneColumn.label  "Milestone">
+  <!ENTITY summaryColumn.label          "Summary">
+]>
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="css/duplicates.css" type="text/css"?>
+
+<window id="duplicates_report"
+        xmlns:html="http://www.w3.org/1999/xhtml"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Duplicates Report">
+
+  // Code for populating the tree from the RDF data source
+  // and loading bug reports when the user selects rows in the tree.
+  <script type="application/x-javascript" src="js/duplicates.js" />
+
+  <tree id="results-tree" flex="1"
+        flags="dont-build-content"
+        enableColumnDrag="true"
+        datasources="rdf:null"
+        ref=""
+        onselect="loadBugInPane();"
+        ondblclick="loadBugInWindow();">
+    <treecols>
+      <treecol id="id_column" label="&idColumn.label;" primary="true" sort="?id" 
+               persist="width hidden sortActive sortDirection ordinal" />
+      <splitter class="tree-splitter"/> 
+
+      <treecol id="duplicate_count_column" label="&duplicateCountColumn.label;" sort="?duplicate_count" 
+               sortActive="true" sortDirection="descending" 
+               persist="width hidden sortActive sortDirection ordinal" />
+      <splitter class="tree-splitter" /> 
+      
+      <treecol id="duplicate_delta_column" label="&duplicateDeltaColumn.label;" sort="?duplicate_delta" 
+               persist="width hidden sortActive sortDirection ordinal" />
+      <splitter class="tree-splitter"/>
+      
+      <treecol id="component_column" label="&componentColumn.label;" flex="3" sort="?component" 
+               persist="width hidden sortActive sortDirection ordinal" />
+      <splitter class="tree-splitter"/> 
+
+      <treecol id="severity_column" label="&severityColumn.label;" flex="1" sort="?severity" 
+               persist="width hidden sortActive sortDirection ordinal" />
+      <splitter class="tree-splitter"/> 
+
+      <treecol id="os_column" label="&osColumn.label;" flex="2" sort="?os" 
+               persist="width hidden sortActive sortDirection ordinal" />
+      <splitter class="tree-splitter"/> 
+
+      <treecol id="target_milestone_column" label="&targetMilestoneColumn.label;" flex="1" sort="?target_milestone" 
+               persist="width hidden sortActive sortDirection ordinal" />
+      <splitter class="tree-splitter"/> 
+
+      <treecol id="summary_column" label="&summaryColumn.label;" flex="12" sort="?summary" 
+               persist="width hidden sortActive sortDirection ordinal" />
+    </treecols>
+    <template>
+      <rule>
+        <conditions>
+          <treeitem uri="?uri" />
+          <triple subject="?uri" predicate="http://www.bugzilla.org/rdf#bugs" object="?bugs" />
+          <member container="?bugs" child="?bug" />
+          <triple subject="?bug" predicate="http://www.bugzilla.org/rdf#id" object="?id" />
+        </conditions>
+        <bindings>
+          <binding subject="?bug" predicate="http://www.bugzilla.org/rdf#duplicate_count"  object="?duplicate_count" />
+          <binding subject="?bug" predicate="http://www.bugzilla.org/rdf#duplicate_delta"  object="?duplicate_delta" />
+          <binding subject="?bug" predicate="http://www.bugzilla.org/rdf#component"        object="?component" />
+          <binding subject="?bug" predicate="http://www.bugzilla.org/rdf#severity"         object="?severity" />
+          <binding subject="?bug" predicate="http://www.bugzilla.org/rdf#priority"         object="?priority" />
+          <binding subject="?bug" predicate="http://www.bugzilla.org/rdf#os"               object="?os" />
+          <binding subject="?bug" predicate="http://www.bugzilla.org/rdf#target_milestone" object="?target_milestone" />
+          <binding subject="?bug" predicate="http://www.bugzilla.org/rdf#summary"          object="?summary" />
+          <binding subject="?bug" predicate="http://www.bugzilla.org/rdf#resolution"       object="?resolution" />
+        </bindings>
+        <action>
+          <treechildren>
+            <treeitem uri="?bug">
+              <treerow properties="resolution-?resolution">
+                <treecell ref="id_column"               label="?id"               properties="resolution-?resolution" />
+                <treecell ref="duplicate_count_column"  label="?duplicate_count"  properties="resolution-?resolution" />
+                <treecell ref="duplicate_delta_column"  label="?duplicate_delta"  properties="resolution-?resolution" />
+                <treecell ref="component_column"        label="?component"        properties="resolution-?resolution" />
+                <treecell ref="severity_column"         label="?severity"         properties="resolution-?resolution" />
+                <treecell ref="os_column"               label="?os"               properties="resolution-?resolution" />
+                <treecell ref="target_milestone_column" label="?target_milestone" properties="resolution-?resolution" />
+                <treecell ref="summary_column"          label="?summary"          properties="resolution-?resolution" />
+              </treerow>
+            </treeitem>
+          </treechildren>
+        </action>
+      </rule>
+    </template>
+  </tree>
+  
+  <splitter id="report-content-splitter" collapse="after" state="open" persist="state">
+    <grippy/>
+  </splitter>
+  
+  <iframe id="content-browser" src="about:blank" flex="2" persist="height" />
+
+</window>
diff --git a/js/duplicates.js b/js/duplicates.js
new file mode 100644 (file)
index 0000000..b1e94a8
--- /dev/null
@@ -0,0 +1,153 @@
+/* The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is the Bugzilla Bug Tracking System.
+ * 
+ * The Initial Developer of the Original Code is Netscape Communications
+ * Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All
+ * Rights Reserved.
+ * 
+ * Contributor(s): Myk Melez <myk@mozilla.org>
+ */
+
+// When the XUL window finishes loading, load the RDF data into it.
+window.addEventListener('load', loadData, false);
+
+// The base URL of this Bugzilla installation; derived from the page's URL.
+var gBaseURL = window.location.href.replace(/duplicates\.(jar!|xul).*/, "");
+
+function loadData()
+{
+  // Loads the duplicates data as an RDF data source, attaches it to the tree,
+  // and rebuilds the tree to display the data.
+
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  
+  // Get the RDF service so we can use it to load the data source.
+  var rdfService = 
+    Components
+      .classes["@mozilla.org/rdf/rdf-service;1"]
+        .getService(Components.interfaces.nsIRDFService);
+
+  // When a bug report loads in the content iframe, a 'load' event bubbles up
+  // to the browser window, which calls this load handler again, which reloads
+  // the RDF data, which causes the tree to lose the selection.  To prevent
+  // this, we have to remove this handler.
+  window.removeEventListener('load', loadData, false);
+
+  // The URL of the RDF file; by default for performance a static file 
+  // generated by collectstats.pl, but a call to duplicates.cgi if the page's 
+  // URL contains parameters (so we can dynamically generate the RDF data 
+  // based on those parameters).
+  var dataURL = gBaseURL + "data/duplicates.rdf";
+  if (window.location.href.search(/duplicates\.xul\?.+/) != -1)
+    dataURL = window.location.href.replace(/(duplicates\.jar!\/)?duplicates\.xul\?/, "duplicates.cgi?ctype=rdf&");
+  
+  // Get the data source and add it to the XUL tree's database to populate
+  // the tree with the data.
+  var dataSource = rdfService.GetDataSource(dataURL);
+  
+  // If we're using the static file, add an observer that detects failed loads
+  // (in case this installation isn't generating the file nightly) and redirects
+  // to the CGI version when loading of the static version fails.
+  if (window.location.href.search(/duplicates\.xul\?.+/) == -1)
+  {
+    var sink = dataSource.QueryInterface(Components.interfaces.nsIRDFXMLSink);
+    sink.addXMLSinkObserver(StaticDataSourceObserver);
+  }
+  
+  // Add the data source to the tree, set the tree's "ref" attribute
+  // to the base URL of the data source, and rebuild the tree.
+  var resultsTree = document.getElementById('results-tree');
+  resultsTree.database.AddDataSource(dataSource);
+  resultsTree.setAttribute('ref', gBaseURL + "data/duplicates.rdf");
+  resultsTree.builder.rebuild();
+}
+
+function getBugURI()
+{
+  var tree = document.getElementById('results-tree');
+  var index = tree.currentIndex;
+
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  var builder = tree.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
+  var resource = builder.getResourceAtIndex(index);
+
+  return resource.Value;
+}
+
+function loadBugInWindow()
+{
+  // Loads the selected bug in the browser window, replacing the duplicates report
+  // with the bug report.
+
+  var bugURI = getBugURI();
+  window.location = bugURI;
+}
+
+function loadBugInPane()
+{
+  // Loads the selected bug in the iframe-based content pane that is part of 
+  // this XUL document.
+
+  var splitter = document.getElementById('report-content-splitter');
+  var state = splitter.getAttribute('state');
+  if (state != "collapsed")
+  {
+    var bugURI = getBugURI();
+    var browser = document.getElementById('content-browser');
+    browser.setAttribute('src', bugURI);
+  }
+}
+
+var StaticDataSourceObserver = {
+  onBeginLoad: function(aSink) { } , 
+  onInterrupt: function(aSink) { } , 
+  onResume: function(aSink) { } , 
+  onEndLoad: function(aSink)
+  {
+    // Removes the observer from the data source so it doesn't stay around
+    // when duplicates.xul is reloaded from scratch.
+    
+    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+    
+    aSink.removeXMLSinkObserver(StaticDataSourceObserver);
+  } , 
+  onError: function(aSink, aStatus, aErrorMsg)
+  {
+    // Tries the dynamic data source since the static one failed to load.
+    
+    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+    
+    // Get the RDF service so we can use it to load the data source.
+    var rdfService = 
+      Components
+        .classes["@mozilla.org/rdf/rdf-service;1"]
+          .getService(Components.interfaces.nsIRDFService);
+    
+    // Remove the observer from the data source so it doesn't stay around
+    // when duplicates.xul is reloaded from scratch.
+    aSink.removeXMLSinkObserver(StaticDataSourceObserver);
+    
+    // Remove the static data source from the tree.
+    var oldDataSource = aSink.QueryInterface(Components.interfaces.nsIRDFDataSource);
+    var resultsTree = document.getElementById('results-tree');
+    resultsTree.database.RemoveDataSource(oldDataSource);
+
+    // Munge the URL to point to the CGI and load the data source.
+    var dataURL = gBaseURL + "duplicates.cgi?ctype=rdf";
+    newDataSource = rdfService.GetDataSource(dataURL);
+    
+    // Add the data source to the tree and rebuild the tree with the new data.
+    resultsTree.database.AddDataSource(newDataSource);
+    resultsTree.builder.rebuild();
+  }
+};
diff --git a/skins/standard/duplicates.css b/skins/standard/duplicates.css
new file mode 100644 (file)
index 0000000..aab36fb
--- /dev/null
@@ -0,0 +1,27 @@
+/* The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ * 
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ * 
+ * The Original Code is the Bugzilla Bug Tracking System.
+ * 
+ * The Initial Developer of the Original Code is Netscape Communications
+ * Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All
+ * Rights Reserved.
+ * 
+ * Contributor(s): Myk Melez <myk@mozilla.org>
+ */
+
+treechildren:-moz-tree-cell-text(resolution-FIXED) { 
+  text-decoration: line-through;
+}
+
+treecol#id_column { width: 6em; }
+treecol#duplicate_count_column { width: 5em; }
+treecol#duplicate_delta_column { width: 5em; }
diff --git a/template/en/default/reports/duplicates.rdf.tmpl b/template/en/default/reports/duplicates.rdf.tmpl
new file mode 100644 (file)
index 0000000..941f9f7
--- /dev/null
@@ -0,0 +1,51 @@
+[% template_version = "1.0@bugzilla.org" %]
+[%# The contents of this file are subject to the Mozilla Public
+  # License Version 1.1 (the "License"); you may not use this file
+  # except in compliance with the License. You may obtain a copy of
+  # the License at http://www.mozilla.org/MPL/
+  #
+  # Software distributed under the License is distributed on an "AS
+  # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+  # implied. See the License for the specific language governing
+  # rights and limitations under the License.
+  #
+  # The Original Code is the Bugzilla Bug Tracking System.
+  #
+  # The Initial Developer of the Original Code is Netscape Communications
+  # Corporation. Portions created by Netscape are
+  # Copyright (C) 1998 Netscape Communications Corporation. All
+  # Rights Reserved.
+  #
+  # Contributor(s): Myk Melez <myk@mozilla.org>
+  #%]
+
+<?xml version="1.0"?>
+<!-- [% template_version %] -->
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:bz="http://www.bugzilla.org/rdf#"
+     xmlns:nc="http://home.netscape.com/NC-rdf#">
+
+<bz:duplicates_report rdf:about="[% Param('urlbase') %]data/duplicates.rdf">
+  <bz:bugs>
+    <Seq>
+      [% FOREACH bug = bugs %]
+        <li>
+          <bz:bug rdf:about="[% Param('urlbase') %]show_bug.cgi?id=[% bug.id %]">
+            <bz:id nc:parseType="Integer">[% bug.id %]</bz:id>
+            <bz:resolution>[% bug.resolution FILTER html %]</bz:resolution>
+            <bz:duplicate_count nc:parseType="Integer">[% bug.count %]</bz:duplicate_count>
+            <bz:duplicate_delta nc:parseType="Integer">[% bug.delta %]</bz:duplicate_delta>
+            <bz:component>[% bug.component FILTER html %]</bz:component>
+            <bz:severity>[% bug.bug_severity FILTER html %]</bz:severity>
+            <bz:os>[% bug.op_sys FILTER html %]</bz:os>
+            <bz:target_milestone>[% bug.target_milestone FILTER html %]</bz:target_milestone>
+            <bz:summary>[% bug.short_desc FILTER html %]</bz:summary>
+          </bz:bug>
+        </li>
+      [% END %]
+    </Seq>
+  </bz:bugs>
+</bz:duplicates_report>
+
+</RDF>