init
This commit is contained in:
232
local/cgi-bin/LJ/S2/DayPage.pm
Executable file
232
local/cgi-bin/LJ/S2/DayPage.pm
Executable file
@@ -0,0 +1,232 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
use strict;
|
||||
package LJ::S2;
|
||||
|
||||
sub DayPage
|
||||
{
|
||||
my ($u, $remote, $opts) = @_;
|
||||
|
||||
my $p = Page($u, $opts);
|
||||
$p->{'_type'} = "DayPage";
|
||||
$p->{'view'} = "day";
|
||||
$p->{'entries'} = [];
|
||||
|
||||
my $user = $u->{'user'};
|
||||
my $journalbase = LJ::journal_base($user, $opts->{'vhost'});
|
||||
|
||||
if ($u->{'journaltype'} eq "R" && $u->{'renamedto'} ne "") {
|
||||
$opts->{'redir'} = LJ::journal_base($u->{'renamedto'}, $opts->{'vhost'}) .
|
||||
"/calendar" . $opts->{'pathextra'};
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($u->{'opt_blockrobots'}) {
|
||||
$p->{'head_content'} .= LJ::robot_meta_tags();
|
||||
}
|
||||
|
||||
my $get = $opts->{'getargs'};
|
||||
|
||||
my $month = $get->{'month'};
|
||||
my $day = $get->{'day'};
|
||||
my $year = $get->{'year'};
|
||||
my @errors = ();
|
||||
|
||||
if ($opts->{'pathextra'} =~ m!^/(\d\d\d\d)/(\d\d)/(\d\d)\b!) {
|
||||
($month, $day, $year) = ($2, $3, $1);
|
||||
}
|
||||
|
||||
$opts->{'errors'} = [];
|
||||
if ($year !~ /^\d+$/) { push @{$opts->{'errors'}}, "Corrupt or non-existant year."; }
|
||||
if ($month !~ /^\d+$/) { push @{$opts->{'errors'}}, "Corrupt or non-existant month."; }
|
||||
if ($day !~ /^\d+$/) { push @{$opts->{'errors'}}, "Corrupt or non-existant day."; }
|
||||
if ($month < 1 || $month > 12 || int($month) != $month) { push @{$opts->{'errors'}}, "Invalid month."; }
|
||||
if ($year < 1970 || $year > 2038 || int($year) != $year) { push @{$opts->{'errors'}}, "Invalid year: $year"; }
|
||||
if ($day < 1 || $day > 31 || int($day) != $day) { push @{$opts->{'errors'}}, "Invalid day."; }
|
||||
if (scalar(@{$opts->{'errors'}})==0 && $day > LJ::days_in_month($month, $year)) { push @{$opts->{'errors'}}, "That month doesn't have that many days."; }
|
||||
return if @{$opts->{'errors'}};
|
||||
|
||||
$p->{'date'} = Date($year, $month, $day);
|
||||
# mysqldate_to_time(): ^(\d\d\d\d)-(\d\d)-(\d\d)(?: (\d\d):(\d\d)(?::(\d\d))?)?$/ -> unixtime, with check.
|
||||
# why not using get_recent_items() ?
|
||||
|
||||
#use Time::HiRes qw(gettimeofday tv_interval);
|
||||
#my $t0 = [gettimeofday];
|
||||
#my @elapsed;
|
||||
#push @elapsed, (tv_interval ($t0));
|
||||
#print STDERR "@elapsed \n";
|
||||
|
||||
my $secwhere = "AND security='public'";
|
||||
my $viewall = 0;
|
||||
my $viewsome = 0; # see public posts from suspended users
|
||||
if ($remote) {
|
||||
|
||||
# do they have the viewall priv?
|
||||
if ($get->{'viewall'} && LJ::check_priv($remote, "canview")) {
|
||||
LJ::statushistory_add($u->{'userid'}, $remote->{'userid'},
|
||||
"viewall", "day: $user, statusvis: $u->{'statusvis'}");
|
||||
$viewall = LJ::check_priv($remote, 'canview', '*');
|
||||
$viewsome = $viewall || LJ::check_priv($remote, 'canview', 'suspended');
|
||||
}
|
||||
|
||||
if ($remote->{'userid'} == $u->{'userid'} || $viewall) {
|
||||
$secwhere = ""; # see everything
|
||||
} elsif ($remote->{'journaltype'} eq 'P' || $remote->{'journaltype'} eq 'I') {
|
||||
my $gmask = LJ::get_groupmask($u, $remote);
|
||||
$secwhere = "AND (security='public' OR (security='usemask' AND allowmask & $gmask))"
|
||||
if $gmask;
|
||||
}
|
||||
}
|
||||
|
||||
my $dbcr = LJ::get_cluster_reader($u);
|
||||
unless ($dbcr) {
|
||||
push @{$opts->{'errors'}}, "Database temporarily unavailable";
|
||||
return;
|
||||
}
|
||||
|
||||
# load the log items
|
||||
my $dateformat = "%Y %m %d %H %i %s %w"; # yyyy mm dd hh mm ss day_of_week
|
||||
my $sth = $dbcr->prepare("SELECT jitemid AS itemid, posterid, security, DATE_FORMAT(eventtime, \"$dateformat\") AS 'alldatepart', anum ".
|
||||
"FROM log2 " .
|
||||
"WHERE journalid=$u->{'userid'} AND year=$year AND month=$month AND day=$day $secwhere " .
|
||||
"ORDER BY eventtime, logtime LIMIT 200");
|
||||
$sth->execute;
|
||||
|
||||
my @items;
|
||||
push @items, $_ while $_ = $sth->fetchrow_hashref;
|
||||
#push @elapsed, (tv_interval ($t0));
|
||||
|
||||
LJ::fill_items_with_text_props(\@items, $u);
|
||||
|
||||
# load 'opt_ljcut_disable_lastn' prop for $remote.
|
||||
LJ::load_user_props($remote, "opt_ljcut_disable_lastn");
|
||||
|
||||
my (%apu, %apu_lite); # alt poster users; UserLite objects
|
||||
foreach (@items) {
|
||||
next unless $_->{'posterid'} != $u->{'userid'};
|
||||
$apu{$_->{'posterid'}} = undef;
|
||||
}
|
||||
if (%apu) {
|
||||
LJ::load_userids_multiple([map { $_, \$apu{$_} } keys %apu], [$u]);
|
||||
$apu_lite{$_} = UserLite($apu{$_}) foreach keys %apu;
|
||||
}
|
||||
|
||||
my $userlite_journal = UserLite($u);
|
||||
#push @elapsed, (tv_interval ($t0));
|
||||
|
||||
ENTRY:
|
||||
foreach my $item (@items)
|
||||
{
|
||||
my ($posterid, $itemid, $security, $alldatepart, $anum) =
|
||||
map { $item->{$_} } qw(posterid itemid security alldatepart anum);
|
||||
|
||||
my $props = $item->{'props'};
|
||||
|
||||
my $replycount = $props->{'replycount'};
|
||||
my $subject = $item->{'text'}->[0];
|
||||
my $text = $item->{'text'}->[1];
|
||||
if ($get->{'nohtml'}) {
|
||||
# quote all non-LJ tags
|
||||
$subject =~ s{<(?!/?lj)(.*?)>} {<$1>}gi;
|
||||
$text =~ s{<(?!/?lj)(.*?)>} {<$1>}gi;
|
||||
}
|
||||
|
||||
# don't show posts from suspended users
|
||||
next ENTRY if $apu{$posterid} && $apu{$posterid}->{'statusvis'} eq 'S' && ! $viewsome;
|
||||
|
||||
LJ::CleanHTML::clean_subject(\$subject) if $subject;
|
||||
|
||||
my $ditemid = $itemid*256 + $anum;
|
||||
|
||||
LJ::CleanHTML::clean_event(\$text, { 'preformatted' => $props->{'opt_preformatted'},
|
||||
'cuturl' => LJ::item_link($u, $itemid, $anum),
|
||||
'ljcut_disable' => $remote->{'opt_ljcut_disable_lastn'}, });
|
||||
LJ::expand_embedded($u, $ditemid, $remote, \$text);
|
||||
|
||||
my $nc = "";
|
||||
$nc .= "nc=$replycount" if $replycount; # && $remote && $remote->{'opt_nctalklinks'};
|
||||
|
||||
my $permalink = "$journalbase/$ditemid.html";
|
||||
my $readurl = $permalink;
|
||||
$readurl .= "?$nc" if $nc;
|
||||
my $posturl = $permalink . "?mode=reply";
|
||||
|
||||
my $comments = CommentInfo({
|
||||
'read_url' => $readurl,
|
||||
'post_url' => $posturl,
|
||||
'count' => $replycount,
|
||||
'maxcomments' => ($replycount >= LJ::get_cap($u, 'maxcomments')) ? 1 : 0,
|
||||
'enabled' => ($u->{'opt_showtalklinks'} eq "Y" && ! $props->{'opt_nocomments'}) ? 1 : 0,
|
||||
'screened' => ($props->{'hasscreened'} && $remote &&
|
||||
($remote->{'user'} eq $u->{'user'} || LJ::can_manage($remote, $u))) ? 1 : 0,
|
||||
});
|
||||
|
||||
my $userlite_poster = $userlite_journal;
|
||||
my $pu = $u;
|
||||
if ($u->{'userid'} != $posterid) {
|
||||
$userlite_poster = $apu_lite{$posterid} or die "No apu_lite for posterid=$posterid";
|
||||
$pu = $apu{$posterid};
|
||||
}
|
||||
my $userpic = Image_userpic($pu, 0, $props->{'picture_keyword'});
|
||||
|
||||
my $entry = Entry($u, {
|
||||
'subject' => $subject,
|
||||
'text' => $text,
|
||||
'dateparts' => $alldatepart,
|
||||
'security' => $security,
|
||||
'props' => $props,
|
||||
'itemid' => $ditemid,
|
||||
'journal' => $userlite_journal,
|
||||
'poster' => $userlite_poster,
|
||||
'comments' => $comments,
|
||||
'userpic' => $userpic,
|
||||
'permalink_url' => $permalink,
|
||||
'enable_tags_compatibility' => [$opts->{enable_tags_compatibility}, $opts->{ctx}],
|
||||
});
|
||||
|
||||
push @{$p->{'entries'}}, $entry;
|
||||
}
|
||||
#push @elapsed, (tv_interval ($t0));
|
||||
#print STDERR "@elapsed \n";
|
||||
|
||||
|
||||
if (@{$p->{'entries'}}) {
|
||||
$p->{'has_entries'} = 1;
|
||||
$p->{'entries'}->[0]->{'new_day'} = 1;
|
||||
$p->{'entries'}->[-1]->{'end_day'} = 1;
|
||||
}
|
||||
|
||||
# calculate previous day
|
||||
my $pdyear = $year;
|
||||
my $pdmonth = $month;
|
||||
my $pdday = $day-1;
|
||||
if ($pdday < 1)
|
||||
{
|
||||
if (--$pdmonth < 1)
|
||||
{
|
||||
$pdmonth = 12;
|
||||
$pdyear--;
|
||||
}
|
||||
$pdday = LJ::days_in_month($pdmonth, $pdyear);
|
||||
}
|
||||
|
||||
# calculate next day
|
||||
my $nxyear = $year;
|
||||
my $nxmonth = $month;
|
||||
my $nxday = $day+1;
|
||||
if ($nxday > LJ::days_in_month($nxmonth, $nxyear))
|
||||
{
|
||||
$nxday = 1;
|
||||
if (++$nxmonth > 12) { ++$nxyear; $nxmonth=1; }
|
||||
}
|
||||
|
||||
$p->{'prev_url'} = "$u->{'_journalbase'}/" . sprintf("%04d/%02d/%02d/", $pdyear, $pdmonth, $pdday);
|
||||
$p->{'prev_date'} = Date($pdyear, $pdmonth, $pdday);
|
||||
$p->{'next_url'} = "$u->{'_journalbase'}/" . sprintf("%04d/%02d/%02d/", $nxyear, $nxmonth, $nxday);
|
||||
$p->{'next_date'} = Date($nxyear, $nxmonth, $nxday);
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
1;
|
||||
432
local/cgi-bin/LJ/S2/EntryPage.pm
Executable file
432
local/cgi-bin/LJ/S2/EntryPage.pm
Executable file
@@ -0,0 +1,432 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
use strict;
|
||||
package LJ::S2;
|
||||
|
||||
sub EntryPage
|
||||
{
|
||||
my ($u, $remote, $opts) = @_;
|
||||
|
||||
my $get = $opts->{'getargs'};
|
||||
|
||||
my $p = Page($u, $opts);
|
||||
$p->{'_type'} = "EntryPage";
|
||||
$p->{'view'} = "entry";
|
||||
$p->{'comments'} = [];
|
||||
$p->{'comment_pages'} = undef;
|
||||
|
||||
# setup viewall options
|
||||
my ($viewall, $viewsome) = (0, 0);
|
||||
if ($get->{viewall} && LJ::check_priv($remote, 'canview')) {
|
||||
# we don't log here, as we don't know what entry we're viewing yet. the logging
|
||||
# is done when we call EntryPage_entry below.
|
||||
$viewall = LJ::check_priv($remote, 'canview', '*');
|
||||
$viewsome = $viewall || LJ::check_priv($remote, 'canview', 'suspended');
|
||||
}
|
||||
|
||||
my ($entry, $s2entry) = EntryPage_entry($u, $remote, $opts);
|
||||
return if $opts->{'suspendeduser'};
|
||||
return if $opts->{'handler_return'};
|
||||
|
||||
$p->{'multiform_on'} = $remote &&
|
||||
($remote->{'userid'} == $u->{'userid'} ||
|
||||
$remote->{'userid'} == $entry->{'posterid'} ||
|
||||
LJ::can_manage($remote, $u));
|
||||
|
||||
my $itemid = $entry->{'itemid'};
|
||||
my $ditemid = $entry->{'itemid'} * 256 + $entry->{'anum'};
|
||||
my $permalink = LJ::journal_base($u) . "/$ditemid.html";
|
||||
my $stylemine = $get->{'style'} eq "mine" ? "style=mine" : "";
|
||||
|
||||
if ($u->{'journaltype'} eq "R" && $u->{'renamedto'} ne "") {
|
||||
$opts->{'redir'} = LJ::journal_base($u->{'renamedto'}, $opts->{'vhost'}) .
|
||||
"/$ditemid.html" . $opts->{'pathextra'};
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($u->{'opt_blockrobots'}) {
|
||||
$p->{'head_content'} .= LJ::robot_meta_tags();
|
||||
}
|
||||
if ($LJ::UNICODE) {
|
||||
$p->{'head_content'} .= '<meta http-equiv="Content-Type" content="text/html; charset='.$opts->{'saycharset'}."\" />\n";
|
||||
}
|
||||
|
||||
$p->{'entry'} = $s2entry;
|
||||
|
||||
# add the comments
|
||||
my %userpic;
|
||||
my %user;
|
||||
my $copts = {
|
||||
'thread' => ($get->{'thread'} >> 8),
|
||||
'page' => $get->{'page'},
|
||||
'view' => $get->{'view'},
|
||||
'userpicref' => \%userpic,
|
||||
'userref' => \%user,
|
||||
# user object is cached from call just made in EntryPage_entry
|
||||
'up' => LJ::load_user($s2entry->{'poster'}->{'username'}),
|
||||
'viewall' => $viewall,
|
||||
|
||||
# Okuklivanie tredov - daem upravlenie pol'zovatelyu -
|
||||
'page_size' => $get->{'page_size'},
|
||||
'max_subjects' => $get->{'max_subjects'},
|
||||
'threading_point' => $get->{'threading_point'},
|
||||
'uncollapse' => $get->{'uncollapse'},
|
||||
};
|
||||
|
||||
my $userlite_journal = UserLite($u);
|
||||
|
||||
my @comments = LJ::Talk::load_comments($u, $remote, "L", $itemid, $copts);
|
||||
|
||||
my $pics = LJ::Talk::get_subjecticons()->{'pic'}; # hashref of imgname => { w, h, img }
|
||||
my $convert_comments = sub {
|
||||
my ($self, $destlist, $srclist, $depth) = @_;
|
||||
|
||||
foreach my $com (@$srclist) {
|
||||
my $dtalkid = $com->{'talkid'} * 256 + $entry->{'anum'};
|
||||
my $text = $com->{'body'};
|
||||
if ($get->{'nohtml'}) {
|
||||
# quote all non-LJ tags
|
||||
$text =~ s{<(?!/?lj)(.*?)>} {<$1>}gi;
|
||||
}
|
||||
LJ::CleanHTML::clean_comment(\$text, { 'preformatted' => $com->{'props'}->{'opt_preformatted'},
|
||||
'anon_comment' => !$com->{posterid}});
|
||||
|
||||
# local time in mysql format to gmtime
|
||||
my $datetime = DateTime_unix(LJ::mysqldate_to_time($com->{'datepost'}));
|
||||
if ($datetime == 0) {
|
||||
$datetime = "Invalid date";
|
||||
}
|
||||
|
||||
my $subject_icon = undef;
|
||||
if (my $si = $com->{'props'}->{'subjecticon'}) {
|
||||
my $pic = $pics->{$si};
|
||||
$subject_icon = Image("$LJ::IMGPREFIX/talk/$pic->{'img'}",
|
||||
$pic->{'w'}, $pic->{'h'}) if $pic;
|
||||
}
|
||||
|
||||
my $comment_userpic;
|
||||
if (my $pic = $userpic{$com->{'picid'}}) {
|
||||
$comment_userpic = Image("$LJ::USERPIC_ROOT/$com->{'picid'}/$pic->{'userid'}",
|
||||
$pic->{'width'}, $pic->{'height'});
|
||||
}
|
||||
|
||||
my $reply_url = LJ::Talk::talkargs($permalink, "replyto=$dtalkid", $stylemine);
|
||||
|
||||
my $par_url;
|
||||
if ($com->{'parenttalkid'}) {
|
||||
my $dparent = ($com->{'parenttalkid'} << 8) + $entry->{'anum'};
|
||||
$par_url = LJ::Talk::talkargs($permalink, "thread=$dparent", $stylemine) . "#t$dparent";
|
||||
}
|
||||
|
||||
my $poster;
|
||||
if ($com->{'posterid'}) {
|
||||
if ($user{$com->{'posterid'}}) {
|
||||
$poster = UserLite($user{$com->{'posterid'}});
|
||||
} else {
|
||||
$poster = {
|
||||
'_type' => 'UserLite',
|
||||
'username' => $com->{'userpost'},
|
||||
'name' => $com->{'userpost'}, # we don't have this, so fake it
|
||||
'journal_type' => 'P', # fake too, but only people can post, so correct
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
my $s2com = {
|
||||
'_type' => 'Comment',
|
||||
'journal' => $userlite_journal,
|
||||
'metadata' => {
|
||||
'picture_keyword' => $com->{'props'}->{'picture_keyword'},
|
||||
},
|
||||
'permalink_url' => "$permalink?thread=$dtalkid#t$dtalkid",
|
||||
'reply_url' => $reply_url,
|
||||
'poster' => $poster,
|
||||
'replies' => [],
|
||||
'subject' => LJ::ehtml($com->{'subject'}),
|
||||
'subject_icon' => $subject_icon,
|
||||
'talkid' => $dtalkid,
|
||||
'text' => $text,
|
||||
'userpic' => $comment_userpic,
|
||||
'time' => $datetime,
|
||||
'tags' => [],
|
||||
'full' => $com->{'_loaded'} ? 1 : 0,
|
||||
'depth' => $depth,
|
||||
'parent_url' => $par_url,
|
||||
'screened' => $com->{'state'} eq "S" ? 1 : 0,
|
||||
'frozen' => $com->{'state'} eq "F" ? 1 : 0,
|
||||
'link_keyseq' => [ 'delete_comment' ],
|
||||
'anchor' => "t$dtalkid",
|
||||
'dom_id' => "ljcmt$dtalkid",
|
||||
};
|
||||
|
||||
# don't show info from suspended users
|
||||
# FIXME: ideally the load_comments should only return these
|
||||
# items if there are children, otherwise they should be hidden entirely
|
||||
my $pu = $com->{'posterid'} ? $user{$com->{'posterid'}} : undef;
|
||||
if ($pu && $pu->{'statusvis'} eq "S" && !$viewsome) {
|
||||
$s2com->{'text'} = "";
|
||||
$s2com->{'subject'} = "";
|
||||
$s2com->{'full'} = 0;
|
||||
$s2com->{'subject_icon'} = undef;
|
||||
$s2com->{'userpic'} = undef;
|
||||
}
|
||||
|
||||
# Conditionally add more links to the keyseq
|
||||
my $link_keyseq = $s2com->{'link_keyseq'};
|
||||
push @$link_keyseq, $s2com->{'screened'} ? 'unscreen_comment' : 'screen_comment';
|
||||
push @$link_keyseq, $s2com->{'frozen'} ? 'unfreeze_thread' : 'freeze_thread';
|
||||
|
||||
if (@{$com->{'children'}}) {
|
||||
$s2com->{'thread_url'} = LJ::Talk::talkargs($permalink, "thread=$dtalkid", $stylemine) . "#t$dtalkid";
|
||||
}
|
||||
|
||||
# add the poster_ip metadata if remote user has
|
||||
# access to see it.
|
||||
$s2com->{'metadata'}->{'poster_ip'} = $com->{'props'}->{'poster_ip'} if
|
||||
($com->{'props'}->{'poster_ip'} && $remote &&
|
||||
($remote->{'userid'} == $entry->{'posterid'} ||
|
||||
LJ::can_manage($remote, $u) || $viewall));
|
||||
|
||||
push @$destlist, $s2com;
|
||||
|
||||
$self->($self, $s2com->{'replies'}, $com->{'children'}, $depth+1);
|
||||
}
|
||||
};
|
||||
$p->{'comments'} = [];
|
||||
$convert_comments->($convert_comments, $p->{'comments'}, \@comments, 1);
|
||||
|
||||
# prepare the javascript data structure to put in the top of the page
|
||||
# if the remote user is a manager of the comments
|
||||
my $do_commentmanage_js = $p->{'multiform_on'};
|
||||
if ($LJ::DISABLED{'commentmanage'}) {
|
||||
if (ref $LJ::DISABLED{'commentmanage'} eq "CODE") {
|
||||
$do_commentmanage_js = $LJ::DISABLED{'commentmanage'}->($remote);
|
||||
} else {
|
||||
$do_commentmanage_js = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($do_commentmanage_js) {
|
||||
my $js = "<script>\n// don't crawl this. read http://www.livejournal.com/developer/exporting.bml\n";
|
||||
$js .= "var LJ_cmtinfo = {\n";
|
||||
my $canAdmin = LJ::can_manage($remote, $u) ? 1 : 0;
|
||||
$js .= "\tjournal: '$u->{user}',\n";
|
||||
$js .= "\tcanAdmin: $canAdmin,\n";
|
||||
$js .= "\tremote: '$remote->{user}',\n" if $remote;
|
||||
my $recurse = sub {
|
||||
my ($self, $array) = @_;
|
||||
foreach my $i (@$array) {
|
||||
my $has_threads = scalar @{$i->{'replies'}};
|
||||
my $poster = $i->{'poster'} ? $i->{'poster'}{'username'} : "";
|
||||
my $child_ids = join(',', map { $_->{'talkid'} } @{$i->{'replies'}});
|
||||
$js .= "\t$i->{'talkid'}: { rc: [$child_ids], u: '$poster' },\n";
|
||||
$self->($self, $i->{'replies'}) if $has_threads;
|
||||
}
|
||||
};
|
||||
$recurse->($recurse, $p->{'comments'});
|
||||
chop $js; chop $js; # remove final ",\n". stupid javascript.
|
||||
$js .= "\n};\n" .
|
||||
"var LJVAR;\n".
|
||||
"if (!LJVAR) LJVAR = new Object();\n".
|
||||
"LJVAR.imgprefix = \"$LJ::IMGPREFIX\";\n".
|
||||
"</script>\n";
|
||||
$p->{'head_content'} .= $js;
|
||||
$p->{'head_content'} .= "<script src='$LJ::SITEROOT/js/commentmanage.js'></script>\n";
|
||||
|
||||
}
|
||||
|
||||
|
||||
$p->{'viewing_thread'} = $get->{'thread'} ? 1 : 0;
|
||||
|
||||
# default values if there were no comments, because
|
||||
# LJ::Talk::load_comments() doesn't provide them.
|
||||
if ($copts->{'out_error'} eq 'noposts') {
|
||||
$copts->{'out_pages'} = $copts->{'out_page'} = 1;
|
||||
$copts->{'out_items'} = 0;
|
||||
$copts->{'out_itemfirst'} = $copts->{'out_itemlast'} = undef;
|
||||
}
|
||||
|
||||
$p->{'comment_pages'} = ItemRange({
|
||||
'all_subitems_displayed' => ($copts->{'out_pages'} == 1),
|
||||
'current' => $copts->{'out_page'},
|
||||
'from_subitem' => $copts->{'out_itemfirst'},
|
||||
'num_subitems_displayed' => scalar @comments,
|
||||
'to_subitem' => $copts->{'out_itemlast'},
|
||||
'total' => $copts->{'out_pages'},
|
||||
'total_subitems' => $copts->{'out_items'},
|
||||
'_url_of' => sub { return "$permalink?page=" . int($_[0]) .
|
||||
($stylemine ? "&$stylemine" : ''); },
|
||||
});
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
sub EntryPage_fast_check
|
||||
{
|
||||
my ($u, $view, $remote, $opts) = @_;
|
||||
|
||||
return unless ($view eq "entry" || $view eq "reply");
|
||||
|
||||
my $get = $opts->{'getargs'};
|
||||
|
||||
my $r = $opts->{'r'};
|
||||
my $uri = $r->uri;
|
||||
|
||||
my ($ditemid, $itemid, $anum);
|
||||
unless ($uri =~ /(\d+)\.html/) {
|
||||
$opts->{'handler_return'} = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
$ditemid = $1;
|
||||
$anum = $ditemid % 256;
|
||||
$itemid = $ditemid >> 8;
|
||||
|
||||
my $entry = LJ::Talk::get_journal_item($u, $itemid, "props_only");
|
||||
unless ($entry && $entry->{'anum'} == $anum) {
|
||||
$opts->{'handler_return'} = 404;
|
||||
return;
|
||||
}
|
||||
my $props = $entry->{'props'};
|
||||
|
||||
# do they have the viewall priv?
|
||||
my $viewall = 0;
|
||||
my $viewsome = 0;
|
||||
if ($get->{'viewall'} && LJ::check_priv($remote, "canview")) {
|
||||
LJ::statushistory_add($u->{'userid'}, $remote->{'userid'},
|
||||
"viewall", "entry: $u->{'user'}, itemid: $itemid, statusvis: $u->{'statusvis'}");
|
||||
$viewall = LJ::check_priv($remote, 'canview', '*');
|
||||
$viewsome = $viewall || LJ::check_priv($remote, 'canview', 'suspended');
|
||||
}
|
||||
|
||||
# check using normal rules
|
||||
unless (LJ::can_view($remote, $entry) || $viewall) {
|
||||
$opts->{'handler_return'} = 403;
|
||||
return;
|
||||
}
|
||||
|
||||
my $pu = $u;
|
||||
if ($entry->{'posterid'} != $entry->{'ownerid'}) {
|
||||
$pu = LJ::load_userid($entry->{'posterid'});
|
||||
}
|
||||
if (($pu && $pu->{'statusvis'} eq 'S') && !$viewsome) {
|
||||
$opts->{'suspendeduser'} = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
# check If-Modified-Since
|
||||
my $lastmod = $props->{'commentalter'};
|
||||
my $revisiontime = $props->{' revtime'};
|
||||
$lastmod = $revisiontime if $revisiontime && $revisiontime > $lastmod;
|
||||
|
||||
my $ims = $r->header_in('If-Modified-Since');
|
||||
if ($ims) {
|
||||
my $theirtime = LJ::http_to_time($ims);
|
||||
if ($theirtime >= $lastmod && !$remote) {
|
||||
# only for anonymous: logged users will be checked by Etag for exact match
|
||||
# reply special: uniq challange string for regular users
|
||||
if ($view eq "entry" || ($view eq "reply" && $r->header_in('User-Agent') =~ /$LJ::ROBOTS_REGEXP/)) {
|
||||
|
||||
$opts->{'notmodified'} = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
$r->header_out("Last-Modified", LJ::time_to_http($lastmod));
|
||||
}
|
||||
|
||||
sub EntryPage_entry
|
||||
{
|
||||
my ($u, $remote, $opts) = @_;
|
||||
|
||||
### NB! EntryPage_fast_check was previously called, so all checks passed.
|
||||
|
||||
my $get = $opts->{'getargs'};
|
||||
|
||||
my $r = $opts->{'r'};
|
||||
my $uri = $r->uri;
|
||||
|
||||
my ($ditemid, $itemid, $anum);
|
||||
unless ($uri =~ /(\d+)\.html/) {
|
||||
$opts->{'handler_return'} = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
$ditemid = $1;
|
||||
$anum = $ditemid % 256;
|
||||
$itemid = $ditemid >> 8;
|
||||
|
||||
my $entry = LJ::Talk::get_journal_item($u, $itemid);
|
||||
unless ($entry && $entry->{'anum'} == $anum) {
|
||||
$opts->{'handler_return'} = 404;
|
||||
return;
|
||||
}
|
||||
### more checks skipped ###
|
||||
|
||||
my $props = $entry->{'props'};
|
||||
|
||||
my $userlite_journal = UserLite($u);
|
||||
my $userlite_poster = $userlite_journal;
|
||||
my $pu = $u;
|
||||
if ($entry->{'posterid'} != $entry->{'ownerid'}) {
|
||||
$pu = LJ::load_userid($entry->{'posterid'});
|
||||
$userlite_poster = UserLite($pu);
|
||||
}
|
||||
|
||||
my $replycount = $props->{'replycount'};
|
||||
my $nc = "";
|
||||
$nc .= "nc=$replycount" if $replycount; # && $remote && $remote->{'opt_nctalklinks'};
|
||||
|
||||
my $stylemine = $get->{'style'} eq "mine" ? "style=mine" : "";
|
||||
|
||||
my $userpic = Image_userpic($pu, 0, $props->{'picture_keyword'});
|
||||
|
||||
my $permalink = LJ::journal_base($u) . "/$ditemid.html";
|
||||
my $readurl = LJ::Talk::talkargs($permalink, $nc, $stylemine);
|
||||
my $posturl = LJ::Talk::talkargs($permalink, "mode=reply", $stylemine);
|
||||
|
||||
my $comments = CommentInfo({
|
||||
'read_url' => $readurl,
|
||||
'post_url' => $posturl,
|
||||
'count' => $replycount,
|
||||
'maxcomments' => ($replycount >= LJ::get_cap($u, 'maxcomments')) ? 1 : 0,
|
||||
'enabled' => ($u->{'opt_showtalklinks'} eq "Y" && !
|
||||
$props->{'opt_nocomments'}) ? 1 : 0,
|
||||
'screened' => ($props->{'hasscreened'} && $remote &&
|
||||
LJ::can_manage($remote, $u)) ? 1 : 0,
|
||||
});
|
||||
|
||||
# format it
|
||||
if ($opts->{'getargs'}->{'nohtml'}) {
|
||||
# quote all non-LJ tags
|
||||
$entry->{'subject'} =~ s{<(?!/?lj)(.*?)>} {<$1>}gi;
|
||||
$entry->{'event'} =~ s{<(?!/?lj)(.*?)>} {<$1>}gi;
|
||||
}
|
||||
my $raw_subj = $entry->{'subject'};
|
||||
LJ::CleanHTML::clean_subject(\$entry->{'subject'});
|
||||
LJ::CleanHTML::clean_event(\$entry->{'event'}, $props->{'opt_preformatted'});
|
||||
LJ::expand_embedded($u, $ditemid, $remote, \$entry->{'event'});
|
||||
|
||||
my $s2entry = Entry($u, {
|
||||
'_rawsubject' => $raw_subj,
|
||||
'subject' => $entry->{'subject'},
|
||||
'text' => $entry->{'event'},
|
||||
'dateparts' => $entry->{'alldatepart'},
|
||||
'security' => $entry->{'security'},
|
||||
'props' => $props,
|
||||
'itemid' => $ditemid,
|
||||
'comments' => $comments,
|
||||
'journal' => $userlite_journal,
|
||||
'poster' => $userlite_poster,
|
||||
'new_day' => 0,
|
||||
'end_day' => 0,
|
||||
'userpic' => $userpic,
|
||||
'permalink_url' => $permalink,
|
||||
'enable_tags_compatibility' => [$opts->{enable_tags_compatibility}, $opts->{ctx}],
|
||||
});
|
||||
|
||||
return ($entry, $s2entry);
|
||||
}
|
||||
|
||||
1;
|
||||
444
local/cgi-bin/LJ/S2/FriendsPage.pm
Executable file
444
local/cgi-bin/LJ/S2/FriendsPage.pm
Executable file
@@ -0,0 +1,444 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
use strict;
|
||||
package LJ::S2;
|
||||
|
||||
eval "use LJR::Distributed;";
|
||||
my $ljr = $@ ? 0 : 1;
|
||||
|
||||
if ($ljr) {
|
||||
use LJR::Distributed;
|
||||
}
|
||||
|
||||
sub FriendsPage
|
||||
{
|
||||
my ($u, $remote, $opts) = @_;
|
||||
|
||||
my $p = Page($u, $opts);
|
||||
$p->{'_type'} = "FriendsPage";
|
||||
$p->{'view'} = "friends";
|
||||
$p->{'entries'} = [];
|
||||
$p->{'friends'} = {};
|
||||
$p->{'friends_title'} = LJ::ehtml($u->{'friendspagetitle'});
|
||||
$p->{'filter_active'} = 0;
|
||||
$p->{'filter_name'} = "";
|
||||
|
||||
my $sth;
|
||||
my $user = $u->{'user'};
|
||||
|
||||
# see how often the remote user can reload this page.
|
||||
# "friendsviewupdate" time determines what granularity time
|
||||
# increments by for checking for new updates
|
||||
my $nowtime = time();
|
||||
|
||||
# update delay specified by "friendsviewupdate"
|
||||
my $newinterval = LJ::get_cap_min($remote, "friendsviewupdate") || 1;
|
||||
|
||||
# when are we going to say page was last modified? back up to the
|
||||
# most recent time in the past where $time % $interval == 0
|
||||
my $lastmod = $nowtime;
|
||||
$lastmod -= $lastmod % $newinterval;
|
||||
|
||||
# see if they have a previously cached copy of this page they
|
||||
# might be able to still use.
|
||||
my $ims = $opts->{'r'}->header_in('If-Modified-Since');
|
||||
if ($ims) {
|
||||
my $theirtime = LJ::http_to_time($ims);
|
||||
|
||||
# send back a 304 Not Modified if they say they've reloaded this
|
||||
# document in the last $newinterval seconds:
|
||||
unless ($theirtime < $lastmod) {
|
||||
$opts->{'handler_return'} = 304;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
$opts->{'r'}->header_out('Last-Modified', LJ::time_to_http($lastmod));
|
||||
|
||||
my $get = $opts->{'getargs'};
|
||||
|
||||
my $ret;
|
||||
|
||||
if ($get->{'mode'} eq "live") {
|
||||
$ret .= "<html><head><title>${user}'s friends: live!</title></head>\n";
|
||||
$ret .= "<frameset rows=\"100%,0%\" border=0>\n";
|
||||
$ret .= " <frame name=livetop src=\"friends?mode=framed\">\n";
|
||||
$ret .= " <frame name=livebottom src=\"friends?mode=livecond&lastitemid=0\">\n";
|
||||
$ret .= "</frameset></html>\n";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($u->{'journaltype'} eq "R" && $u->{'renamedto'} ne "") {
|
||||
$opts->{'redir'} = LJ::journal_base($u->{'renamedto'}, $opts->{'vhost'}) . "/friends";
|
||||
return 1;
|
||||
}
|
||||
|
||||
LJ::load_user_props($remote, "opt_nctalklinks", "opt_stylemine", "opt_imagelinks", "opt_ljcut_disable_friends");
|
||||
|
||||
# load options for image links
|
||||
my ($maximgwidth, $maximgheight) = (undef, undef);
|
||||
($maximgwidth, $maximgheight) = ($1, $2)
|
||||
if ($remote && $remote->{'userid'} == $u->{'userid'} &&
|
||||
$remote->{'opt_imagelinks'} =~ m/^(\d+)\|(\d+)$/);
|
||||
|
||||
## never have spiders index friends pages (change too much, and some
|
||||
## people might not want to be indexed)
|
||||
$p->{'head_content'} .= LJ::robot_meta_tags();
|
||||
|
||||
my $itemshow = S2::get_property_value($opts->{'ctx'}, "page_friends_items")+0;
|
||||
if ($itemshow < 1) { $itemshow = 20; }
|
||||
elsif ($itemshow > 50) { $itemshow = 50; }
|
||||
|
||||
my $skip = $get->{'skip'}+0;
|
||||
my $maxskip = ($LJ::MAX_SCROLLBACK_FRIENDS || 1000) - $itemshow;
|
||||
if ($skip > $maxskip) { $skip = $maxskip; }
|
||||
if ($skip < 0) { $skip = 0; }
|
||||
my $itemload = $itemshow+$skip;
|
||||
|
||||
my $dayskip = $get->{'dayskip'}+0;
|
||||
|
||||
my $filter;
|
||||
my $group;
|
||||
my $common_filter = 1;
|
||||
|
||||
if (defined $get->{'filter'} && $remote && $remote->{'user'} eq $user) {
|
||||
$filter = $get->{'filter'};
|
||||
$common_filter = 0;
|
||||
$p->{'filter_active'} = 1;
|
||||
$p->{'filter_name'} = "";
|
||||
} else {
|
||||
if ($opts->{'pathextra'}) {
|
||||
$group = $opts->{'pathextra'};
|
||||
$group =~ s!^/!!;
|
||||
$group =~ s!/$!!;
|
||||
if ($group) { $group = LJ::durl($group); $common_filter = 0; }
|
||||
}
|
||||
if ($group) {
|
||||
$p->{'filter_active'} = 1;
|
||||
$p->{'filter_name'} = LJ::ehtml($group);
|
||||
}
|
||||
my $grp = LJ::get_friend_group($u, { 'name' => $group || "Default View" });
|
||||
my $bit = $grp->{'groupnum'};
|
||||
my $public = $grp->{'is_public'};
|
||||
if ($bit && ($public || ($remote && $remote->{'user'} eq $user))) {
|
||||
$filter = (1 << $bit);
|
||||
} elsif ($group) {
|
||||
$opts->{'badfriendgroup'} = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($opts->{'view'} eq "friendsfriends") {
|
||||
$p->{'friends_mode'} = "friendsfriends";
|
||||
}
|
||||
|
||||
if ($get->{'mode'} eq "livecond")
|
||||
{
|
||||
## load the itemids
|
||||
my @items = LJ::get_friend_items({
|
||||
'u' => $u,
|
||||
'remote' => $remote,
|
||||
'itemshow' => 1,
|
||||
'skip' => 0,
|
||||
'filter' => $filter,
|
||||
'common_filter' => $common_filter,
|
||||
});
|
||||
my $first = @items ? $items[0]->{'itemid'} : 0;
|
||||
|
||||
$ret .= "time = " . scalar(time()) . "<br />";
|
||||
$opts->{'headers'}->{'Refresh'} = "30;URL=$LJ::SITEROOT/users/$user/friends?mode=livecond&lastitemid=$first";
|
||||
if ($get->{'lastitemid'} == $first) {
|
||||
$ret .= "nothing new!";
|
||||
} else {
|
||||
if ($get->{'lastitemid'}) {
|
||||
$ret .= "<b>New stuff!</b>\n";
|
||||
$ret .= "<script language=\"JavaScript\">\n";
|
||||
$ret .= "window.parent.livetop.location.reload(true);\n";
|
||||
$ret .= "</script>\n";
|
||||
$opts->{'trusted_html'} = 1;
|
||||
} else {
|
||||
$ret .= "Friends Live! started.";
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
## load the itemids
|
||||
my %friends;
|
||||
my %friends_row;
|
||||
my @items = LJ::get_friend_items({
|
||||
'u' => $u,
|
||||
'remote' => $remote,
|
||||
'itemshow' => $itemshow,
|
||||
'skip' => $skip,
|
||||
'dayskip' => $dayskip,
|
||||
'filter' => $filter,
|
||||
'common_filter' => $common_filter,
|
||||
'friends_u' => \%friends,
|
||||
'friends' => \%friends_row,
|
||||
'showtypes' => $get->{'show'},
|
||||
'friendsoffriends' => $opts->{'view'} eq "friendsfriends",
|
||||
'dateformat' => 'S2',
|
||||
});
|
||||
|
||||
while ($_ = each %friends) {
|
||||
# we expect fgcolor/bgcolor to be in here later
|
||||
$friends{$_}->{'fgcolor'} = $friends_row{$_}->{'fgcolor'} || '#ffffff';
|
||||
$friends{$_}->{'bgcolor'} = $friends_row{$_}->{'bgcolor'} || '#000000';
|
||||
}
|
||||
|
||||
return $p unless %friends;
|
||||
|
||||
my %posters;
|
||||
{
|
||||
my @posterids;
|
||||
foreach my $item (@items) {
|
||||
next if $friends{$item->{'posterid'}};
|
||||
push @posterids, $item->{'posterid'};
|
||||
}
|
||||
LJ::load_userids_multiple([ map { $_ => \$posters{$_} } @posterids ])
|
||||
if @posterids;
|
||||
}
|
||||
|
||||
my %objs_of_picid;
|
||||
my @userpic_load;
|
||||
|
||||
my %lite; # posterid -> s2_UserLite
|
||||
my $get_lite = sub {
|
||||
my $id = shift;
|
||||
return $lite{$id} if $lite{$id};
|
||||
return $lite{$id} = UserLite($posters{$id} || $friends{$id});
|
||||
};
|
||||
|
||||
my $eventnum = 0;
|
||||
my $hiddenentries = 0;
|
||||
ENTRY:
|
||||
foreach my $item (@items)
|
||||
{
|
||||
my ($friendid, $posterid, $itemid, $security, $alldatepart) =
|
||||
map { $item->{$_} } qw(ownerid posterid itemid security alldatepart);
|
||||
|
||||
my $fru = $friends{$friendid};
|
||||
my ($friend, $poster);
|
||||
$friend = $poster = $fru->{'user'};
|
||||
$p->{'friends'}->{$fru->{'user'}} ||= Friend($fru);
|
||||
|
||||
my $clusterid = $item->{'clusterid'}+0;
|
||||
|
||||
my $props = $item->{'props'};
|
||||
|
||||
my $replycount = $props->{'replycount'};
|
||||
my $subject = $item->{'text'}->[0];
|
||||
my $text = $item->{'text'}->[1];
|
||||
if ($get->{'nohtml'}) {
|
||||
# quote all non-LJ tags
|
||||
$subject =~ s{<(?!/?lj)(.*?)>} {<$1>}gi;
|
||||
$text =~ s{<(?!/?lj)(.*?)>} {<$1>}gi;
|
||||
}
|
||||
|
||||
LJ::CleanHTML::clean_subject(\$subject) if $subject;
|
||||
|
||||
my $ditemid = $itemid * 256 + $item->{'anum'};
|
||||
|
||||
my $stylemine = "";
|
||||
$stylemine .= "style=mine" if $remote && $remote->{'opt_stylemine'} &&
|
||||
$remote->{'userid'} != $friendid;
|
||||
|
||||
LJ::CleanHTML::clean_event(\$text, { 'preformatted' => $props->{'opt_preformatted'},
|
||||
'cuturl' => LJ::item_link($fru, $itemid, $item->{'anum'}, $stylemine),
|
||||
'maximgwidth' => $maximgwidth,
|
||||
'maximgheight' => $maximgheight,
|
||||
'ljcut_disable' => $remote->{'opt_ljcut_disable_friends'}, });
|
||||
LJ::expand_embedded($fru, $ditemid, $remote, \$text);
|
||||
|
||||
my $userlite_poster = $get_lite->($posterid);
|
||||
my $userlite_journal = $get_lite->($friendid);
|
||||
|
||||
# get the poster user
|
||||
my $po = $posters{$posterid} || $friends{$posterid};
|
||||
|
||||
# don't allow posts from suspended users
|
||||
if ($po->{'statusvis'} eq 'S') {
|
||||
$hiddenentries++; # Remember how many we've skipped for later
|
||||
next ENTRY;
|
||||
}
|
||||
|
||||
# do the picture
|
||||
my $picid = 0;
|
||||
my $picu = undef;
|
||||
if ($friendid != $posterid && S2::get_property_value($opts->{ctx}, 'use_shared_pic')) {
|
||||
# using the community, the user wants to see shared pictures
|
||||
$picu = $fru;
|
||||
|
||||
# use shared pic for community
|
||||
$picid = $fru->{defaultpicid};
|
||||
} else {
|
||||
# we're using the poster for this picture
|
||||
$picu = $po;
|
||||
|
||||
# check if they specified one
|
||||
$picid = LJ::get_picid_from_keyword($po, $props->{picture_keyword})
|
||||
if $props->{picture_keyword};
|
||||
|
||||
# fall back on the poster's default
|
||||
$picid ||= $po->{defaultpicid};
|
||||
}
|
||||
|
||||
my $nc = "";
|
||||
$nc .= "nc=$replycount" if $replycount; # && $remote && $remote->{'opt_nctalklinks'};
|
||||
|
||||
my $journalbase = LJ::journal_base($fru);
|
||||
my $permalink = "$journalbase/$ditemid.html";
|
||||
my $readurl = LJ::Talk::talkargs($permalink, $nc, $stylemine);
|
||||
my $posturl = LJ::Talk::talkargs($permalink, "mode=reply", $stylemine);
|
||||
my $synurl = "";
|
||||
|
||||
if ($ljr && $props->{'syn_link'}) {
|
||||
my $rs = LJR::Distributed::match_remote_server($props->{'syn_link'});
|
||||
if ($rs->{"servertype"} eq "lj") {
|
||||
$readurl = $props->{'syn_link'};
|
||||
$posturl = $props->{'syn_link'} . "?mode=reply";
|
||||
$replycount = 'Read';
|
||||
}
|
||||
else {
|
||||
$posturl = $props->{'syn_link'};
|
||||
$replycount = undef;
|
||||
}
|
||||
$synurl = $props->{'syn_link'};
|
||||
}
|
||||
|
||||
my $comments = CommentInfo({
|
||||
'read_url' => $readurl,
|
||||
'post_url' => $posturl,
|
||||
'syn_url' => $synurl,
|
||||
'count' => $replycount,
|
||||
'maxcomments' => ($replycount >= LJ::get_cap($u, 'maxcomments')) ? 1 : 0,
|
||||
'enabled' => ($fru->{'opt_showtalklinks'} eq "Y" &&
|
||||
! $props->{'opt_nocomments'} ||
|
||||
$props->{'syn_link'}
|
||||
) ? 1 : 0,
|
||||
'screened' => ($remote && LJ::can_manage($remote, $fru) && $props->{'hasscreened'}) ? 1 : 0,
|
||||
});
|
||||
|
||||
my $moodthemeid = $u->{'opt_forcemoodtheme'} eq 'Y' ?
|
||||
$u->{'moodthemeid'} : $fru->{'moodthemeid'};
|
||||
|
||||
my $entry = Entry($u, {
|
||||
'subject' => $subject,
|
||||
'text' => $text,
|
||||
'dateparts' => $alldatepart,
|
||||
'security' => $security,
|
||||
'props' => $props,
|
||||
'itemid' => $ditemid,
|
||||
'journal' => $userlite_journal,
|
||||
'poster' => $userlite_poster,
|
||||
'comments' => $comments,
|
||||
'new_day' => 0, # setup below
|
||||
'end_day' => 0, # setup below
|
||||
'userpic' => undef,
|
||||
'permalink_url' => $permalink,
|
||||
'base_url' => $journalbase,
|
||||
'moodthemeid' => $moodthemeid,
|
||||
'enable_tags_compatibility' => [$opts->{enable_tags_compatibility}, $opts->{ctx}],
|
||||
});
|
||||
$entry->{'_ymd'} = join('-', map { $entry->{'time'}->{$_} } qw(year month day));
|
||||
|
||||
if ($picid && $picu) {
|
||||
push @userpic_load, [ $picu, $picid ];
|
||||
push @{$objs_of_picid{$picid}}, \$entry->{'userpic'};
|
||||
}
|
||||
|
||||
push @{$p->{'entries'}}, $entry;
|
||||
$eventnum++;
|
||||
|
||||
} # end while
|
||||
|
||||
# set the new_day and end_day members.
|
||||
if ($eventnum) {
|
||||
for (my $i = 0; $i < $eventnum; $i++) {
|
||||
my $entry = $p->{'entries'}->[$i];
|
||||
$entry->{'new_day'} = 1;
|
||||
my $last = $i;
|
||||
for (my $j = $i+1; $j < $eventnum; $j++) {
|
||||
my $ej = $p->{'entries'}->[$j];
|
||||
if ($ej->{'_ymd'} eq $entry->{'_ymd'}) {
|
||||
$last = $j;
|
||||
}
|
||||
}
|
||||
$p->{'entries'}->[$last]->{'end_day'} = 1;
|
||||
$i = $last;
|
||||
}
|
||||
}
|
||||
|
||||
# load the pictures that were referenced, then retroactively populate
|
||||
# the userpic fields of the Entries above
|
||||
my %userpics;
|
||||
LJ::load_userpics(\%userpics, \@userpic_load);
|
||||
|
||||
foreach my $picid (keys %userpics) {
|
||||
my $up = Image("$LJ::USERPIC_ROOT/$picid/$userpics{$picid}->{'userid'}",
|
||||
$userpics{$picid}->{'width'},
|
||||
$userpics{$picid}->{'height'});
|
||||
foreach (@{$objs_of_picid{$picid}}) { $$_ = $up; }
|
||||
}
|
||||
|
||||
# make the skip links
|
||||
my $nav = {
|
||||
'_type' => 'RecentNav',
|
||||
'version' => 1,
|
||||
'skip' => $skip,
|
||||
'count' => $eventnum,
|
||||
};
|
||||
|
||||
my $base = "$u->{'_journalbase'}/$opts->{'view'}";
|
||||
if ($group) {
|
||||
$base .= "/" . LJ::eurl($group);
|
||||
}
|
||||
|
||||
# $linkfilter is distinct from $filter: if user has a default view,
|
||||
# $filter is now set according to it but we don't want it to show in the links.
|
||||
# $incfilter may be true even if $filter is 0: user may use filter=0 to turn
|
||||
# off the default group
|
||||
my $linkfilter = $get->{'filter'} + 0;
|
||||
my $incfilter = defined $get->{'filter'};
|
||||
|
||||
# if we've skipped down, then we can skip back up
|
||||
if ($skip) {
|
||||
my %linkvars;
|
||||
$linkvars{'filter'} = $linkfilter if $incfilter;
|
||||
$linkvars{'show'} = $get->{'show'} if $get->{'show'} =~ /^\w+$/;
|
||||
my $newskip = $skip - $itemshow;
|
||||
if ($newskip > 0) { $linkvars{'skip'} = $newskip; }
|
||||
else { $newskip = 0; }
|
||||
$linkvars{'dayskip'} = $dayskip if $dayskip;
|
||||
$nav->{'forward_url'} = LJ::make_link($base, \%linkvars);
|
||||
$nav->{'forward_skip'} = $newskip;
|
||||
$nav->{'forward_count'} = $itemshow;
|
||||
}
|
||||
|
||||
## unless we didn't even load as many as we were expecting on this
|
||||
## page, then there are more (unless there are exactly the number shown
|
||||
## on the page, but who cares about that)
|
||||
# Must remember to count $hiddenentries or we'll have no skiplinks when > 1
|
||||
unless (($eventnum + $hiddenentries) != $itemshow || $skip == $maxskip) {
|
||||
my %linkvars;
|
||||
$linkvars{'filter'} = $linkfilter if $incfilter;
|
||||
$linkvars{'show'} = $get->{'show'} if $get->{'show'} =~ /^\w+$/;
|
||||
my $newskip = $skip + $itemshow;
|
||||
$linkvars{'skip'} = $newskip;
|
||||
$linkvars{'dayskip'} = $dayskip if $dayskip;
|
||||
$nav->{'backward_url'} = LJ::make_link($base, \%linkvars);
|
||||
$nav->{'backward_skip'} = $newskip;
|
||||
$nav->{'backward_count'} = $itemshow;
|
||||
}
|
||||
|
||||
$p->{'nav'} = $nav;
|
||||
|
||||
if ($get->{'mode'} eq "framed") {
|
||||
$p->{'head_content'} .= "<base target='_top' />";
|
||||
}
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
1;
|
||||
224
local/cgi-bin/LJ/S2/MonthPage.pm
Executable file
224
local/cgi-bin/LJ/S2/MonthPage.pm
Executable file
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
use strict;
|
||||
package LJ::S2;
|
||||
|
||||
sub MonthPage
|
||||
{
|
||||
my ($u, $remote, $opts) = @_;
|
||||
|
||||
my $get = $opts->{'getargs'};
|
||||
|
||||
my $p = Page($u, $opts);
|
||||
$p->{'_type'} = "MonthPage";
|
||||
$p->{'view'} = "month";
|
||||
$p->{'days'} = [];
|
||||
|
||||
my $ctx = $opts->{'ctx'};
|
||||
|
||||
my $dbcr = LJ::get_cluster_reader($u);
|
||||
|
||||
my $user = $u->{'user'};
|
||||
my $journalbase = LJ::journal_base($user, $opts->{'vhost'});
|
||||
|
||||
if ($u->{'journaltype'} eq "R" && $u->{'renamedto'} ne "") {
|
||||
$opts->{'redir'} = LJ::journal_base($u->{'renamedto'}, $opts->{'vhost'}) .
|
||||
"/" . $opts->{'pathextra'};
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($u->{'opt_blockrobots'}) {
|
||||
$p->{'head_content'} .= LJ::robot_meta_tags();
|
||||
}
|
||||
|
||||
my ($year, $month);
|
||||
if ($opts->{'pathextra'} =~ m!^/(\d\d\d\d)/(\d\d)\b!) {
|
||||
($year, $month) = ($1, $2);
|
||||
}
|
||||
|
||||
$opts->{'errors'} = [];
|
||||
if ($month < 1 || $month > 12) { push @{$opts->{'errors'}}, "Invalid month: $month"; }
|
||||
if ($year < 1970 || $year > 2038) { push @{$opts->{'errors'}}, "Invalid year: $year"; }
|
||||
unless ($dbcr) { push @{$opts->{'errors'}}, "Database temporarily unavailable"; }
|
||||
return if @{$opts->{'errors'}};
|
||||
|
||||
$p->{'date'} = Date($year, $month, 0);
|
||||
|
||||
# load the log items
|
||||
my $dateformat = "%Y %m %d %H %i %s %w"; # yyyy mm dd hh mm ss day_of_week
|
||||
my $sth;
|
||||
|
||||
my $secwhere = "AND l.security='public'";
|
||||
my $viewall = 0;
|
||||
my $viewsome = 0;
|
||||
if ($remote) {
|
||||
|
||||
# do they have the viewall priv?
|
||||
if ($get->{'viewall'} && LJ::check_priv($remote, "canview")) {
|
||||
LJ::statushistory_add($u->{'userid'}, $remote->{'userid'},
|
||||
"viewall", "month: $user, statusvis: $u->{'statusvis'}");
|
||||
$viewall = LJ::check_priv($remote, 'canview', '*');
|
||||
$viewsome = $viewall || LJ::check_priv($remote, 'canview', 'suspended');
|
||||
}
|
||||
|
||||
if ($remote->{'userid'} == $u->{'userid'} || $viewall) {
|
||||
$secwhere = ""; # see everything
|
||||
} elsif ($remote->{'journaltype'} eq 'P' || $remote->{'journaltype'} eq 'I') {
|
||||
my $gmask = LJ::get_groupmask($u, $remote);
|
||||
$secwhere = "AND (l.security='public' OR (l.security='usemask' AND l.allowmask & $gmask))"
|
||||
if $gmask;
|
||||
}
|
||||
}
|
||||
|
||||
$sth = $dbcr->prepare("SELECT l.jitemid AS 'itemid', l.posterid, l.anum, l.day, ".
|
||||
" DATE_FORMAT(l.eventtime, '$dateformat') AS 'alldatepart', ".
|
||||
" l.replycount, l.security ".
|
||||
"FROM log2 l ".
|
||||
"WHERE l.journalid=? AND l.year=? AND l.month=? ".
|
||||
"$secwhere LIMIT 2000");
|
||||
$sth->execute($u->{'userid'}, $year, $month);
|
||||
|
||||
my @items;
|
||||
push @items, $_ while $_ = $sth->fetchrow_hashref;
|
||||
@items = sort { $a->{'alldatepart'} cmp $b->{'alldatepart'} } @items;
|
||||
|
||||
LJ::fill_items_with_text_props(\@items, $u, {'only_subject' => 1});
|
||||
|
||||
my (%pu, %pu_lite); # poster users; UserLite objects
|
||||
foreach (@items) {
|
||||
$pu{$_->{'posterid'}} = undef;
|
||||
}
|
||||
LJ::load_userids_multiple([map { $_, \$pu{$_} } keys %pu], [$u]);
|
||||
$pu_lite{$_} = UserLite($pu{$_}) foreach keys %pu;
|
||||
|
||||
my %day_entries; # <day> -> [ Entry+ ]
|
||||
|
||||
my $opt_text_subjects = S2::get_property_value($ctx, "page_month_textsubjects");
|
||||
my $userlite_journal = UserLite($u);
|
||||
|
||||
ENTRY:
|
||||
foreach my $item (@items)
|
||||
{
|
||||
my ($posterid, $itemid, $security, $alldatepart, $replycount, $anum) =
|
||||
map { $item->{$_} } qw(posterid itemid security alldatepart replycount anum);
|
||||
my $day = $item->{'day'};
|
||||
|
||||
# don't show posts from suspended users
|
||||
next unless $pu{$posterid};
|
||||
next ENTRY if $pu{$posterid}->{'statusvis'} eq 'S' && !$viewsome;
|
||||
|
||||
my $subject = $item->{'text'}->[0];
|
||||
my $props = $item->{'props'};
|
||||
|
||||
if ($opt_text_subjects) {
|
||||
LJ::CleanHTML::clean_subject_all(\$subject);
|
||||
} else {
|
||||
LJ::CleanHTML::clean_subject(\$subject);
|
||||
}
|
||||
|
||||
my $ditemid = $itemid*256 + $anum;
|
||||
my $nc = "";
|
||||
$nc .= "nc=$replycount" if $replycount; # && $remote && $remote->{'opt_nctalklinks'};
|
||||
my $permalink = "$journalbase/$ditemid.html";
|
||||
my $readurl = $permalink;
|
||||
$readurl .= "?$nc" if $nc;
|
||||
my $posturl = $permalink . "?mode=reply";
|
||||
|
||||
my $comments = CommentInfo({
|
||||
'read_url' => $readurl,
|
||||
'post_url' => $posturl,
|
||||
'count' => $replycount,
|
||||
'maxcomments' => ($replycount >= LJ::get_cap($u, 'maxcomments')) ? 1 : 0,
|
||||
'enabled' => ($u->{'opt_showtalklinks'} eq "Y" && ! $props->{'opt_nocomments'}) ? 1 : 0,
|
||||
'screened' => ($props->{'hasscreened'} && $remote &&
|
||||
($remote->{'user'} eq $u->{'user'} || LJ::can_manage($remote, $u))) ? 1 : 0,
|
||||
});
|
||||
|
||||
my $userlite_poster = $userlite_journal;
|
||||
my $userpic = $p->{'journal'}->{'default_pic'};
|
||||
if ($u->{'userid'} != $posterid) {
|
||||
$userlite_poster = $pu_lite{$posterid};
|
||||
$userpic = Image_userpic($pu{$posterid}, 0, $props->{'picture_keyword'});
|
||||
}
|
||||
|
||||
my $entry = Entry($u, {
|
||||
'subject' => $subject,
|
||||
'text' => "",
|
||||
'dateparts' => $alldatepart,
|
||||
'security' => $security,
|
||||
'props' => $props,
|
||||
'itemid' => $ditemid,
|
||||
'journal' => $userlite_journal,
|
||||
'poster' => $userlite_poster,
|
||||
'comments' => $comments,
|
||||
'userpic' => $userpic,
|
||||
'permalink_url' => $permalink,
|
||||
});
|
||||
|
||||
push @{$day_entries{$day}}, $entry;
|
||||
}
|
||||
|
||||
my $days_month = LJ::days_in_month($month, $year);
|
||||
for my $day (1..$days_month) {
|
||||
my $entries = $day_entries{$day} || [];
|
||||
my $month_day = {
|
||||
'_type' => 'MonthDay',
|
||||
'date' => Date($year, $month, $day),
|
||||
'day' => $day,
|
||||
'has_entries' => scalar @$entries > 0,
|
||||
'num_entries' => scalar @$entries,
|
||||
'url' => $journalbase . sprintf("/%04d/%02d/%02d/", $year, $month, $day),
|
||||
'entries' => $entries,
|
||||
};
|
||||
push @{$p->{'days'}}, $month_day;
|
||||
}
|
||||
|
||||
# populate redirector
|
||||
my $vhost = $opts->{'vhost'};
|
||||
$vhost =~ s/:.*//;
|
||||
$p->{'redir'} = {
|
||||
'_type' => "Redirector",
|
||||
'user' => $u->{'user'},
|
||||
'vhost' => $vhost,
|
||||
'type' => 'monthview',
|
||||
'url' => "$LJ::SITEROOT/go.bml",
|
||||
};
|
||||
|
||||
# figure out what months have been posted into
|
||||
my $nowval = $year*12 + $month;
|
||||
|
||||
$p->{'months'} = [];
|
||||
|
||||
my $days = LJ::get_daycounts($u, $remote) || [];
|
||||
my $lastmo;
|
||||
foreach my $day (@$days) {
|
||||
my ($oy, $om) = ($day->[0], $day->[1]);
|
||||
my $mo = "$oy-$om";
|
||||
next if $mo eq $lastmo;
|
||||
$lastmo = $mo;
|
||||
|
||||
my $date = Date($oy, $om, 0);
|
||||
my $url = $journalbase . sprintf("/%04d/%02d/", $oy, $om);
|
||||
push @{$p->{'months'}}, {
|
||||
'_type' => "MonthEntryInfo",
|
||||
'date' => $date,
|
||||
'url' => $url,
|
||||
'redir_key' => sprintf("%04d%02d", $oy, $om),
|
||||
};
|
||||
|
||||
my $val = $oy*12+$om;
|
||||
if ($val < $nowval) {
|
||||
$p->{'prev_url'} = $url;
|
||||
$p->{'prev_date'} = $date;
|
||||
}
|
||||
if ($val > $nowval && ! $p->{'next_date'}) {
|
||||
$p->{'next_url'} = $url;
|
||||
$p->{'next_date'} = $date;
|
||||
}
|
||||
}
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
1;
|
||||
216
local/cgi-bin/LJ/S2/RecentPage.pm
Executable file
216
local/cgi-bin/LJ/S2/RecentPage.pm
Executable file
@@ -0,0 +1,216 @@
|
||||
use strict;
|
||||
package LJ::S2;
|
||||
|
||||
sub RecentPage
|
||||
{
|
||||
my ($u, $remote, $opts) = @_;
|
||||
|
||||
my $p = Page($u, $opts);
|
||||
$p->{'_type'} = "RecentPage";
|
||||
$p->{'view'} = "recent";
|
||||
$p->{'entries'} = [];
|
||||
|
||||
my $user = $u->{'user'};
|
||||
my $journalbase = LJ::journal_base($user, $opts->{'vhost'});
|
||||
|
||||
if ($u->{'journaltype'} eq "R" && $u->{'renamedto'} ne "") {
|
||||
$opts->{'redir'} = LJ::journal_base($u->{'renamedto'}, $opts->{'vhost'});
|
||||
return;
|
||||
}
|
||||
|
||||
LJ::load_user_props($remote, "opt_nctalklinks", "opt_ljcut_disable_lastn");
|
||||
|
||||
my $get = $opts->{'getargs'};
|
||||
|
||||
if ($opts->{'pathextra'}) {
|
||||
$opts->{'badargs'} = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($u->{'opt_blockrobots'} || $get->{'skip'}) {
|
||||
$p->{'head_content'} .= LJ::robot_meta_tags();
|
||||
}
|
||||
|
||||
$p->{'head_content'} .= qq{<link rel="openid.server" href="$LJ::OPENID_SERVER" />\n}
|
||||
if LJ::OpenID::server_enabled();
|
||||
|
||||
my $itemshow = S2::get_property_value($opts->{'ctx'}, "page_recent_items")+0;
|
||||
if ($itemshow < 1) { $itemshow = 20; }
|
||||
elsif ($itemshow > 50) { $itemshow = 50; }
|
||||
|
||||
my $skip = $get->{'skip'}+0;
|
||||
my $maxskip = $LJ::MAX_HINTS_LASTN-$itemshow;
|
||||
if ($skip < 0) { $skip = 0; }
|
||||
if ($skip > $maxskip) { $skip = $maxskip; }
|
||||
|
||||
my $dayskip = $get->{'dayskip'}+0;
|
||||
|
||||
# do they want to view all entries, regardless of security?
|
||||
my $viewall = 0;
|
||||
my $viewsome = 0;
|
||||
if ($get->{'viewall'} && LJ::check_priv($remote, "canview")) {
|
||||
LJ::statushistory_add($u->{'userid'}, $remote->{'userid'},
|
||||
"viewall", "lastn: $user, statusvis: $u->{'statusvis'}");
|
||||
$viewall = LJ::check_priv($remote, 'canview', '*');
|
||||
$viewsome = $viewall || LJ::check_priv($remote, 'canview', 'suspended');
|
||||
}
|
||||
|
||||
## load the items
|
||||
my $err;
|
||||
my @items = LJ::get_recent_items({
|
||||
'u' => $u,
|
||||
'clustersource' => 'slave',
|
||||
'viewall' => $viewall,
|
||||
'remote' => $remote,
|
||||
'itemshow' => $itemshow,
|
||||
'skip' => $skip,
|
||||
'dayskip' => $dayskip,
|
||||
'tags' => $opts->{tags},
|
||||
'dateformat' => 'S2',
|
||||
'order' => ($u->{'journaltype'} eq "C" || $u->{'journaltype'} eq "Y") # community or syndicated
|
||||
? "logtime" : "",
|
||||
'err' => \$err,
|
||||
});
|
||||
|
||||
die $err if $err;
|
||||
|
||||
my $lastdate = "";
|
||||
my $itemnum = 0;
|
||||
my $lastentry = undef;
|
||||
|
||||
my (%apu, %apu_lite); # alt poster users; UserLite objects
|
||||
foreach (@items) {
|
||||
next unless $_->{'posterid'} != $u->{'userid'};
|
||||
$apu{$_->{'posterid'}} = undef;
|
||||
}
|
||||
if (%apu) {
|
||||
LJ::load_userids_multiple([map { $_, \$apu{$_} } keys %apu], [$u]);
|
||||
$apu_lite{$_} = UserLite($apu{$_}) foreach keys %apu;
|
||||
}
|
||||
|
||||
my $userlite_journal = UserLite($u);
|
||||
|
||||
ENTRY:
|
||||
foreach my $item (@items)
|
||||
{
|
||||
my ($posterid, $itemid, $security, $alldatepart) =
|
||||
map { $item->{$_} } qw(posterid itemid security alldatepart);
|
||||
|
||||
my $props = $item->{'props'};
|
||||
|
||||
my $replycount = $props->{'replycount'};
|
||||
my $subject = $item->{'text'}->[0];
|
||||
my $text = $item->{'text'}->[1];
|
||||
if ($get->{'nohtml'}) {
|
||||
# quote all non-LJ tags
|
||||
$subject =~ s{<(?!/?lj)(.*?)>} {<$1>}gi;
|
||||
$text =~ s{<(?!/?lj)(.*?)>} {<$1>}gi;
|
||||
}
|
||||
|
||||
# don't show posts from suspended users unless the user doing the viewing says to (and is allowed)
|
||||
next ENTRY if $apu{$posterid} && $apu{$posterid}->{'statusvis'} eq 'S' && !$viewsome;
|
||||
|
||||
my $date = substr($alldatepart, 0, 10);
|
||||
my $new_day = 0;
|
||||
if ($date ne $lastdate) {
|
||||
$new_day = 1;
|
||||
$lastdate = $date;
|
||||
$lastentry->{'end_day'} = 1 if $lastentry;
|
||||
}
|
||||
|
||||
$itemnum++;
|
||||
LJ::CleanHTML::clean_subject(\$subject) if $subject;
|
||||
|
||||
my $ditemid = $itemid * 256 + $item->{'anum'};
|
||||
LJ::CleanHTML::clean_event(\$text, { 'preformatted' => $props->{'opt_preformatted'},
|
||||
'cuturl' => LJ::item_link($u, $itemid, $item->{'anum'}),
|
||||
'ljcut_disable' => $remote->{"opt_ljcut_disable_lastn"}, });
|
||||
LJ::expand_embedded($u, $ditemid, $remote, \$text);
|
||||
|
||||
my $nc = "";
|
||||
$nc .= "nc=$replycount" if $replycount; # && $remote && $remote->{'opt_nctalklinks'};
|
||||
|
||||
my $permalink = "$journalbase/$ditemid.html";
|
||||
my $readurl = $permalink;
|
||||
$readurl .= "?$nc" if $nc;
|
||||
my $posturl = $permalink . "?mode=reply";
|
||||
|
||||
my $comments = CommentInfo({
|
||||
'read_url' => $readurl,
|
||||
'post_url' => $posturl,
|
||||
'count' => $replycount,
|
||||
'maxcomments' => ($replycount >= LJ::get_cap($u, 'maxcomments')) ? 1 : 0,
|
||||
'enabled' => ($u->{'opt_showtalklinks'} eq "Y" && ! $props->{'opt_nocomments'}) ? 1 : 0,
|
||||
'screened' => ($props->{'hasscreened'} && ($remote->{'user'} eq $u->{'user'}|| LJ::can_manage($remote, $u))) ? 1 : 0,
|
||||
});
|
||||
|
||||
my $userlite_poster = $userlite_journal;
|
||||
my $pu = $u;
|
||||
if ($u->{'userid'} != $posterid) {
|
||||
$userlite_poster = $apu_lite{$posterid} or die "No apu_lite for posterid=$posterid";
|
||||
$pu = $apu{$posterid};
|
||||
}
|
||||
my $userpic = Image_userpic($pu, 0, $props->{'picture_keyword'});
|
||||
|
||||
my $entry = $lastentry = Entry($u, {
|
||||
'subject' => $subject,
|
||||
'text' => $text,
|
||||
'dateparts' => $alldatepart,
|
||||
'security' => $security,
|
||||
'props' => $props,
|
||||
'itemid' => $ditemid,
|
||||
'journal' => $userlite_journal,
|
||||
'poster' => $userlite_poster,
|
||||
'comments' => $comments,
|
||||
'new_day' => $new_day,
|
||||
'end_day' => 0, # if true, set later
|
||||
'userpic' => $userpic,
|
||||
'permalink_url' => $permalink,
|
||||
'enable_tags_compatibility' => [$opts->{enable_tags_compatibility}, $opts->{ctx}],
|
||||
});
|
||||
|
||||
push @{$p->{'entries'}}, $entry;
|
||||
|
||||
} # end huge while loop
|
||||
|
||||
# mark last entry as closing.
|
||||
$p->{'entries'}->[-1]->{'end_day'} = 1 if $itemnum;
|
||||
|
||||
#### make the skip links
|
||||
my $nav = {
|
||||
'_type' => 'RecentNav',
|
||||
'version' => 1,
|
||||
'skip' => $skip,
|
||||
'count' => $itemnum,
|
||||
};
|
||||
|
||||
# if we've skipped down, then we can skip back up
|
||||
if ($skip) {
|
||||
my $newskip = $skip - $itemshow;
|
||||
$newskip = 0 if $newskip <= 0;
|
||||
$nav->{'forward_skip'} = $newskip;
|
||||
$nav->{'forward_url'} = LJ::make_link("$p->{base_url}/", { skip => ($newskip || ""), tag => (LJ::eurl($get->{tag}) || ""), dayskip => ($dayskip || "") });
|
||||
$nav->{'forward_count'} = $itemshow;
|
||||
}
|
||||
|
||||
# unless we didn't even load as many as we were expecting on this
|
||||
# page, then there are more (unless there are exactly the number shown
|
||||
# on the page, but who cares about that)
|
||||
unless ($itemnum != $itemshow) {
|
||||
$nav->{'backward_count'} = $itemshow;
|
||||
if ($skip == $maxskip) {
|
||||
my $date_slashes = $lastdate; # "yyyy mm dd";
|
||||
$date_slashes =~ s! !/!g;
|
||||
$nav->{'backward_url'} = "$p->{'base_url'}/day/$date_slashes";
|
||||
} else {
|
||||
my $newskip = $skip + $itemshow;
|
||||
$nav->{'backward_url'} = LJ::make_link("$p->{'base_url'}/", { skip => ($newskip || ""), tag => (LJ::eurl($get->{tag}) || ""), dayskip => ($dayskip || "") });
|
||||
$nav->{'backward_skip'} = $newskip;
|
||||
}
|
||||
}
|
||||
|
||||
$p->{'nav'} = $nav;
|
||||
return $p;
|
||||
}
|
||||
|
||||
1;
|
||||
139
local/cgi-bin/LJ/S2/ReplyPage.pm
Executable file
139
local/cgi-bin/LJ/S2/ReplyPage.pm
Executable file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
use strict;
|
||||
package LJ::S2;
|
||||
|
||||
sub ReplyPage
|
||||
{
|
||||
my ($u, $remote, $opts) = @_;
|
||||
|
||||
my $p = Page($u, $opts);
|
||||
$p->{'_type'} = "ReplyPage";
|
||||
$p->{'view'} = "reply";
|
||||
|
||||
my $get = $opts->{'getargs'};
|
||||
|
||||
my ($entry, $s2entry) = EntryPage_entry($u, $remote, $opts);
|
||||
return if $opts->{'suspendeduser'};
|
||||
return if $opts->{'handler_return'};
|
||||
my $ditemid = $entry->{'itemid'}*256 + $entry->{'anum'};
|
||||
$p->{'head_content'} .= $LJ::COMMON_CODE{'chalresp_js'};
|
||||
|
||||
if ($u->{'opt_blockrobots'}) {
|
||||
$p->{'head_content'} .= LJ::robot_meta_tags();
|
||||
}
|
||||
|
||||
$p->{'entry'} = $s2entry;
|
||||
|
||||
# setup the replying item
|
||||
my $replyto = $s2entry;
|
||||
my $parpost;
|
||||
if ($get->{'replyto'}) {
|
||||
my $re_talkid = int($get->{'replyto'} >> 8);
|
||||
my $re_anum = $get->{'replyto'} % 256;
|
||||
unless ($re_anum == $entry->{'anum'}) {
|
||||
$opts->{'handler_return'} = 404;
|
||||
return;
|
||||
}
|
||||
|
||||
my $sql = "SELECT jtalkid, posterid, state, datepost FROM talk2 ".
|
||||
"WHERE journalid=$u->{'userid'} AND jtalkid=$re_talkid ".
|
||||
"AND nodetype='L' AND nodeid=$entry->{'jitemid'}";
|
||||
foreach my $pass (1, 2) {
|
||||
my $db = $pass == 1 ? LJ::get_cluster_reader($u) : LJ::get_cluster_def_reader($u);
|
||||
$parpost = $db->selectrow_hashref($sql);
|
||||
last if $parpost;
|
||||
}
|
||||
unless ($parpost and $parpost->{'state'} ne 'D') {
|
||||
$opts->{'handler_return'} = 404;
|
||||
return;
|
||||
}
|
||||
if ($parpost->{'state'} eq 'S' && !LJ::Talk::can_unscreen($remote, $u, $s2entry->{'poster'}->{'username'}, undef)) {
|
||||
$opts->{'handler_return'} = 403;
|
||||
return;
|
||||
}
|
||||
if ($parpost->{'state'} eq 'F') {
|
||||
# frozen comment, no replies allowed
|
||||
|
||||
# FIXME: eventually have S2 ErrorPage to handle this and similar
|
||||
# For now, this hack will work; this error is pretty uncommon anyway.
|
||||
$opts->{status} = "403 Forbidden";
|
||||
return "<p>This thread has been frozen; no more replies are allowed.</p>";
|
||||
}
|
||||
|
||||
my $tt = LJ::get_talktext2($u, $re_talkid);
|
||||
$parpost->{'subject'} = $tt->{$re_talkid}->[0];
|
||||
$parpost->{'body'} = $tt->{$re_talkid}->[1];
|
||||
$parpost->{'props'} =
|
||||
LJ::load_talk_props2($u, [ $re_talkid ])->{$re_talkid} || {};
|
||||
|
||||
if($LJ::UNICODE && $parpost->{'props'}->{'unknown8bit'}) {
|
||||
LJ::item_toutf8($u, \$parpost->{'subject'}, \$parpost->{'body'}, {});
|
||||
}
|
||||
|
||||
LJ::CleanHTML::clean_comment(\$parpost->{'body'},
|
||||
{ 'preformatted' => $parpost->{'props'}->{'opt_preformatted'},
|
||||
'anon_comment' => !$parpost->{posterid} });
|
||||
|
||||
my $datetime = DateTime_unix(LJ::mysqldate_to_time($parpost->{'datepost'}));
|
||||
|
||||
my ($s2poster, $pu);
|
||||
my $comment_userpic;
|
||||
if ($parpost->{'posterid'}) {
|
||||
$pu = LJ::load_userid($parpost->{'posterid'});
|
||||
return $opts->{handler_return} = 403 if $pu->{statusvis} eq 'S'; # do not show comments by suspended users
|
||||
$s2poster = UserLite($pu);
|
||||
|
||||
# FIXME: this is a little heavy:
|
||||
$comment_userpic = Image_userpic($pu, 0, $parpost->{'props'}->{'picture_keyword'});
|
||||
}
|
||||
|
||||
my $dtalkid = $re_talkid * 256 + $entry->{'anum'};
|
||||
$replyto = {
|
||||
'_type' => 'EntryLite',
|
||||
'subject' => LJ::ehtml($parpost->{'subject'}),
|
||||
'text' => $parpost->{'body'},
|
||||
'userpic' => $comment_userpic,
|
||||
'poster' => $s2poster,
|
||||
'journal' => $s2entry->{'journal'},
|
||||
'metadata' => {},
|
||||
'permalink_url' => $u->{'_journalbase'} . "/$ditemid.html?view=$dtalkid#t$dtalkid",
|
||||
'depth' => 1,
|
||||
'time' => $datetime,
|
||||
};
|
||||
}
|
||||
|
||||
$p->{'replyto'} = $replyto;
|
||||
|
||||
$p->{'form'} = {
|
||||
'_type' => "ReplyForm",
|
||||
'_remote' => $remote,
|
||||
'_u' => $u,
|
||||
'_ditemid' => $ditemid,
|
||||
'_parpost' => $parpost,
|
||||
};
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
package S2::Builtin::LJ;
|
||||
|
||||
sub ReplyForm__print
|
||||
{
|
||||
my ($ctx, $form) = @_;
|
||||
my $remote = $form->{'_remote'};
|
||||
my $u = $form->{'_u'};
|
||||
my $parpost = $form->{'_parpost'};
|
||||
my $parent = $parpost ? $parpost->{'jtalkid'} : 0;
|
||||
|
||||
$S2::pout->(LJ::Talk::talkform({ 'remote' => $remote,
|
||||
'journalu' => $u,
|
||||
'parpost' => $parpost,
|
||||
'replyto' => $parent,
|
||||
'ditemid' => $form->{'_ditemid'},
|
||||
'form' => $form }));
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
181
local/cgi-bin/LJ/S2/YearPage.pm
Executable file
181
local/cgi-bin/LJ/S2/YearPage.pm
Executable file
@@ -0,0 +1,181 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
use strict;
|
||||
package LJ::S2;
|
||||
|
||||
sub YearPage
|
||||
{
|
||||
my ($u, $remote, $opts) = @_;
|
||||
|
||||
my $p = Page($u, $opts);
|
||||
$p->{'_type'} = "YearPage";
|
||||
$p->{'view'} = "archive";
|
||||
|
||||
my $user = $u->{'user'};
|
||||
|
||||
if ($u->{'journaltype'} eq "R" && $u->{'renamedto'} ne "") {
|
||||
$opts->{'redir'} = LJ::journal_base($u->{'renamedto'}, $opts->{'vhost'}) .
|
||||
"/calendar" . $opts->{'pathextra'};
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ($u->{'opt_blockrobots'}) {
|
||||
$p->{'head_content'} .= LJ::robot_meta_tags();
|
||||
}
|
||||
if ($LJ::UNICODE) {
|
||||
$p->{'head_content'} .= '<meta http-equiv="Content-Type" content="text/html; charset='.$opts->{'saycharset'}."\" />\n";
|
||||
}
|
||||
|
||||
my $get = $opts->{'getargs'};
|
||||
|
||||
my $count = LJ::S2::get_journal_day_counts($p);
|
||||
my @years = sort { $a <=> $b } keys %$count;
|
||||
my $maxyear = @years ? $years[-1] : undef;
|
||||
my $year = $get->{'year'}; # old form was /users/<user>/calendar?year=1999
|
||||
|
||||
# but the new form is purtier: */calendar/2001
|
||||
if (! $year && $opts->{'pathextra'} =~ m!^/(\d\d\d\d)/?\b!) {
|
||||
$year = $1;
|
||||
}
|
||||
|
||||
# else... default to the year they last posted.
|
||||
$year ||= $maxyear;
|
||||
|
||||
$p->{'year'} = $year;
|
||||
$p->{'years'} = [];
|
||||
foreach (@years) {
|
||||
push @{$p->{'years'}}, YearYear($_, "$p->{'base_url'}/$_/", $_ == $p->{'year'});
|
||||
}
|
||||
|
||||
$p->{'months'} = [];
|
||||
|
||||
for my $month (1..12) {
|
||||
push @{$p->{'months'}}, YearMonth($p, {
|
||||
'month' => $month,
|
||||
'year' => $year,
|
||||
});
|
||||
}
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
sub YearMonth {
|
||||
my ($p, $calmon) = @_;
|
||||
|
||||
my ($month, $year) = ($calmon->{'month'}, $calmon->{'year'});
|
||||
$calmon->{'_type'} = 'YearMonth';
|
||||
$calmon->{'weeks'} = [];
|
||||
$calmon->{'url'} = sprintf("$p->{'_u'}->{'_journalbase'}/$year/%02d/", $month);
|
||||
|
||||
my $count = LJ::S2::get_journal_day_counts($p);
|
||||
my $has_entries = $count->{$year} && $count->{$year}->{$month} ? 1 : 0;
|
||||
$calmon->{'has_entries'} = $has_entries;
|
||||
|
||||
my $start_monday = 0; # FIXME: check some property to see if weeks start on monday
|
||||
my $week = undef;
|
||||
|
||||
my $flush_week = sub {
|
||||
my $end_month = shift;
|
||||
return unless $week;
|
||||
push @{$calmon->{'weeks'}}, $week;
|
||||
if ($end_month) {
|
||||
$week->{'post_empty'} =
|
||||
7 - $week->{'pre_empty'} - @{$week->{'days'}};
|
||||
}
|
||||
$week = undef;
|
||||
};
|
||||
|
||||
my $push_day = sub {
|
||||
my $d = shift;
|
||||
unless ($week) {
|
||||
my $leading = $d->{'date'}->{'_dayofweek'}-1;
|
||||
if ($start_monday) {
|
||||
$leading = 6 if --$leading < 0;
|
||||
}
|
||||
$week = {
|
||||
'_type' => 'YearWeek',
|
||||
'days' => [],
|
||||
'pre_empty' => $leading,
|
||||
'post_empty' => 0,
|
||||
};
|
||||
}
|
||||
push @{$week->{'days'}}, $d;
|
||||
if ($week->{'pre_empty'} + @{$week->{'days'}} == 7) {
|
||||
$flush_week->();
|
||||
my $size = scalar @{$calmon->{'weeks'}};
|
||||
}
|
||||
};
|
||||
|
||||
my $day_of_week = LJ::day_of_week($year, $month, 1);
|
||||
|
||||
my $daysinmonth = LJ::days_in_month($month, $year);
|
||||
|
||||
for my $day (1..$daysinmonth) {
|
||||
# so we don't auto-vivify years/months
|
||||
my $daycount = $has_entries ? $count->{$year}->{$month}->{$day} : 0;
|
||||
my $d = YearDay($p->{'_u'}, $year, $month, $day,
|
||||
$daycount, $day_of_week+1);
|
||||
$push_day->($d);
|
||||
$day_of_week = ($day_of_week + 1) % 7;
|
||||
}
|
||||
$flush_week->(1); # end of month flag
|
||||
|
||||
my $nowval = $year * 12 + $month;
|
||||
|
||||
# determine the most recent month with posts that is older than
|
||||
# the current time $month/$year. gives calendars the ability to
|
||||
# provide smart next/previous links.
|
||||
my $maxbefore;
|
||||
while (my ($iy, $h) = each %$count) {
|
||||
next if $iy > $year;
|
||||
while (my $im = each %$h) {
|
||||
next if $im >= $month;
|
||||
my $val = $iy * 12 + $im;
|
||||
if ($val < $nowval && $val > $maxbefore) {
|
||||
$maxbefore = $val;
|
||||
$calmon->{'prev_url'} = $p->{'_u'}->{'_journalbase'} . sprintf("/%04d/%02d/", $iy, $im);
|
||||
$calmon->{'prev_date'} = Date($iy, $im, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# same, except inverse: next month after current time with posts
|
||||
my $minafter;
|
||||
while (my ($iy, $h) = each %$count) {
|
||||
next if $iy < $year;
|
||||
while (my $im = each %$h) {
|
||||
next if $im <= $month;
|
||||
my $val = $iy * 12 + $im;
|
||||
if ($val > $nowval && (!$minafter || $val < $minafter)) {
|
||||
$minafter = $val;
|
||||
$calmon->{'next_url'} = $p->{'_u'}->{'_journalbase'} . sprintf("/%04d/%02d/", $iy, $im);
|
||||
$calmon->{'next_date'} = Date($iy, $im, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $calmon;
|
||||
}
|
||||
|
||||
sub YearYear {
|
||||
my ($year, $url, $displayed) = @_;
|
||||
return { '_type' => "YearYear",
|
||||
'year' => $year, 'url' => $url, 'displayed' => $displayed };
|
||||
}
|
||||
|
||||
sub YearDay {
|
||||
my ($u, $year, $month, $day, $count, $dow) = @_;
|
||||
my $d = {
|
||||
'_type' => 'YearDay',
|
||||
'day' => $day,
|
||||
'date' => Date($year, $month, $day, $dow),
|
||||
'num_entries' => $count
|
||||
};
|
||||
if ($count) {
|
||||
$d->{'url'} = sprintf("$u->{'_journalbase'}/$year/%02d/%02d/",
|
||||
$month, $day);
|
||||
}
|
||||
return $d;
|
||||
}
|
||||
|
||||
1;
|
||||
Reference in New Issue
Block a user