App-JobLog
view release on metacpan or search on metacpan
lib/App/JobLog/Command/summary.pm view on Meta::CPAN
package App::JobLog::Command::summary;
$App::JobLog::Command::summary::VERSION = '1.042';
# ABSTRACT: show what you did during a particular period
use App::JobLog -command;
use Modern::Perl;
use Class::Autouse qw(
App::JobLog::Log
App::JobLog::Log::Day
);
use autouse 'App::JobLog::TimeGrammar' => qw(parse daytime);
use autouse 'Carp' => qw(carp);
use autouse 'Getopt::Long::Descriptive' => qw(prog_name);
use autouse 'App::JobLog::Config' => qw(
columns
is_hidden
merge
);
use autouse 'App::JobLog::Log::Format' => qw(
display
single_interval
summary
);
use autouse 'App::JobLog::Log::Synopsis' => qw(
MERGE_ALL
MERGE_ADJACENT
MERGE_ADJACENT_SAME_TAGS
MERGE_SAME_TAGS
MERGE_SAME_DAY
MERGE_SAME_DAY_SAME_TAGS
MERGE_NONE
);
use autouse 'App::JobLog::Time' => qw(today);
no if $] >= 5.018, warnings => "experimental::smartmatch";
sub execute {
my ( $self, $opt, $args ) = @_;
my $tags = $opt->{tag} || [];
my $excluded_tags = $opt->{exclude_tag} || [];
my $match = $opt->{match} || [];
my $no_match = $opt->{no_match} || [];
my $time_expr = join( ' ', @$args ) || $opt->{date};
my $time = $opt->{time};
$time_expr ||= $opt->{date};
# validate regexes, if any, while generating test
# NOTE: using $opt->{x} form rather than $opt->x to facilitate invoking summary
# from today command
my $test = _make_test( $tags, $excluded_tags, $match, $no_match, $time );
my $merge_level;
for ( $opt->{merge} || '' ) {
when ('no_merge') {
$merge_level = MERGE_NONE
}
when ('merge_all') {
$merge_level = MERGE_ALL
}
when ('merge_adjacent') {
$merge_level = MERGE_ADJACENT
}
when ('merge_adjacent_same_tags') {
$merge_level = MERGE_ADJACENT_SAME_TAGS
}
when ('merge_same_tags') {
$merge_level = MERGE_SAME_TAGS
}
when ('merge_same_day') {
$merge_level = MERGE_SAME_DAY
}
when ('merge_same_day_same_tags') {
$merge_level = MERGE_SAME_DAY_SAME_TAGS
}
default {
# some dark wizardry here
my $m = uc merge;
$m =~ s/ /_/g;
$m = \&{"MERGE_$m"};
$merge_level = &$m;
}
}
my $dateless = $merge_level == MERGE_ALL || $merge_level == MERGE_SAME_TAGS;
if (
$opt->{no_totals}
&& ( $dateless || $opt->{no_date} || is_hidden('date') )
&& ( !single_interval($merge_level)
|| $opt->{no_time}
|| is_hidden('time') )
&& ( $opt->{no_duration} || is_hidden('duration') )
&& ( $opt->{no_tags} || is_hidden('tags') )
&& ( $opt->{no_description} || is_hidden('description') )
)
{
$self->usage_error('you have chosen not to display anything');
}
# record hiding options in hash reference
my $hidden = {
vacation => $opt->{no_vacation} || $opt->{notes},
date => $dateless || $opt->{no_date} || is_hidden('date'),
time => $opt->{no_time} || is_hidden('time'),
duration => $opt->{notes} || $opt->{no_duration} || is_hidden('duration'),
tags => $opt->{no_tags} || is_hidden('tags'),
description => $opt->{no_description} || is_hidden('description'),
lib/App/JobLog/Command/summary.pm view on Meta::CPAN
'time|i=s',
'consider only those portions of events/notes that overlap the given time range'
],
[
"merge" => hidden => {
one_of => [
[
"merge-all|mall|ma" =>
"glom all events/notes into one synopsis"
],
[ "merge-adjacent|madj" => "merge contiguous events" ],
[
"merge-adjacent-same-tags|mast" =>
"merge contiguous, identically-tagged events/notes (default)"
],
[
"merge-same-tags|mst" =>
"merge all identically tagged events/notes"
],
[
"merge-same-day|msd" =>
"merge all events/notes in a given day"
],
[
"merge-same-day-same-tags|msdst" =>
"merge all events/notes in a given day"
],
[ "no-merge|nm" => "keep all events/notes separate" ],
]
}
],
[ 'no-vacation|V', 'do not display vacation hours' ],
[ 'no-date', 'do not display a date before each distinct day' ],
[
'no-time',
'do not display event or note start times and event end times'
],
[ 'no-duration', 'do not display event durations' ],
[ 'no-tags', 'do not display tags' ],
[ 'no-description', 'do not display event/note descriptions' ],
[
'no-totals',
'do not display the footer containing total hours worked, etc.'
],
[
'wrap' => 'hidden' => {
one_of => [
[
'columns|c=i',
'limit the width of the report to the specified number of columns; '
. ' by default the width of the terminal is automatically detected and, if that fails, a width of 76 is used'
],
[ 'no-wrap|W', 'do not wrap the text to fit columns' ],
]
}
],
[ 'hidden', 'display nothing', { hidden => 1 } ],
);
}
sub validate {
my ( $self, $opt, $args ) = @_;
$self->usage_error('no time expression provided')
unless @$args || $opt->date;
$self->usage_error('two time expression provided') if @$args && $opt->date;
$self->usage_error('columns must be positive')
if defined $opt->{columns} && $opt->columns < 1;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
App::JobLog::Command::summary - show what you did during a particular period
=head1 VERSION
version 1.042
=head1 SYNOPSIS
houghton@NorthernSpy:~$ job summary --help
job <command>
job summary [-cdiMmnTtVW] [long options...] [<date or date range>]
Use 'job help summary' to see full details.
-d STR --date STR provide the time expression as
an option instead of an argument
-n --notes show notes instead of events
-t STR... --tag STR... filter events/notes to include
only those with given tags;
multiple tags may be specified
-T STR... --exclude-tag STR... filter events/notes to exclude
those with given tags; multiple
tags may be specified
-m STR... --match STR... filter events/notes to include
only those one of whose
descriptions matches the given
regex; multiple regexes may be
specified
-M STR... --no-match STR... filter events/notes to include
only those one of whose
descriptions do not match the
given regex; multiple regexes
may be specified
-i STR --time STR consider only those portions of
events/notes that overlap the
given time range
--ma --mall --merge-all glom all events/notes into one
synopsis
--madj --merge-adjacent merge contiguous events
--mast --merge-adjacent-same-tags merge contiguous,
identically-tagged events/notes
( run in 0.991 second using v1.01-cache-2.11-cpan-39bf76dae61 )