view release on metacpan or search on metacpan
lib/App/JobLog/Command/add.pm view on Meta::CPAN
}
my $log = App::JobLog::Log->new;
my ($last) = $log->last_event;
my $is_ongoing = $last && $last->is_open;
$log->append_event(
$tags ? ( tags => $tags ) : (),
description => [ join ' ', @$args ],
time => now
);
if ( $is_ongoing && _different_day( $last->start, now ) ) {
say 'Event spans midnight. Perhaps you failed to close the last event.';
}
}
sub _different_day {
my ( $d1, $d2 ) = @_;
return !( $d1->year == $d2->year
&& $d1->month == $d2->month
&& $d1->day == $d2->day );
}
lib/App/JobLog/Command/configure.pm view on Meta::CPAN
WORKDAYS
);
use autouse 'App::JobLog::TimeGrammar' => qw(parse);
no if $] >= 5.018, warnings => "experimental::smartmatch";
sub execute {
my ( $self, $opt, $args ) = @_;
_list_params() if $opt->list;
if ( defined $opt->precision ) {
my $precision = precision( $opt->precision );
say "precision set to $precision";
}
if ( defined $opt->start_pay_period ) {
eval {
my ($s) = parse( $opt->start_pay_period );
my $d = start_pay_period($s);
say 'beginning of pay period set to ' . $d->strftime('%F');
};
$self->usage_error(
'could not understand date: ' . $opt->start_pay_period )
if $@;
}
if ( defined $opt->length_pay_period ) {
my $length_pp = pay_period_length( $opt->length_pay_period );
say "length of pay period in days set to $length_pp";
}
if ( defined $opt->day_length ) {
my $day_length = day_length( $opt->day_length );
say "length of work day set to $day_length";
}
if ( defined $opt->workdays ) {
my $days = uc $opt->workdays;
my %days = map { $_ => 1 } split //, $days;
my @days;
for ( split //, DAYS ) {
push @days, $_ if $days{$_};
}
$days = join '', @days;
$days = workdays($days);
say "workdays set to $days";
}
if ( defined $opt->sunday_begins_week ) {
my $bool;
for ( $opt->sunday_begins_week ) {
when (/true/i) { $bool = 1 }
when (/false/i) { $bool = 0 }
default { $bool = $opt->sunday_begins_week || 0 };
}
$bool = sunday_begins_week($bool);
say "Sunday begins week is now " . ( $bool ? 'true' : 'false' );
}
if ( defined $opt->merge ) {
my $m = lc $opt->merge;
$m =~ s/^\s++|\s++$//g;
$m =~ s/\s++/ /g;
my $value = merge($m);
say "merge level is now '$value'";
}
if ( defined $opt->editor ) {
my $value = editor( $opt->editor );
say "log editor is now $value";
}
if ( defined $opt->hidden_columns ) {
my @cols = map { my $v = $_; lc $v } @{ $opt->hidden_columns };
my %cols = map { $_ => 1 } @cols;
my $value = join ' ', sort keys %cols;
$value = hidden_columns($value);
say "hidden columns: $value";
}
if ( defined $opt->time_zone ) {
my $value = time_zone( $opt->time_zone );
say "time zone is now $value";
}
}
sub usage_desc { '%c ' . __PACKAGE__->name . ' %o' }
sub abstract { 'set or display various parameters' }
sub options {
return (
[
lib/App/JobLog/Command/done.pm view on Meta::CPAN
sub execute {
my ( $self, $opt, $args ) = @_;
$self->simple_command_check($args);
my $log = App::JobLog::Log->new;
my ($last) = $log->last_event;
if ( $last && $last->is_open ) {
$log->append_event( done => 1 );
}
else {
say 'No currently open event in log.';
}
}
sub usage_desc { '%c ' . __PACKAGE__->name }
sub abstract { 'mark current task as done' }
1;
__END__
lib/App/JobLog/Command/edit.pm view on Meta::CPAN
my $md5 = Digest::MD5->new;
my $md51 = $md5->addfile($fh)->hexdigest;
system "$editor $log";
$fh = FileHandle->new($log);
my $md52 = $md5->reset->addfile($fh)->hexdigest;
if ( $md51 ne $md52 ) {
$fh = FileHandle->new( "$log.bak", 'w' );
copy( $fn, $fh );
$fh->close;
say "saved backup log in $log.bak";
my $errors = App::JobLog::Log->new->validate;
_error_report($errors);
}
else {
unlink $fn;
}
}
else {
say 'nothing in log to edit';
}
}
else {
$self->usage_error('no editor specified') unless $opt->close;
}
}
sub usage_desc {
'%c ' . __PACKAGE__->name . ' [--validate] [-c <date and time>]';
}
lib/App/JobLog/Command/edit.pm view on Meta::CPAN
'add a "DONE" line to the log at the specified moment'
],
[ 'validate|v' => 'check log for errors, commenting out any found' ],
);
}
sub _error_report {
my $errors = shift;
if ($errors) {
say "errors found: $errors";
say 'Error messages have been inserted into the log. Please edit.';
}
else {
say 'log is valid';
}
}
sub validate {
my ( $self, $opt, $args ) = @_;
if ( $opt->close ) {
$self->usage_error('no time expression provided') unless @$args;
}
}
lib/App/JobLog/Command/last.pm view on Meta::CPAN
last if $test->($e);
}
if ($e) {
my $start = $e->start->strftime('%F at %H:%M:%S %p');
my $end = $e->is_open ? 'now' : $e->end->strftime('%F at %H:%M:%S %p');
$opt->{merge} = 'no_merge';
App::JobLog::Command::summary->execute( $opt, ["$start - $end"] );
}
else {
say $count ? 'no matching event' : 'empty log';
}
}
sub usage_desc { '%c ' . __PACKAGE__->name }
sub abstract { 'describe the last task recorded' }
sub options {
return (
[
lib/App/JobLog/Command/parse.pm view on Meta::CPAN
use App::JobLog -command;
use autouse 'App::JobLog::TimeGrammar' => qw(parse);
use Modern::Perl;
sub execute {
my ( $self, $opt, $args ) = @_;
my $expression = join ' ', @$args;
eval {
my ( $s, $e, $is_interval ) = parse $expression;
say <<END;
received: $expression
start time: $s
end time: $e
received interval: @{[$is_interval ? 'true' : 'false']}
END
};
$self->usage_error($@) if $@;
}
lib/App/JobLog/Command/tags.pm view on Meta::CPAN
$events = App::JobLog::Log->new->$method;
}
};
$self->usage_error($@) if $@;
my %tags;
for my $e (@$events) {
$tags{$_} = 1 for @{ $e->tags };
}
if (%tags) {
print "\n";
say $_ for sort keys %tags;
print "\n";
}
else {
say 'no tags in log';
}
}
sub usage_desc { '%c ' . __PACKAGE__->name . ' %o [date or date range]' }
sub abstract {
'list tags employed in log or some subrange thereof';
}
sub full_description {
lib/App/JobLog/Command/vacation.pm view on Meta::CPAN
$vacation->close;
}
sub _show {
my ($vacation) = @_;
my $lines = $vacation->show;
if (@$lines) {
print $_ for @$lines;
}
else {
say 'no vacation times recorded';
}
}
sub usage_desc { '%c ' . __PACKAGE__->name . ' %o [<description>]' }
sub abstract { 'list or define days off' }
sub options {
return (
[ 'list|l', 'show all vacation times recorded', ],
lib/App/JobLog/Command/when.pm view on Meta::CPAN
print <<END;
WARNING! The last event in the log has been open since before 12:00 am today!
END
}
}
my $remaining = 0;
$remaining += $_->time_remaining for @$days;
if ( $remaining == 0 ) {
say "\nyou are just now done";
}
else {
my $then = now->add( seconds => $remaining );
my $format;
if ( $then->year == now->year ) {
my $delta = abs $then->delta_days(now)->in_units('days');
if ( $delta > 7 ) {
$format = SAME_YEAR_FORMAT;
}
elsif ( $then->month == now->month && $then->day == now->day ) {
lib/App/JobLog/Command/when.pm view on Meta::CPAN
}
else {
$format = SAME_WEEK_FORMAT;
}
}
else {
$format = FULL_FORMAT;
}
if ( $then < now ) {
$then = ( $days->[-1]->last_event->end // now )->add( seconds => $remaining );
say "\nyou were finished at " . $then->strftime($format);
}
else {
say "\nyou will be finished at " . $then->strftime($format);
}
print "\n";
}
}
sub usage_desc { '%c ' . __PACKAGE__->name . ' %o <date or date range>' }
sub abstract {
'report when work is done for the day';
}
lib/App/JobLog/Log/Day.pm view on Meta::CPAN
push @lines, [ $s->time_fmt ] if $show_times;
push @lines, [ duration( $s->duration ) ] if $show_durations;
push @lines, wrap( $s->tag_string, $tag_width ) if $show_tags;
push @lines, $screen_width == -1
? [ $s->description ]
: wrap( $s->description, $description_width )
if $show_descriptions;
my $count = _pad_lines( \@lines );
for my $i ( 0 .. $count ) {
say sprintf $format, _gather( \@lines, $i );
}
}
print "\n"
if $show_times
|| $show_durations
|| $show_tags
|| $show_descriptions
|| $show_date;
}
lib/App/JobLog/Log/Format.pm view on Meta::CPAN
printf $format, 'UNTAGGED', duration( $times->{untagged} )
if $times->{untagged};
for my $key ( sort keys %{ $times->{tags} } ) {
my $d = $times->{tags}{$key};
printf $format, $key, duration($d);
}
}
}
}
else {
say 'No events in interval specified.';
}
}
# generate printf format for synopses
# returns format and wrap widths for tags and descriptions
sub _define_format {
my ( $synopses, $hash, $screen_width ) = @_;
#determine maximum width of each column
my $widths;
lib/App/JobLog/TimeGrammar.pm view on Meta::CPAN
use DateTime;
use App::JobLog::Time qw(tz);
use App::JobLog::TimeGrammar qw(parse);
# for demonstration purposes we modify "today"
$App::JobLog::Time::today =
DateTime->new( year => 2011, month => 2, day => 17, time_zone => tz );
for my $phrase ( 'Monday until the end of the week', 'Tuesday at 9:00 p.m.' ) {
my ( $start, $end, $endpoints ) = parse($phrase);
say $phrase;
say "$start - $end; both endpoints specified? "
. ( $endpoints ? 'yes' : 'no' );
}
produces
Monday until the end of the week
2011-02-14T00:00:00 - 2011-02-20T23:59:59; both endpoints specified? yes
Tuesday at 9:00 p.m.
2011-02-08T21:00:00 - 2011-02-15T23:59:59; both endpoints specified? no