This adds a script to generate the todo item page from
bugzilla. This requires a valid username+password for
bugzilla, so it is intended that this only be run on
the
libvirt.org website via cron. Normal usage will just
generate an empty stub page.
* docs/todo.pl: Script to extract todo items from bugzilla
* docs/todo.cfg-example: Example config file
* docs/sitemap.html.in: Add todo page
* docs/Makefile.am: Generation rules for todo items
---
docs/.gitignore | 1 +
docs/Makefile.am | 20 +++++++-
docs/sitemap.html.in | 6 +++
docs/todo.cfg-example | 26 +++++++++++
docs/todo.pl | 120 +++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 171 insertions(+), 2 deletions(-)
create mode 100644 docs/todo.cfg-example
create mode 100644 docs/todo.pl
diff --git a/docs/.gitignore b/docs/.gitignore
index 80bf00f..dd78dd0 100644
--- a/docs/.gitignore
+++ b/docs/.gitignore
@@ -5,3 +5,4 @@ apibuild.pyc
*.html
libvirt-api.xml
libvirt-refs.xml
+todo.html.in
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 114ea1f..9a80ec0 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -1,6 +1,8 @@
## Process this file with automake to produce Makefile.in
SUBDIRS= schemas
+PERL = perl
+
# The directory containing the source code (if it contains documentation).
DOC_SOURCE_DIR=../src
@@ -53,7 +55,7 @@ gif = \
architecture.gif \
node.gif
-dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in))
+dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) todo.html.in
dot_html = $(dot_html_in:%.html.in=%.html)
patches = $(wildcard api_extension/*.patch)
@@ -97,6 +99,20 @@ ChangeLog.html.in: ChangeLog.xml ChangeLog.xsl
$(XSLTPROC) --nonet $(top_srcdir)/docs/ChangeLog.xsl $< > $@ \
|| { rm $@ && exit 1; }; fi
+todo.html.in: todo.pl
+ if [ -f todo.cfg ]; then \
+ echo "Generating $@"; \
+ $(PERL) $(srcdir)/$< > $@ \
+ || { rm $@ && exit 1; }; \
+ else \
+ echo "Stubbing $@"; \
+ echo "<html><body><h1>Todo
list</h1></body></html>" >> $@ ; \
+ fi
+
+todo:
+ rm -f todo.html.in
+ $(MAKE) todo.html
+
%.png: %.fig
convert -rotate 90 $< $@
@@ -153,7 +169,7 @@ clean-local:
rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html
maintainer-clean-local: clean-local
- rm -rf libvirt-api.xml libvirt-refs.xml
+ rm -rf libvirt-api.xml libvirt-refs.xml todo.html.in
rebuild: api all
diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in
index bb9cd8e..481507e 100644
--- a/docs/sitemap.html.in
+++ b/docs/sitemap.html.in
@@ -275,6 +275,12 @@
<li>
<a href="bugs.html">Bug reports</a>
<span>How and where to report bugs and request features</span>
+ <ul>
+ <li>
+ <a href="todo.html">Todo list</a>
+ <span>Main feature request list</span>
+ </li>
+ </ul>
</li>
<li>
<a href="contact.html">Contact</a>
diff --git a/docs/todo.cfg-example b/docs/todo.cfg-example
new file mode 100644
index 0000000..a99c61a
--- /dev/null
+++ b/docs/todo.cfg-example
@@ -0,0 +1,26 @@
+bugzilla = {
+ #username = ...some email addr...
+ #password = ...some bz password...
+ server =
https://bugzilla.redhat.com
+}
+query = {
+ product = Virtualization Tools
+ alias = libvirtTodo
+}
+
+output = {
+ title = Todo list
+ blurb = <<EOF
+This is a summary of all the ideas submitted for future todo items in
+libvirt. Listing an idea here does not imply that it is committed to
+for inclusion in libvirt, just that someone thought it might be a
+useful feature. Discussion for final approval of features always takes
+place on the <a href="contact.html">development mailing list</a>.
+If you intend to work on one of the items here, it is recommended to
+add a comment to the corresponding bugzilla ticket to this effect.
+This will reduce the risk of duplicated effort between developers.
+It is also strongly recommended to mail the development mailing list
+with proposals for new APIs & XML before fully implementing them, to
+allow for early design review.
+EOF
+}
diff --git a/docs/todo.pl b/docs/todo.pl
new file mode 100644
index 0000000..e541932
--- /dev/null
+++ b/docs/todo.pl
@@ -0,0 +1,120 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use BZ::Client;
+use BZ::Client::Bug;
+
+use Config::Record;
+
+my $cfg = Config::Record->new(file => "todo.cfg");
+my $server = $cfg->get("bugzilla/server",
"https://bugzilla.redhat.com");
+my $username = $cfg->get("bugzilla/username");
+my $password = $cfg->get("bugzilla/password");
+
+my $product = $cfg->get("query/product", "Virtualization Tools");
+my $todoalias = $cfg->get("query/todoalias", "libvirtTodo");
+
+my $title = $cfg->get("output/title", undef);
+my $blurb = $cfg->get("output/blurb", undef);
+
+$SIG{__DIE__} = sub {
+ my $err = shift;
+ if (UNIVERSAL::isa($err, "BZ::Client::Exception")) {
+ die "Unable to access bugzilla: " . $err->message;
+ }
+ die $err;
+};
+
+my $client = BZ::Client->new(url => $server,
+ user => $username,
+ password => $password);
+
+my $todo = BZ::Client::Bug->search($client, {'product' => $product,
+ 'alias' => $todoalias});
+
+die "Cannot find bug alias 'libvirtTodo'" unless $#{$todo} > -1;
+my $todoid = $todo->[0]->{'bug_id'};
+my $todosummary = $todo->[0]->{'short_desc'};
+$todosummary =~ s/^\s*RFE\s*:\s*//;
+$todosummary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//;
+$todosummary =~ s/^\s*Tracker\s*:\s*//;
+
+my $trackers = BZ::Client::Bug->search($client, {'product' => $product,
+ 'blocked' => $todoid });
+
+my @trackers;
+
+foreach my $tracker (@{$trackers}) {
+ my $summary = $tracker->{'short_desc'};
+ $summary =~ s/^\s*RFE\s*:\s*//;
+ $summary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//;
+ $summary =~ s/^\s*Tracker\s*:\s*//;
+
+ push @trackers, {
+ id => $tracker->{'bug_id'},
+ summary => $summary,
+ features => [],
+ };
+}
+
+foreach my $tracker (@trackers) {
+ my $features = BZ::Client::Bug->search($client, {'product' =>
$product,
+ 'blocked' => $tracker->{id}});
+
+ foreach my $feature (@{$features}) {
+ my $summary = $feature->{'short_desc'};
+ $summary =~ s/^\s*RFE\s*:\s*//;
+ $summary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//;
+
+ push @{$tracker->{features}}, {
+ id => $feature->{'bug_id'},
+ summary => $summary,
+ };
+ }
+}
+
+sub escape {
+ my $txt = shift;
+ $txt =~ s/&/&/g;
+ $txt =~ s/</</g;
+ $txt =~ s/>/>/g;
+ return $txt;
+};
+
+print "<?xml version=\"1.0\"?>\n";
+print "<html>\n";
+print " <body>\n";
+if (defined $title) {
+ print " <h1>", &escape($title), "</h1>\n";
+} else {
+ print " <h1>", &escape($todosummary),
"</h1>\n";
+}
+if (defined $blurb) {
+ print " <p>\n";
+ print $blurb;
+ print " </p>\n";
+}
+foreach my $tracker (sort { $a->{summary} cmp $b->{summary} } @trackers) {
+ next unless $#{$tracker->{features}} > 0;
+
+ my $summary = &escape($tracker->{summary});
+ my $id = $tracker->{id};
+ print " <h2><a
href=\"$server/$id\">$summary</a></h2>\n";
+ print " <ul>\n";
+ foreach my $feature (sort { $a->{summary} cmp $b->{summary} }
@{$tracker->{features}}) {
+ $summary = &escape($feature->{summary});
+ $summary =~ s,^([^:]+):,<strong>$1</strong>,;
+
+ $id = $feature->{id};
+ print " <li>$summary (<strong>rhbz <a
href=\"$server/$id\">$id</a></strong>)</li>\n";
+ }
+ print " </ul>\n";
+}
+
+print " <p>\n";
+print " This page is automatatically generated from <a
href=\"$server/$todoid\">", &escape($todosummary),
"</a>\n";
+print " </p>\n";
+print " </body>\n";
+print "</html>\n";
--
1.7.2.3