reading_sched.cgi


#!/usr/bin/perl
#
# generate page-goal html (calendar format)
#

use local::lib;

use strict;
use warnings;
use CGI;
use CGI::Carp 'fatalsToBrowser';
use Date::Manip;
use English qw( -no_match_vars );
use HTML::Template;
use Const::Fast;
use version; our $VERSION = qv('v2017.10.11');

const my $EMPTY         => q{};
const my $DAYS_PER_WEEK => 7;

my $q             = CGI->new;
my $template_file = '/home/pas/public_html/misc/templates/cal_bookmark.tmpl';
my $template      = HTML::Template->new(
    filename  => $template_file,
    associate => $q,
    utf8      => 1,
);

#
# get CGI params ....
#
my $title = $q->param('title');
( $title ne $EMPTY ) || die "Must enter title\n";

my $startdate_str = $q->param('startdate');
my $startdate     = Date::Manip::Date->new();
$startdate->config( 'setdate', 'now,UTC' );
$startdate->parse_date($startdate_str) && die "Can't parse startdate\n";

my $startpage = $q->param('startpage');
( $startpage =~ /^[-+]?[0123456789]+$/ )
    || die "Sorry, can't parse startpage\n";

my $page0 = $startpage - 1;    # "pages already read"

my $enddate_str = $q->param('enddate');
my $enddate     = Date::Manip::Date->new();
$enddate->config( 'setdate', 'now,UTC' );
my $err = $enddate->parse_date($enddate_str);

if ( !$enddate ) {             # try a delta
    my $delta = Date::Manip::Delta->new();
    $delta->parse($enddate_str)
        || die "Can't parse enddate as date or delta\n";
    my $today = Date::Manip::Date->new();
    $today->parse_date('today');
    $enddate = $today->calc($delta);
}

( $startdate->cmp($enddate) < 0 )
    || die "Sorry, end date must be after start date\n";

my $endpage = $q->param('endpage');
( $endpage =~ /^[-+]?[0123456789]+$/ ) || die "Sorry, can't parse endpage\n";

my $npages = $endpage - $page0;

( $npages > 0 ) || die "Sorry, end must come after start\n";

#
# the number of days between start and end date (inclusive) is...
#
my $delta = $startdate->calc($enddate);
my $ndays = 1 + $delta->printf('%dys');

#
# one-day increment and decrement
#
my $plus_one_day = Date::Manip::Delta->new();
$plus_one_day->parse('+1 day');
my $minus_one_day = Date::Manip::Delta->new();
$minus_one_day->parse('-1 day');

#
# start calendar on Sunday...
#
my $dt    = $startdate;
my $dayno = 1;
while ( $dt->printf('%A') ne 'Sunday' ) {
    $dt = $dt->calc($minus_one_day);
    $dayno--;
}

#
# loop over as many weeks as needed...
#
my @wl = ();
while ( $dt->cmp($enddate) <= 0 ) {
    my @dl = ();
    #
    # loop over days of week...
    #
    for ( 1 .. $DAYS_PER_WEEK ) {
        my $pg
            = ( $dayno >= 1 && $dayno <= $ndays )
            ? sprintf( '%.0f', $page0 + $dayno / $ndays * $npages )
            : $EMPTY;

        ( my $ddd = $dt->printf('%f/%e') ) =~ s/\s//g;
        push @dl, { 'date' => $ddd, 'goal' => $pg, };
        $dt = $dt->calc($plus_one_day);
        $dayno++;
    }
    push @wl, { 'days' => \@dl };
}

$template->param( 'weeks' => \@wl );
$template->param( 'title' => $title );

print "Content-Type: text/html\n\n";
print $template->output;