X-Git-Url: http://git.bytex64.net/?a=blobdiff_plain;f=rss.cgi;h=3eed7e26bd90408dc44cb10c240e29d0164b8820;hb=948ce5be6ef6bba36edfb544565ca22e316afb0a;hp=ca2a7797fe7e0e2f7b49e3b030dfd85903d73923;hpb=4d670f36be4aa9843fd429f545fe340cbb2e4d7f;p=blerg.git diff --git a/rss.cgi b/rss.cgi index ca2a779..3eed7e2 100755 --- a/rss.cgi +++ b/rss.cgi @@ -3,6 +3,7 @@ use CGI::Fast qw/:cgi/; use Blerg::Database; use URI::Escape; use POSIX qw/strftime/; +use MIME::Base64; use strict; my $baseurl = Blerg::Database::constant('BASEURL'); @@ -15,6 +16,35 @@ sub xml_escape { return $_; } +sub decode_basic_auth { + my ($q) = @_; + + my ($method, $base64) = split(/\s+/, $q->http('Authorization')); + if (!defined $method) { + return; + } elsif ($method ne 'Basic') { + return; + } + + my ($username, $password) = split(':', decode_base64($base64), 2); + if (!defined $username) { + return; + } + + return ($username, $password); +} + +sub print_401 { + print header(-type => 'text/html', + -status => '401 Unauthorized', + -WWW_Authenticate => 'Basic realm="blerg"'); + print < +

401 Unauthorized

+Please log in. +DOC +} + sub print_404 { print header(-type => 'text/html', -status => '404 Not Found'); @@ -25,6 +55,30 @@ Not Found DOC } +sub fetch_records { + my @out; + local $_; + + foreach (@_) { + my $b = Blerg::Database->open_existing($_->{author}); + my $data = $b->fetch($_->{record}); + if (!defined $data) { + $b->close; + next; + } + my $timestamp = $b->timestamp($_->{record}); + $b->close; + push @out, { + author => $_->{author}, + record => $_->{record}, + data => $data, + timestamp => $timestamp, + }; + } + + return @out; +} + sub print_rss { my ($type, $name, @items) = @_; @@ -32,6 +86,9 @@ sub print_rss { if ($type eq 'user') { $title = "${name}'s blërg"; $link = "${baseurl}#$name"; + } elsif ($type eq 'feed') { + $title = "${name}'s stalking feed"; + $link = "${baseurl}#/feed"; } elsif ($type eq 'tag' || $type eq 'ref') { $title = $name; my $basename = $name; @@ -49,13 +106,16 @@ sub print_rss { HEADER for my $i (@items) { - my $data = xml_escape($i->{data}); - my $post_time = strftime("%a, %d %b %Y %H:%M:%S %Z", localtime($i->{timestamp})); my $author = defined $i->{author} ? $i->{author} : $name; + my $data = xml_escape(qq{\@$author
$i->{data}}); + my $title = xml_escape(substr($i->{data}, 0, 27)) . "..."; + my $post_time = strftime("%a, %d %b %Y %H:%M:%S %Z", localtime($i->{timestamp})); print < + $title $post_time ${baseurl}get/$author/$i->{record} + ${baseurl}#$author/$i->{record} $data ITEM @@ -69,10 +129,28 @@ FOOTER REQUEST: while (my $q = new CGI::Fast) { + $q->charset('utf8'); my @path = split('/', $ENV{PATH_INFO}); shift @path; - if (@path == 1) { + if ($path[0] eq 'feed') { + my ($username, $password) = decode_basic_auth($q); + if (!defined $username) { + print_401; + next REQUEST; + } + if (!Blerg::Database::auth_check_password($username, $password)) { + print_401; + next REQUEST; + } + + my $b = Blerg::Database->open_existing($username); + my @list = fetch_records($b->subscription_list()); + $b->close; + + print header(-type => 'application/rss+xml'); + print_rss(feed => $username, @list); + } elsif (@path == 1) { # Assume this is a username; redirect to /user/ my $username = $path[0]; my $b = Blerg::Database->open_existing($username); @@ -87,7 +165,7 @@ while (my $q = new CGI::Fast) { # And present the content in case their client is broken my $i = { record => '?failed_redirect', - timestamp => time, + timestamp => time, data => qq{Your RSS aggregator is dumb and isn't following 301 redirects. Please manually redirect it here: ${baseurl}rss/user/$username} }; print_rss(user => $username, $i); @@ -109,29 +187,18 @@ while (my $q = new CGI::Fast) { } ($n > 50 ? $n - 50 : 0)..$n; $b->close; print_rss(user => $username, @list); - } elsif ($path[0] eq 'tag') { + } elsif ($path[0] eq 'tag' || $path[0] eq 'ref') { my $tag = $path[1]; - $tag =~ s/^H/#/; - my @list = Blerg::Database::tag_list($tag, 0, -1); - @list = map { - my $b = Blerg::Database->open_existing($_->{author}); - my $data = $b->fetch($_->{record}); - my $timestamp = $b->timestamp($_->{record}); - $b->close; - { - author => $_->{author}, - record => $_->{record}, - data => $data, - timestamp => $timestamp, - }; - } @list; - print header(-type => 'application/rss+xml'); - if (substr($tag, 0, 1) eq '#') { - print_rss(tag => $tag, @list); + my $atag; + if ($path[0] eq 'tag') { + $atag = '#' . $tag; } else { - print_rss(ref => $tag, @list); + $atag = '@' . $tag; } - } elsif ($path[0] eq 'ref') { - } elsif ($path[0] eq 'feed') { + + my @list = fetch_records(Blerg::Database::tag_list($atag, 0, -1)); + + print header(-type => 'application/rss+xml'); + print_rss($path[0] => $atag, @list); } }