App-tt

 view release on metacpan or  search on metacpan

script/tt  view on Meta::CPAN

        $self->{config}{lc($1)} = $2;
      }
    }

    $self->{defaults} ||= {
      editor          => $ENV{EDITOR}             || 'nano',
      export_columns  => $ENV{TT_COLUMNS}         || 'date,project,hours,rounded,tags,description',
      hours_per_month => $ENV{TT_HOURS_PER_MONTH} || 0,
      min_time        => $ENV{TT_MIN_TIME}        || 300,
      round_up_at     => $ENV{TT_ROUND_UP_AT}     || 30,
    };
  }

  return $self->{config}{$key} // $self->{defaults}{$key} // die "Missing option '$key'.\n";
}

sub _edit_with_editor {
  my ($self, $trc_file) = @_;
  my $prev  = $trc_file ? 0                          : 1;
  my $event = $prev     ? $self->_get_previous_event : $self->_load($trc_file);

  $trc_file = $event->{path} //= 'Not found';
  die "Could not find file to edit. ($event->{path})\n" unless $event->{start};

  my $fh = File::Temp->new;
  printf $fh "# %s\n", $event->{path};
  for my $k (qw(project tags description start stop user)) {
    $event->{$k} = join ', ', @{$event->{$k} || []} if $k eq 'tags';
    $event->{$k} = $event->{$k}->datetime if $k eq 'start' or $k eq 'stop' and $event->{$k};
    printf $fh "%-12s %s\n", "$k:", $event->{$k} // '';
  }

  close $fh;
  $self->_print("Edit $event->{path}");
  system $self->config('editor') => "$fh";

  for (split /\n/, App::tt::file->new("$fh")->slurp) {
    my ($k, $v) = /^(\w+)\s*:\s*(.+)/ or next;
    $v           = [grep {length} split /[\s,]+/, $v] if $k eq 'tags';
    $v           = $self->_time(str => $v)                         if $k eq 'start';
    $v           = $self->_time(str => $v, ref => $event->{start}) if $k eq 'stop';
    $event->{$k} = $v;
  }

  return $! unless $self->_save($event);
  $self->home->child('previous')->spurt($event->{path}) if $prev;
  unlink $trc_file or die "rm $trc_file: $!" unless $trc_file eq $event->{path};
  return 0;
}

sub _fill_event {
  my ($self, $event) = @_;

  my $project = $self->project;
  $project ||= App::tt::file->new->basename if -d '.git';
  $project ||= $self->config('project');

  $event->{__CLASS__}   ||= 'App::TimeTracker::Data::Task';
  $event->{project}     ||= $project;
  $event->{seconds}     ||= 0;
  $event->{user}        ||= scalar(getpwuid $<);
  $event->{tags}        ||= [$self->_tags];
  $event->{description} ||= $self->description // '';

  return $event;
}

sub _print {
  my ($self, $data, @args) = @_;

  if (ref $data eq 'ARRAY') {
    my $th     = $data->[0][-1] eq '{X}' ? 1    : 0;
    my @margin = $PTY                    ? ('') : ();
    my ($width, @lines, @spec);

    for my $row (@$data) {
      push @lines, $row and next unless ref $row eq 'ARRAY';
      my $w = 0;
      for my $col (0 .. $#$row) {
        ($row->[$col] //= '') =~ y/\r\n//d;
        my $len = length $row->[$col];
        $spec[$col] = $len if $len >= ($spec[$col] // 0);
        $w += $spec[$col] + 2;
      }
      $width = $w if $w >= ($width // 0);
    }

    $width -= 2;
    my @fm = (map({"\%-${_}s"} @spec[0 .. $#spec - 1]), '%s');
    $data = join '', map {
      ref $_
        ? sprintf join('  ', @margin, @fm[0 .. $#$_]) . "\n", @$_
        : '  ' . ($_ x $width) . "\n";
    } @$data;
  }

  my $fh = $self->{stdout} ||= \*STDOUT;
  if ($data =~ s/^(\d*)(>|!)\s//) {
    $fh   = $self->{stderr} ||= \*STDERR if $1 eq '2' || $2 eq '!';
    $data = "\n$data\n";
    $data =~ s!\n!\n  !g if $PTY;
  }

  return print {$fh} "$data\n" if @_ == 2;
  return printf {$fh} "$data\n", @args;
}

sub _fill_log_days {
  my ($self, $last, $now) = @_;
  my $interval = int(($now - $last)->days);

  map {
    my $t = $last + $_ * 86400;
    +{seconds => 0, start => $t, tags => [$t->day]}
  } 1 .. $interval;
}

sub _get_previous_event {
  my $self = shift;

  # $ROOT/previous contains path to last .trc file



( run in 1.460 second using v1.01-cache-2.11-cpan-39bf76dae61 )