This commit is contained in:
2019-02-06 00:49:12 +03:00
commit 8dbb1bb605
4796 changed files with 506072 additions and 0 deletions

View 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?>

View 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?>

View 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?>

View 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?>