App-Easer

 view release on metacpan or  search on metacpan

eg/moodu2  view on Meta::CPAN

   }
   return 0
     if $self->edit_file($target) && length $self->get_title($target);
   $target->remove if -e $target;
   $self->fatal("bailing out creating new task");
} ## end sub add ($self)

sub cmd_cat ($self) {
   print {*STDOUT} $self->resolve->slurp_utf8;
   return 0;
}

sub cmd_done ($self) {
   $self->move_task;
}

sub cmd_edit ($self) {
   my $target   = $self->resolve;
   my $previous = $target->slurp_utf8;
   return 0
     if $self->edit_file($target) && length $self->get_title($target);
   $target->spew_utf8($previous);
   $self->fatal("bailing out editing task");
} ## end sub edit ($self)

sub cmd_list ($self) {
   my $config = $self->config_hash;

   my @active = qw< ongoing waiting >;
   my @candidates = (@active, 'done');
   my %included;

   # Add stuff
   if ($config->{all}) {
      @included{@candidates} = (1) x @candidates;
   }
   for my $option (@candidates) {
      $included{$option} = 1 if $config->{$option};
   }
   if ($config->{active} || !scalar keys %included) {
      @included{@active} = (1) x @active;
   }

   # Remove stuff
   delete @included{@active}
     if exists $config->{active} && !$config->{active};
   for my $option (@candidates) {
      delete $included{$option}
        if exists $config->{$option} && !$config->{$option};
   }

   my $basedir = $self->basedir;
   my (%cf, %pf);
   my $limit = $config->{n};
   for my $source (@candidates) {
      next unless $included{$source};
      for my $file ($self->list_category($source)) {
         my $title = $self->get_title($file);
         my $sid = $config->{id} ? '-' . $file->basename : ++$cf{$source};
         my $id = substr($source, 0, 1) . $sid;
         say "$id [$source] $title";
         last if $limit && ++$pf{$source} >= $limit;
      } ## end for my $file ($self->list_category...)
   } ## end for my $source (@candidates)

   return 0;
} ## end sub list ($self)

sub cmd_ongoing ($self) {
   $self->move_task;
}

sub cmd_remove ($self) {
   $self->resolve->remove;
   return 0;
}

sub cmd_show ($self) {
   my $contents = $self->resolve->slurp_utf8;
   $contents =~ s{\n\z}{}mxs;
   say "----\n$contents\n----";
   return 0;
} ## end sub show ($self)

sub cmd_waiting ($self) {
   $self->move_task;
}


########################################################################
# Support methods

sub add_file ($self, $hint, $contents) {
   my $attempts         = 0;
   my $file             = path($hint);
   my $allowed_attempts = $self->config('attempts');
   while ('necessary') {
      eval {
         my $fh =
           $file->filehandle({exclusive => 1}, '>', ':encoding(UTF-8)');
         print {$fh} $contents;
         close $fh;
      } && return $file;
      ++$attempts;
      last if $allowed_attempts && $attempts >= $allowed_attempts;
      $file = $hint->sibling($hint->basename . "-$attempts");
   } ## end while ('necessary')
   $self->fatal("cannot save file '$hint' or variants");
} ## end sub add_file

sub basedir ($self) {
   return path($self->config('basedir'));
}

sub edit_file ($self, $path) {
   my $editor = $self->config('editor');
   my $outcome = system {$editor} $editor, $path->stringify;
   return $outcome == 0;
}

sub fatal ($self, @message) {
   die join(' ', @message) . "\n";
}

sub get_title ($self, $path) {
   my ($title) = $path->lines({count => 1});
   ($title // '') =~ s{\A\s+|\s+\z}{}grmxs;
}

sub list_category ($self, $category) {
   my $dir = $self->basedir->child($category);
   return reverse sort { $a cmp $b } $dir->children;
}

sub move_task ($self) {
   my $category = (caller(1))[3] =~ s{\A cmd_}{}rmxs;
   my $child  = $self->resolve;
   my $parent = $child->parent;
   if ($parent->basename eq $category) {
      $self->notice("task is already $category");
      return 0;



( run in 1.316 second using v1.01-cache-2.11-cpan-364913b4093 )