App-TimeTracker
view release on metacpan or search on metacpan
lib/App/TimeTracker/Data/Task.pm view on Meta::CPAN
package App::TimeTracker::Data::Task;
# ABSTRACT: App::TimeTracker Task storage
our $VERSION = '3.010'; # VERSION
use 5.010;
use Moose;
use App::TimeTracker::Utils qw(now);
use namespace::autoclean;
use App::TimeTracker;
use DateTime::Format::ISO8601;
use DateTime::Format::Duration;
use User::pwent;
use MooseX::Storage;
with Storage(
format => [ JSONpm => { json_opts => { pretty => 1, canonical => 1 } } ],
io => "File",
);
MooseX::Storage::Engine->add_custom_type_handler(
'DateTime' => (
expand => sub { DateTime::Format::ISO8601->parse_datetime(shift) },
collapse => sub { (shift)->iso8601 } ) );
my $dtf_dur = DateTime::Format::Duration->new( pattern => '%H:%M:%S',
normalise => 1 );
my $dtf_sec = DateTime::Format::Duration->new( pattern => '%s' );
has 'start' => (
isa => 'DateTime',
is => 'ro',
required => 1,
default => sub { now() } );
has 'stop' => (
isa => 'DateTime',
is => 'rw',
trigger => \&_calc_duration,
);
has 'seconds' => (
isa => 'Maybe[Int]',
is => 'rw',
lazy_build => 1,
);
sub _build_seconds {
my $self = shift;
my $delta = now()->subtract_datetime( $self->start );
my $s = $dtf_sec->format_duration($delta);
return undef unless $s > 1;
return $s;
}
has 'duration' => (
isa => 'Str',
is => 'rw',
);
has 'status' => (
isa => 'Str',
is => 'rw',
);
sub _build_user {
return @{ getpw($<) }[0];
}
has 'user' => (
isa => 'Str',
is => 'ro',
required => 1,
lazy_build => 1,
);
has 'project' => (
isa => 'Str',
is => 'ro',
required => 1,
);
has 'description' => (
isa => 'Maybe[Str]',
is => 'ro',
required => 0,
);
has 'tags' => (
isa => 'ArrayRef',
is => 'ro',
default => sub { [] },
traits => ['Array'],
handles => { has_tags => 'count', },
);
sub _filepath {
my $self = shift;
my $start = $self->start;
my $name = $self->project;
$name =~ s/\W/_/g;
$name =~ s/_+/_/g;
$name =~ s/^_//;
$name =~ s/_$//;
( run in 0.785 second using v1.01-cache-2.11-cpan-39bf76dae61 )