aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/canonicalise-csv28
-rwxr-xr-xbin/load-contacts4
-rwxr-xr-xweb/alert.cgi86
-rwxr-xr-xweb/confirm.cgi47
-rw-r--r--web/css.css15
-rw-r--r--web/i/email.pngbin0 -> 593 bytes
-rw-r--r--web/i/feed.gifbin652 -> 0 bytes
-rw-r--r--web/i/feed.pngbin0 -> 764 bytes
-rwxr-xr-xweb/index.cgi35
-rw-r--r--web/js.js16
-rwxr-xr-xweb/rss.cgi6
-rw-r--r--web/xsl.xsl21
12 files changed, 182 insertions, 76 deletions
diff --git a/bin/canonicalise-csv b/bin/canonicalise-csv
index 72502e2d8..6163b3741 100755
--- a/bin/canonicalise-csv
+++ b/bin/canonicalise-csv
@@ -6,7 +6,7 @@
# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved.
# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
#
-# $Id: canonicalise-csv,v 1.1 2006-10-13 15:37:48 matthew Exp $
+# $Id: canonicalise-csv,v 1.2 2007-01-26 22:48:30 matthew Exp $
use strict;
require 5.8.0;
@@ -82,20 +82,20 @@ foreach my $type (@$types) {
my $areas_info = mySociety::MaPit::get_voting_areas_info($areas);
foreach my $id (keys %$areas_info) {
my $area_info = $areas_info->{$id};
- my $name = $area_info->{name};
- if ($name eq 'Durham City Council') {
- $out{$id} = $councils{'Durham City'};
- next;
- } elsif ($name eq 'Durham County Council') {
- $out{$id} = $councils{'Durham County'};
- next;
- }
- $name =~ s/( (Borough|City|District|County))* Council//;
+ my $name = $area_info->{name};
+ if ($name eq 'Durham City Council') {
+ $out{$id} = $councils{'Durham City'};
+ next;
+ } elsif ($name eq 'Durham County Council') {
+ $out{$id} = $councils{'Durham County'};
+ next;
+ }
+ $name =~ s/( (Borough|City|District|County))* Council//;
if ($councils{$name} && $councils{$name} =~ /@/) {
- $out{$id} = $councils{$name};
- } elsif ($councils{$name} || exists($councils{$name})) {
- push @missing, $id;
- }
+ $out{$id} = $councils{$name};
+ } elsif ($councils{$name} || exists($councils{$name})) {
+ push @missing, $id;
+ }
}
}
diff --git a/bin/load-contacts b/bin/load-contacts
index bac8497d3..d3f0681e2 100755
--- a/bin/load-contacts
+++ b/bin/load-contacts
@@ -6,7 +6,7 @@
# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved.
# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
#
-# $Id: load-contacts,v 1.1 2006-10-13 15:37:48 matthew Exp $
+# $Id: load-contacts,v 1.2 2007-01-26 22:48:30 matthew Exp $
use strict;
require 5.8.0;
@@ -42,7 +42,7 @@ while (<FP>) {
my ($id, $email) = split /,/;
dbh()->do("INSERT INTO contacts (area_id, email, editor, whenedited, note)
VALUES (?, ?, 'import', ms_current_timestamp(), 'Initial import')",
- {}, $id, $email);
+ {}, $id, $email);
}
dbh()->commit();
close(FP);
diff --git a/web/alert.cgi b/web/alert.cgi
index e9a173273..724e1731f 100755
--- a/web/alert.cgi
+++ b/web/alert.cgi
@@ -6,7 +6,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
#
-# $Id: alert.cgi,v 1.1 2007-01-26 01:01:23 matthew Exp $
+# $Id: alert.cgi,v 1.2 2007-01-26 22:48:31 matthew Exp $
use strict;
require 5.8.0;
@@ -15,12 +15,15 @@ require 5.8.0;
use FindBin;
use lib "$FindBin::Bin/../perllib";
use lib "$FindBin::Bin/../../perllib";
+use Digest::SHA1 qw(sha1_hex);
use Page;
use mySociety::Alert;
use mySociety::AuthToken;
use mySociety::Config;
use mySociety::DBHandle qw(dbh select_all);
+use mySociety::Util qw(is_valid_email);
+use mySociety::Web qw(ent);
BEGIN {
mySociety::Config::set_file("$FindBin::Bin/../conf/general");
@@ -36,10 +39,22 @@ BEGIN {
sub main {
my $q = shift;
my $out = '';
- if (my $token = $q->param('token')) {
+ if (my $signed_email = $q->param('signed_email')) {
+ my ($salt, $signed_email) = split /,/, $signed_email;
+ my $email = $q->param('email');
+ my $id = $q->param('id');
+ my $secret = scalar(dbh()->selectrow_array('select secret from secret'));
+ if ($signed_email eq sha1_hex("$id-$email-$salt-$secret")) {
+ my $alert_id = mySociety::Alert::create($email, 'new_updates', $id);
+ mySociety::Alert::confirm($alert_id);
+ $out .= '<p>You have successfully subscribed to that alert.</p>';
+ } else {
+ $out = '<p>We could not validate that alert.</p>';
+ }
+ } elsif (my $token = $q->param('token')) {
my $data = mySociety::AuthToken::retrieve('alert', $token);
- if (my $id = $data->{id}) {
- my $type = $data->{type};
+ if (my $id = $data->{id}) {
+ my $type = $data->{type};
if ($type eq 'subscribe') {
mySociety::Alert::confirm($id);
$out = '<p>You have successfully confirmed your alert.</p>';
@@ -55,24 +70,31 @@ and we'll look into it.
EOF
}
} elsif (my $email = $q->param('email')) {
- # XXX: Need to validate email
- my $type = $q->param('type');
- my $alert_id;
- if ($type eq 'updates') {
- my $id = $q->param('id');
- $alert_id = mySociety::Alert::create($email, 'new_updates', $id);
- } elsif ($type eq 'problems') {
- $alert_id = mySociety::Alert::create($email, 'new_problems');
- } else {
- throw mySociety::Alert::Error('Invalid type');
- }
- my %h = ();
- $h{url} = mySociety::Config::get('BASE_URL') . '/A/'
- . mySociety::AuthToken::store('alert', { id => $alert_id, type => 'subscribe' } );
- dbh()->commit();
- $out = Page::send_email($email, undef, 'alert-confirm', %h);
+ my @errors;
+ push @errors, 'Please enter a valid email address' unless is_valid_email($email);
+ if (@errors) {
+ $out = display_form($q, @errors);
+ } else {
+ my $type = $q->param('type');
+ my $alert_id;
+ if ($type eq 'updates') {
+ my $id = $q->param('id');
+ $alert_id = mySociety::Alert::create($email, 'new_updates', $id);
+ } elsif ($type eq 'problems') {
+ $alert_id = mySociety::Alert::create($email, 'new_problems');
+ } else {
+ throw mySociety::Alert::Error('Invalid type');
+ }
+ my %h = ();
+ $h{url} = mySociety::Config::get('BASE_URL') . '/A/'
+ . mySociety::AuthToken::store('alert', { id => $alert_id, type => 'subscribe' } );
+ dbh()->commit();
+ $out = Page::send_email($email, undef, 'alert-confirm', %h);
+ }
+ } elsif ($q->param('id')) {
+ $out = display_form($q);
} else {
- $out = 'This should probably show some sort of subscribe page.';
+ $out = '<p>Subscribe from a problem page!</p>';
}
print Page::header($q, 'Confirmation');
@@ -81,3 +103,25 @@ EOF
}
Page::do_fastcgi(\&main);
+# Updates only at present
+sub display_form {
+ my ($q, @errors) = @_;
+ my @vars = qw(id email);
+ my %input = map { $_ => $q->param($_) || '' } @vars;
+ my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars;
+ my $out = '';
+ if (@errors) {
+ $out .= '<ul id="error"><li>' . join('</li><li>', @errors) . '</li></ul>';
+ }
+ $out .= <<EOF;
+<p>Receive email when updates are left on this problem.
+<form action="alert" method="post">
+<label class="n" for="alert_email">Email:</label>
+<input type="text" name="email" id="alert_email" value="$input_h{email}" size="30">
+<input type="hidden" name="id" value="$input_h{id}">
+<input type="hidden" name="type" value="updates">
+<input type="submit" value="Subscribe">
+</form>
+EOF
+ return $out;
+}
diff --git a/web/confirm.cgi b/web/confirm.cgi
index 10f2b9656..6184f418f 100755
--- a/web/confirm.cgi
+++ b/web/confirm.cgi
@@ -6,7 +6,7 @@
# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved.
# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
#
-# $Id: confirm.cgi,v 1.6 2007-01-26 01:05:35 matthew Exp $
+# $Id: confirm.cgi,v 1.7 2007-01-26 22:48:31 matthew Exp $
use strict;
require 5.8.0;
@@ -15,11 +15,13 @@ require 5.8.0;
use FindBin;
use lib "$FindBin::Bin/../perllib";
use lib "$FindBin::Bin/../../perllib";
+use Digest::SHA1 qw(sha1_hex);
use Page;
use mySociety::AuthToken;
use mySociety::Config;
use mySociety::DBHandle qw(dbh select_all);
+use mySociety::Util qw(random_bytes);
BEGIN {
mySociety::Config::set_file("$FindBin::Bin/../conf/general");
@@ -42,22 +44,49 @@ sub main {
if ($id) {
if ($type eq 'update') {
dbh()->do("update comment set state='confirmed' where id=?", {}, $id);
- my ($id, $fixed, $reopen) = dbh()->selectrow_array("select problem_id,mark_fixed,mark_open from comment where id=?", {}, $id);
+ my ($email) = dbh()->selectrow_array("select email from comment where id=?", {}, $id);
+ my ($problem_id, $fixed, $reopen) = dbh()->selectrow_array("select problem_id,mark_fixed,mark_open from comment where id=?", {}, $id);
if ($fixed) {
- dbh()->do("update problem set state='fixed' where id=? and state='confirmed'", {}, $id);
+ dbh()->do("update problem set state='fixed' where id=? and state='confirmed'", {}, $problem_id);
} elsif ($reopen) {
- dbh()->do("update problem set state='confirmed' where id=? and state='fixed'", {}, $id);
+ dbh()->do("update problem set state='confirmed' where id=? and state='fixed'", {}, $problem_id);
}
- # XXX: Ask about email alert here, and RSS feed? Or should the form have another checkbox?
+ my $salt = unpack('h*', random_bytes(8));
+ my $secret = scalar(dbh()->selectrow_array('select secret from secret'));
+ my $signed_email = sha1_hex("$problem_id-$email-$salt-$secret");
$out = <<EOF;
-<p>You have successfully confirmed your update and you can now <a href="/?id=$id">view it on the site</a>.</p>
+<form action="/alert" method="post">
+<p>You have successfully confirmed your update and you can now <a href="/?id=$problem_id#update_$id">view it on the site</a>.</p>
+<p>You could also
+<a href="/rss/$problem_id">subscribe to the RSS feed</a> of updates on this problem,
+or
+<input type="hidden" name="signed_email" value="$salt,$signed_email">
+<input type="hidden" name="email" value="$email">
+<input type="hidden" name="id" value="$problem_id">
+<input type="hidden" name="type" value="updates">
+<input type="submit" value="sign up"> if you wish to receive updates by email.
+</p>
+</form>
EOF
} elsif ($type eq 'problem') {
dbh()->do("update problem set state='confirmed' where id=?", {}, $id);
- my $pc = dbh()->selectrow_array("select postcode from problem where id=?", {}, $id);
- # Ask about email alert here, and RSS feed?
+ my $email = dbh()->selectrow_array("select email from problem where id=?", {}, $id);
+ my $salt = unpack('h*', random_bytes(8));
+ my $secret = scalar(dbh()->selectrow_array('select secret from secret'));
+ my $signed_email = sha1_hex("$id-$email-$salt-$secret");
$out = <<EOF;
-<p>You have successfully confirmed your problem and you can now <a href="/?id=$id;pc=$pc">view it on the site</a>.</p>
+<form action="/alert" method="post">
+<p>You have successfully confirmed your problem and you can now <a href="/?id=$id">view it on the site</a>.</p>
+<p>You could also
+<a href="/rss/$id">subscribe to the RSS feed</a> of updates on this problem,
+or
+<input type="hidden" name="signed_email" value="$salt,$signed_email">
+<input type="hidden" name="email" value="$email">
+<input type="hidden" name="id" value="$id">
+<input type="hidden" name="type" value="updates">
+<input type="submit" value="sign up"> if you wish to receive updates by email.
+</p>
+</form>
EOF
}
dbh()->commit();
diff --git a/web/css.css b/web/css.css
index 2b1f93e08..98b2efe57 100644
--- a/web/css.css
+++ b/web/css.css
@@ -254,10 +254,23 @@ ol#current img {
font-weight: bolder;
}
-#comments div em {
+#updates div em {
border-bottom: dotted 1px #5e552b;
}
+#email_alert_box {
+ display:none;
+ position: absolute;
+ padding: 3px;
+ font-size:83%;
+ border:solid 1px #7399C3;
+ background-color: #eeeeff;
+ color: #000000;
+}
+#email_alert_box p {
+ margin: 0;
+}
+
#rss_items {
width:62%;
float:left;
diff --git a/web/i/email.png b/web/i/email.png
new file mode 100644
index 000000000..030eafde6
--- /dev/null
+++ b/web/i/email.png
Binary files differ
diff --git a/web/i/feed.gif b/web/i/feed.gif
deleted file mode 100644
index b0e4adf1d..000000000
--- a/web/i/feed.gif
+++ /dev/null
Binary files differ
diff --git a/web/i/feed.png b/web/i/feed.png
new file mode 100644
index 000000000..1679ab05b
--- /dev/null
+++ b/web/i/feed.png
Binary files differ
diff --git a/web/index.cgi b/web/index.cgi
index 55538ac19..545899a8c 100755
--- a/web/index.cgi
+++ b/web/index.cgi
@@ -6,7 +6,7 @@
# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved.
# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
#
-# $Id: index.cgi,v 1.58 2007-01-26 14:19:42 matthew Exp $
+# $Id: index.cgi,v 1.59 2007-01-26 22:48:31 matthew Exp $
# TODO
# Nothing is done about the update checkboxes - not stored anywhere on anything!
@@ -411,7 +411,7 @@ EOF
$out .= <<EOF;
</ol>
<h2>Recent problems reported within 10km</h2>
- <p><a href="/rss/$x,$y"><img align="right" src="/i/feed.gif" width="16" height="16" alt="RSS feed" border="0"></a></p>
+ <p><a href="/rss/$x,$y"><img align="right" src="/i/feed.png" width="16" height="16" title="RSS feed of recent local problems" alt="RSS feed" border="0"></a></p>
<ol id="current" start="$list_start">
EOF
foreach (@$current) {
@@ -487,6 +487,19 @@ EOF
my $back = NewURL($q, id=>undef, x=>$x_tile, y=>$y_tile);
$out .= '<p style="padding-bottom: 0.5em; border-bottom: dotted 1px #999999;" align="right"><a href="' . $back . '">Back to listings</a></p>';
+ $out .= '<a href="/rss/'.$input_h{id}.'"><img align="right" src="/i/feed.png" width="16" height="16" title="RSS feed" alt="RSS feed of updates to this problem" border="0"></a> ';
+ $out .= '<a id="email_alert" href="/alert?type=updates;id='.$input_h{id}.'"><img align="right" src="/i/email.png" width="16" height="16" title="Email alerts" alt="Email alerts of updates to this problem" border="0"></a>';
+ $out .= <<EOF;
+<form action="alert" method="post" id="email_alert_box">
+<p>Receive email when updates are left on this problem</p>
+<label class="n" for="alert_email">Email:</label>
+<input type="text" name="email" id="alert_email" value="$input_h{email}" size="30">
+<input type="hidden" name="id" value="$input_h{id}">
+<input type="hidden" name="type" value="updates">
+<input type="submit" value="Subscribe">
+</form>
+EOF
+
# Display updates
my $updates = select_all(
"select id, name, extract(epoch from created) as created, text, mark_fixed, mark_open
@@ -494,10 +507,9 @@ EOF
order by created desc", $input{id});
if (@$updates) {
$out .= '<div id="updates">';
- $out .= '<a href="/rss/'.$input_h{id}.'"><img align="right" src="/i/feed.gif" width="16" height="16" alt="RSS feed of updates to this problem" border="0"></a>';
- $out .= '<h2>Updates</h2>';
+ $out .= '<h2>Updates</h2>';
foreach my $row (@$updates) {
- $out .= "<div><em>Posted by $row->{name} at " . prettify_epoch($row->{created});
+ $out .= "<div><a name=\"update_$row->{id}\"></a><em>Posted by $row->{name} at " . prettify_epoch($row->{created});
$out .= ', marked fixed' if ($row->{mark_fixed});
$out .= ', reopened' if ($row->{mark_open});
$out .= '</em>';
@@ -505,19 +517,6 @@ EOF
}
$out .= '</div>';
}
- $out .= <<EOF;
-<h2>Follow this problem</h2>
-<ul>
-<li>Receive email when updates are left on this problem.
-<form action="alert" method="post">
-<label class="n" for="alert_email">Email:</label>
-<input type="text" name="email" id="alert_email" value="$input_h{email}" size="30">
-<input type="hidden" name="id" value="$input_h{id}">
-<input type="hidden" name="type" value="updates">
-<input type="submit" value="Subscribe">
-</form>
-</ul>
-EOF
$out .= '<h2>Provide an update</h2>';
if (@errors) {
$out .= '<ul id="error"><li>' . join('</li><li>', @errors) . '</li></ul>';
diff --git a/web/js.js b/web/js.js
index fc1e7409b..45140816a 100644
--- a/web/js.js
+++ b/web/js.js
@@ -34,6 +34,22 @@ YAHOO.util.Event.onContentReady('mapForm', function() {
}
});
+YAHOO.util.Event.onContentReady('email_alert', function() {
+ this.onclick = function() {
+ if (this.on) {
+ YAHOO.util.Dom.setStyle('email_alert_box', 'display', 'none');
+ this.on = false;
+ } else {
+ var pos = YAHOO.util.Dom.getXY(this);
+ pos[0] -= 20; pos[1] += 20;
+ YAHOO.util.Dom.setStyle('email_alert_box', 'display', 'block');
+ YAHOO.util.Dom.setXY('email_alert_box', pos);
+ this.on = true;
+ }
+ return false;
+ }
+});
+
// I love the global
var tile_x = 0;
var tile_y = 0;
diff --git a/web/rss.cgi b/web/rss.cgi
index 0fd0e8602..6c25b56fa 100755
--- a/web/rss.cgi
+++ b/web/rss.cgi
@@ -6,7 +6,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
#
-# $Id: rss.cgi,v 1.2 2007-01-26 14:19:42 matthew Exp $
+# $Id: rss.cgi,v 1.3 2007-01-26 22:48:31 matthew Exp $
use strict;
require 5.8.0;
@@ -40,13 +40,13 @@ sub main {
if ($type eq 'local_problems') {
my $x = $q->param('x');
my $y = $q->param('y');
- my $qs = 'x='.$x.';y='.$y;
+ my $qs = 'x='.$x.';y='.$y;
$x = ($x * 5000 / 31);
$y = ($y * 5000 / 31);
mySociety::Alert::generate_rss($type, $qs, $x, $y);
} elsif ($type eq 'new_updates') {
my $id = $q->param('id');
- my $qs = 'id='.$id;
+ my $qs = 'id='.$id;
mySociety::Alert::generate_rss($type, $qs, $id);
} elsif ($type eq 'new_problems') {
mySociety::Alert::generate_rss($type, '');
diff --git a/web/xsl.xsl b/web/xsl.xsl
index 1572193b4..85334ae18 100644
--- a/web/xsl.xsl
+++ b/web/xsl.xsl
@@ -36,14 +36,14 @@ href="https://secure.mysociety.org/cvstrac/dir?d=mysociety/services/TilMa">code<
<h1>What is this page?</h1>
<p>This is an RSS feed from the Neighbourhood Fix-It website. RSS feeds allow you to stay up to date with the latest changes and additions to the site.
To subscribe to it, you will need a News Reader or other similar device.
- <br/>
- <a href="http://news.bbc.co.uk/1/hi/help/3223484.stm#whatisrss"><strong>Help</strong>, I don't know what a news reader is and still don't know what this is about (from the BBC).</a></p>
+ <br/>
+ <a href="http://news.bbc.co.uk/1/hi/help/3223484.stm#whatisrss"><strong>Help</strong>, I don't know what a news reader is and still don't know what this is about (from the BBC).</a></p>
</div>
<p>Below is the latest content available from this feed,
<a href="#" class="item"><img height="16" hspace="5" vspace="0" border="0" width="16" alt="RSS News feeds" src="/i/feed.gif" title="RSS News feeds" /><xsl:value-of select="$title"/></a>.</p>
- <div id="rss_items"><ul><xsl:apply-templates select="item"/></ul></div>
+ <div id="rss_items"><ul><xsl:apply-templates select="item"/></ul></div>
<div id="rss_rhs">
<h2 style="margin:0">Subscribe to this feed</h2>
<p>You can subscribe to this RSS feed in a number of ways, including the following:</p>
@@ -54,11 +54,16 @@ href="https://secure.mysociety.org/cvstrac/dir?d=mysociety/services/TilMa">code<
</ul>
<h3>One-click subscriptions</h3>
<p>If you use one of the following web-based News Readers, click on the appropriate button to subscribe to the RSS feed.</p>
- <a href="http://www.bloglines.com/sub/{uri}"><img height="18" width="91" vspace="3" border="0" alt="bloglines" src="http://newsimg.bbc.co.uk/shared/bsp/xsl/rss/img/bloglines.gif" /></a><br />
- <a href="http://www.feedzilla.com/mini/default.asp?ref=bbc&amp;url={uri}"><img height="22" width="93" vspace="3" border="0" alt="feedzilla" src="http://newsimg.bbc.co.uk/shared/bsp/xsl/rss/img/feedzilla.gif" /></a><br />
- <a href="http://add.my.yahoo.com/rss?url={uri}"><img height="17" width="91" vspace="3" border="0" alt="my yahoo" src="http://newsimg.bbc.co.uk/shared/bsp/xsl/rss/img/myyahoo.gif" /></a><br />
-<a href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url={uri}"><img height="17" width="91" vspace="3" border="0" alt="newsgator" src="http://newsimg.bbc.co.uk/shared/bsp/xsl/rss/img/newsgator.gif" /></a><br />
-<a href="http://www.live.com/?add={uri}"><img height="17" width="91" vspace="3" border="0" alt="Microsoft Live" src="http://newsimg.bbc.co.uk/shared/bsp/xsl/rss/img/windowslive.gif" /></a><br />
+<a href="http://www.bloglines.com/sub/{uri}"><img height="18" width="91" hspace="3" vspace="3" border="0" alt="bloglines" src="http://newsimg.bbc.co.uk/shared/bsp/xsl/rss/img/bloglines.gif" /></a>
+<a href="http://www.feedzilla.com/mini/default.asp?ref=bbc&amp;url={uri}"><img height="22" width="93" hspace="3" vspace="3" border="0" alt="feedzilla" src="http://newsimg.bbc.co.uk/shared/bsp/xsl/rss/img/feedzilla.gif" /></a>
+<a href="http://add.my.yahoo.com/rss?url={uri}"><img height="17" width="91" hspace="3" vspace="3" border="0" alt="my yahoo" src="http://newsimg.bbc.co.uk/shared/bsp/xsl/rss/img/myyahoo.gif" /></a>
+<a href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url={uri}"><img height="17" width="91" hspace="3" vspace="3" border="0" alt="newsgator" src="http://newsimg.bbc.co.uk/shared/bsp/xsl/rss/img/newsgator.gif" /></a>
+<a href="http://www.live.com/?add={uri}"><img height="17" width="91" hspace="3" vspace="3" border="0" alt="Microsoft Live" src="http://newsimg.bbc.co.uk/shared/bsp/xsl/rss/img/windowslive.gif" /></a>
+<a href="http://feeds.my.aol.com/add.jsp?url={uri}"><img hspace="3" src="http://o.aolcdn.com/myfeeds/html/vis/myaol_cta1.gif" alt="Add to My AOL" border="0"/></a>
+<a href="http://www.rojo.com/add-subscription?resource={uri}"><img hspace="3" src="http://www.rojo.com/corporate/images/add-to-rojo.gif" alt="Subscribe in Rojo"/></a>
+<a href="http://www.netvibes.com/subscribe.php?url={uri}"><img hspace="3" src="http://www.netvibes.com/img/add2netvibes.gif" alt="Add to netvibes" /></a>
+<a href="http://fusion.google.com/add?feedurl={uri}"><img hspace="3" src="http://buttons.googlesyndication.com/fusion/add.gif" width="104" height="17" alt="Add to Google"/></a>
+<a href="http://www.pageflakes.com/subscribe.aspx?url={uri}"><img hspace="3" src="http://www.pageflakes.com/subscribe2.gif" border="0"/></a>
<ul>
<li><a href="http://google.com/reader/view/feed/{uri}">Google Reader</a></li>