112 lines
4.2 KiB
Plaintext
112 lines
4.2 KiB
Plaintext
|
<?_code
|
||
|
{
|
||
|
use strict;
|
||
|
|
||
|
BML::set_content_type("text/xml");
|
||
|
|
||
|
my $recent = LJ::MemCache::get("blob:ljcom_latestposts2") || [];
|
||
|
|
||
|
my $ret = "<?xml version='1.0'?>\n";
|
||
|
$ret .= <<"EOT";
|
||
|
<!--You can poll this feed as often as you like, but please don't spider the links.
|
||
|
Mail dev\@livejournal.com if you have any questions/interesting research ideas.-->
|
||
|
EOT
|
||
|
$ret .= "<rdf:RDF ".
|
||
|
"xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' ".
|
||
|
"xmlns:dc='http://purl.org/dc/elements/1.1/' ".
|
||
|
"xmlns:lj='http://livejournal.org/rss/lj/1.0/' ".
|
||
|
"xmlns='http://purl.org/rss/1.0/'>\n";
|
||
|
|
||
|
$ret .= "<channel rdf:about='$LJ::SITEROOT/stats/latest-rss.bml'><title>Latest $LJ::SITENAME Posts</title><link>$LJ::SITEROOT/stats/latest.bml</link><description>Latest public posts at $LJ::SITENAME.</description>\n";
|
||
|
|
||
|
# setup for security logging
|
||
|
my %securities = (
|
||
|
public => 0,
|
||
|
private => 0,
|
||
|
friends => 0,
|
||
|
custom => 0,
|
||
|
);
|
||
|
|
||
|
# retrieve posts.
|
||
|
my @postids;
|
||
|
foreach my $p (@$recent) {
|
||
|
$securities{$p->{security}}++;
|
||
|
next unless $p->{security} eq 'public';
|
||
|
$p->{ditemid} = $p->{itemid}*256 + $p->{anum};
|
||
|
$p->{urn} = "urn:$LJ::DOMAIN:entry:$p->{journalu}{user}:$p->{ditemid}";
|
||
|
|
||
|
push @postids, [ $p->{clusterid}, $p->{journalu}{userid}, $p->{itemid} ];
|
||
|
}
|
||
|
my $rawposts = LJ::get_posts_raw({memcache_only=>1}, @postids);
|
||
|
|
||
|
my $rdftoc = "<items><rdf:Seq>\n";
|
||
|
my $rdfitems = "";
|
||
|
|
||
|
foreach my $p (@$recent) {
|
||
|
next unless $p->{security} eq 'public';
|
||
|
my $uj = $p->{'journalu'};
|
||
|
my $up = $p->{'journalp'};
|
||
|
my $id = "$uj->{userid}:$p->{itemid}";
|
||
|
my $props = $rawposts->{prop}{$id};
|
||
|
|
||
|
# we shouldn't expect every post to be in the memcache.
|
||
|
next unless $rawposts->{text}{$id};
|
||
|
|
||
|
# skipping unknown8bit users sucks, but we can't load users here.
|
||
|
next if $props->{unknown8bit};
|
||
|
|
||
|
$rdftoc .= " <rdf:li resource='$p->{urn}' />\n";
|
||
|
|
||
|
my $url = LJ::journal_base($uj) . "/$p->{ditemid}.html";
|
||
|
my ($subject, $body) = @{$rawposts->{text}{$id}};
|
||
|
|
||
|
$rdfitems .= "<item rdf:about='$p->{urn}'>\n";
|
||
|
|
||
|
# first, the required RDF elements.
|
||
|
# we use title to represent all the metadata in one string,
|
||
|
# then dublin core for the data in pieces.
|
||
|
$rdfitems .= "<title>$up->{'user'}";
|
||
|
$rdfitems .= " (in $uj->{'user'})" if $uj->{userid} != $up->{userid};
|
||
|
$rdfitems .= ": " . LJ::exml($subject) if $subject;
|
||
|
$rdfitems .= "</title>\n";
|
||
|
$rdfitems .= "<description>" . LJ::exml($body) . "</description>\n";
|
||
|
$rdfitems .= "<category>$_</category>\n" foreach map { LJ::exml($_) } @{$p->{tags} || []};
|
||
|
$rdfitems .= "<link>$url</link>\n";
|
||
|
|
||
|
# use dc for the rest.
|
||
|
$rdfitems .= "<dc:title>" . LJ::exml($subject) . "</dc:title>\n" if $subject;
|
||
|
$rdfitems .= "<dc:creator>" . LJ::exml($up->{name}) . " ($up->{user})</dc:creator>\n";
|
||
|
$rdfitems .= "<dc:publisher>" . LJ::exml($uj->{user}) . "</dc:publisher>\n"
|
||
|
if $uj->{userid} != $up->{userid};
|
||
|
$rdfitems .= "<dc:date>" . LJ::time_to_w3c($p->{timepost}) . "Z</dc:date>\n";
|
||
|
|
||
|
# and lj for the lj-specific data.
|
||
|
my $mood = $props->{current_mood};
|
||
|
$mood ||= LJ::mood_name($props->{current_moodid}) if $props->{current_moodid};
|
||
|
|
||
|
my $moodid = " id='$props->{current_moodid}'" if $props->{current_moodid};
|
||
|
$rdfitems .= "<lj:mood$moodid>" . LJ::exml($mood) . "</lj:mood>\n"
|
||
|
if $mood or $moodid;
|
||
|
$rdfitems .= "<lj:music>" . LJ::exml($props->{current_music}) . "</lj:music>\n"
|
||
|
if $props->{current_music};
|
||
|
$rdfitems .= "<lj:pickeyword>" . LJ::exml($props->{picture_keyword}) . "</lj:pickeyword>\n"
|
||
|
if $props->{picture_keyword};
|
||
|
|
||
|
$rdfitems .= "</item>\n";
|
||
|
}
|
||
|
$rdftoc .= "</rdf:Seq></items></channel>\n";
|
||
|
|
||
|
$ret .= $rdftoc . $rdfitems;
|
||
|
$ret .= "</rdf:RDF>\n";
|
||
|
|
||
|
$ret .= <<"EOT";
|
||
|
<!-- Security breakdown:
|
||
|
public: $securities{public} (shown above)
|
||
|
private: $securities{private}
|
||
|
friends: $securities{friends}
|
||
|
custom: $securities{custom} -->
|
||
|
EOT
|
||
|
return BML::noparse($ret);
|
||
|
}
|
||
|
_code?>
|