mourningdove/cgi-bin/LJ/S2/DayPage.pm
2026-05-24 01:03:05 +00:00

189 lines
6.8 KiB
Perl

#!/usr/bin/perl
#
# This code was forked from the LiveJournal project owned and operated
# by Live Journal, Inc. The code has been modified and expanded by
# Dreamwidth Studios, LLC. These files were originally licensed under
# the terms of the license supplied by Live Journal, Inc, which can
# currently be found at:
#
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
#
# In accordance with the original license, this code and all its
# modifications are provided under the GNU General Public License.
# A copy of that license can be found in the LICENSE file included as
# part of this distribution.
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 = $u->journal_base( vhost => $opts->{'vhost'} );
if ( $u->should_block_robots ) {
$p->{'head_content'} .= LJ::robot_meta_tags();
}
# include JS for quick reply, icon browser, and ajax cut tag
my $handle_with_siteviews = $opts->{handle_with_siteviews_ref}
&& ${ $opts->{handle_with_siteviews_ref} };
LJ::Talk::init_s2journal_js(
iconbrowser => 1,
siteskin => $handle_with_siteviews,
lastn => 1
);
my $collapsed = BML::ml('widget.cuttag.collapsed');
my $expanded = BML::ml('widget.cuttag.expanded');
my $collapseAll = BML::ml('widget.cuttag.collapseAll');
my $expandAll = BML::ml('widget.cuttag.expandAll');
$p->{'head_content'} .= qq[
<script type='text/javascript'>
expanded = '$expanded';
collapsed = '$collapsed';
collapseAll = '$collapseAll';
expandAll = '$expandAll';
</script>
];
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 );
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?
( $viewall, $viewsome ) =
$remote->view_priv_check( $u, $get->{viewall}, 'day' );
if ( $viewall || $remote->equals($u) || $remote->can_manage($u) ) {
$secwhere = ""; # see everything
}
elsif ( $remote->is_individual ) {
my $gmask = $u->is_community ? $remote->member_of($u) : $u->trustmask($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, allowmask, "
. "DATE_FORMAT(eventtime, \"$dateformat\") AS 'alldatepart', anum, "
. "DATE_FORMAT(logtime, \"$dateformat\") AS 'system_alldatepart' "
. "FROM log2 "
. "WHERE journalid=$u->{'userid'} AND year=$year AND month=$month AND day=$day $secwhere "
. "ORDER BY eventtime, logtime LIMIT 2000" );
$sth->execute;
my @items;
push @items, $_ while $_ = $sth->fetchrow_hashref;
$opts->{cut_disable} = ( $remote && $remote->prop('opt_cut_disable_journal') );
ENTRY:
foreach my $item (@items) {
my ( $posterid, $itemid, $anum ) =
map { $item->{$_} } qw(posterid itemid anum);
my $ditemid = $itemid * 256 + $anum;
my $entry_obj = LJ::Entry->new( $u, ditemid => $ditemid );
# don't show posts from suspended users or suspended posts
next ENTRY if $entry_obj && $entry_obj->poster->is_suspended && !$viewsome;
next ENTRY if $entry_obj && $entry_obj->is_suspended_for($remote);
# create S2 Entry object
my $entry = Entry_from_entryobj( $u, $entry_obj, $opts );
# add S2 Entry object to page
push @{ $p->{entries} }, $entry;
LJ::Hooks::run_hook( 'notify_event_displayed', $entry_obj );
}
if ( @{ $p->{'entries'} } ) {
$p->{'has_entries'} = 1;
$p->{'entries'}->[0]->{'new_day'} = 1;
$p->{'entries'}->[-1]->{'end_day'} = 1;
}
# find near days
my ( $prev, $next );
my $here = sprintf( "%04d%02d%02d", $year, $month, $day ); # we are here now
foreach ( @{ $u->get_daycounts($remote) } ) {
$_ = sprintf( "%04d%02d%02d", (@$_)[ 0 .. 2 ] ); # map each date as YYYYMMDD number
if ( $_ < $here && ( !$prev || $_ > $prev ) )
{ # remember in $prev less then $here last date
$prev = $_;
}
elsif ( $_ > $here && ( !$next || $_ < $next ) )
{ # remember in $next greater then $here first date
$next = $_;
}
}
# create Date objects for ($prev, $next) pair
my ( $pdate, $ndate ) =
map { defined $_ && /^(\d\d\d\d)(\d\d)(\d\d)\b/ ? Date( $1, $2, $3 ) : Null('Date') }
( $prev, $next );
# insert slashes into $prev and $next
map { defined $_ && s!^(\d\d\d\d)(\d\d)(\d\d)\b!$1/$2/$3! } ( $prev, $next );
$p->{'prev_url'} = defined $prev ? ("$u->{'_journalbase'}/$prev") : '';
$p->{'prev_date'} = $pdate;
$p->{'next_url'} = defined $next ? ("$u->{'_journalbase'}/$next") : '';
$p->{'next_date'} = $ndate;
$p->{head_content} .= qq{<link rel="prev" href="$p->{prev_url}" />\n} if $p->{prev_url};
$p->{head_content} .= qq{<link rel="next" href="$p->{next_url}" />\n} if $p->{next_url};
return $p;
}
1;