182 lines
5.2 KiB
Perl
182 lines
5.2 KiB
Perl
|
#!/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;
|