init
This commit is contained in:
39
ljcom/htdocs/stats/latest-img.bml
Normal file
39
ljcom/htdocs/stats/latest-img.bml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?_code
|
||||
{
|
||||
use strict;
|
||||
|
||||
BML::set_content_type("text/xml");
|
||||
BML::noparse();
|
||||
|
||||
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.
|
||||
See $LJ::SITEROOT/bots/ for more information.
|
||||
Mail dev\@livejournal.com if you have any questions/interesting research ideas.-->
|
||||
EOT
|
||||
|
||||
$ret .= "<livejournal>\n";
|
||||
|
||||
my $rimg = LJ::MemCache::get("blob:ljcom_latestimg");
|
||||
unless (ref $rimg eq "ARRAY" && @$rimg) {
|
||||
$ret .= "<!-- no images found -->\n";
|
||||
$ret .= "</livejournal>\n";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$ret .= "<recent-images>\n";
|
||||
|
||||
foreach my $ri (reverse @$rimg) {
|
||||
my ($img, $ju, $jitemid, $anum) = @$ri;
|
||||
$img = LJ::exml($img);
|
||||
my $url = LJ::item_link($ju, $jitemid, $anum);
|
||||
$ret .= "<recent-image img='$img' url='$url' />\n";
|
||||
}
|
||||
|
||||
|
||||
$ret .= "</recent-images>\n";
|
||||
$ret .= "</livejournal>\n";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
_code?>
|
||||
111
ljcom/htdocs/stats/latest-rss.bml
Normal file
111
ljcom/htdocs/stats/latest-rss.bml
Normal file
@@ -0,0 +1,111 @@
|
||||
<?_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?>
|
||||
90
ljcom/htdocs/stats/latest.bml
Normal file
90
ljcom/htdocs/stats/latest.bml
Normal file
@@ -0,0 +1,90 @@
|
||||
<?page
|
||||
title=>Latest Posts
|
||||
head<=
|
||||
<style>
|
||||
div.entry { margin-left: 20px; }
|
||||
</style>
|
||||
<=head
|
||||
body<=
|
||||
<?_code
|
||||
{
|
||||
use strict;
|
||||
|
||||
LJ::set_active_crumb('latestposts');
|
||||
|
||||
my $recent;
|
||||
my $stat;
|
||||
|
||||
$recent = LJ::MemCache::get("blob:ljcom_latestposts2");
|
||||
$stat = LJ::MemCache::get("blob:ljcom_latestposts_stats");
|
||||
return "No posts found." unless ref $recent eq "ARRAY";
|
||||
|
||||
my $ret;
|
||||
|
||||
if (ref $stat eq 'ARRAY' and my $delta = $stat->[1] - $stat->[2]) {
|
||||
|
||||
my $rate_sec = $stat->[0] / $delta;
|
||||
|
||||
my $rate_min = $rate_sec * 60;
|
||||
my $fmt_min = $rate_min > 10 ? "%.0f" : "%.2f";
|
||||
|
||||
my $rate_hour = $rate_min * 60;
|
||||
my $fmt_hour = $rate_hour > 10 ? "%.0f" : "%.2f";
|
||||
|
||||
my $post_min = sprintf($fmt_min, $rate_min);
|
||||
my $post_hour = sprintf($fmt_hour, $rate_hour);
|
||||
|
||||
$ret .= "Current posting stats: <b>$post_hour</b> per hour, <b>$post_min</b> per minute\n";
|
||||
}
|
||||
|
||||
my @postids;
|
||||
foreach my $p (@$recent) {
|
||||
next unless $p->{security} eq 'public';
|
||||
$p->{ditemid} = $p->{itemid}*256 + $p->{anum};
|
||||
push @postids, [ $p->{clusterid}, $p->{journalu}{userid}, $p->{itemid} ];
|
||||
}
|
||||
my $rawposts = LJ::get_posts_raw({memcache_only=>1}, @postids);
|
||||
|
||||
$ret .= "<a href='latest-rss.bml'><img src=\"$LJ::IMGPREFIX/xml.gif\" width='36' height='14' alt='RSS version' align='right' border='0' /></a>";
|
||||
$ret .= "<table border='0' cellpadding='4' style='margin-top: 10px;'>\n";
|
||||
foreach my $p (@$recent) {
|
||||
next unless $p->{security} eq 'public';
|
||||
my $uj = $p->{'journalu'};
|
||||
my $up = $p->{'journalp'};
|
||||
my $id = "$uj->{userid}:$p->{itemid}";
|
||||
|
||||
# we shouldn't expect every post to be in the memcache.
|
||||
next unless $rawposts->{text}{$id};
|
||||
|
||||
# this sucks, but we can't load users here.
|
||||
next if $rawposts->{prop}{$id}{unknown8bit};
|
||||
|
||||
my $url = LJ::journal_base($uj) . "/$p->{'ditemid'}.html";
|
||||
my ($subject, $body) = @{$rawposts->{text}{$id}};
|
||||
|
||||
$ret .= "<tr valign='top'><td nowrap='nowrap'><a href=\"$url\">" . substr(scalar(gmtime($p->{timepost})), 4, 12) . "</a></td>";
|
||||
$ret .= "<td>\n";
|
||||
|
||||
$ret .= LJ::ljuser($up->{user});
|
||||
if ($up->{userid} != $uj->{userid}) {
|
||||
$ret .= " (in " . LJ::ljuser($uj->{user}, {type => $uj->{journaltype}}) . ")";
|
||||
}
|
||||
$ret .= ":<br />\n";
|
||||
|
||||
$ret .= "<div class='entry'>";
|
||||
LJ::CleanHTML::clean_subject(\$subject);
|
||||
LJ::CleanHTML::clean_event(\$body, {'cuturl' => LJ::item_link($uj, $p->{'itemid'}, $p->{'anum'})});
|
||||
$ret .= "$subject<br />\n" if $subject;
|
||||
$ret .= $body;
|
||||
$ret .= "</div></td></tr>\n";
|
||||
|
||||
}
|
||||
$ret .= "</table>\n";
|
||||
|
||||
BML::noparse();
|
||||
return $ret;
|
||||
}
|
||||
_code?>
|
||||
|
||||
<=body
|
||||
page?>
|
||||
34
ljcom/htdocs/stats/weblog-updates-xml.bml
Normal file
34
ljcom/htdocs/stats/weblog-updates-xml.bml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?_code
|
||||
{
|
||||
use strict;
|
||||
|
||||
BML::set_content_type("text/xml");
|
||||
|
||||
my $recent = LJ::MemCache::get("blob:ljcom_latestposts2") || [];
|
||||
my $ret;
|
||||
|
||||
$ret .= "<?xml version='1.0' encoding='utf-8'?>\n";
|
||||
$ret .= <<"EOT";
|
||||
<!-- You can poll this feed often, but spider smartly. We watch
|
||||
and ban stupid bots. Your user agent should have contact/project info.
|
||||
See $LJ::SITEROOT/bots/ -->
|
||||
EOT
|
||||
|
||||
$ret .= "<weblogUpdates version='1'>\n";
|
||||
|
||||
# retrieve posts.
|
||||
my @postids;
|
||||
my %done; # journalid -> 1
|
||||
foreach my $p (@$recent) {
|
||||
next unless $p->{security} eq 'public';
|
||||
my $u = $p->{journalu} or next;
|
||||
next if $done{$u->{userid}}++;
|
||||
my $base = LJ::journal_base($u);
|
||||
$ret .= "<weblog url='$base/' rss='$base/data/rss' when='$p->{timepost}' />\n";
|
||||
}
|
||||
|
||||
$ret .= "</weblogUpdates>\n";
|
||||
|
||||
return BML::noparse($ret);
|
||||
}
|
||||
_code?>
|
||||
Reference in New Issue
Block a user