From a470747864e9774c512e611ecc39e389c242af80 Mon Sep 17 00:00:00 2001 From: jluehrs2 Date: Thu, 8 May 2008 20:48:44 -0500 Subject: initial framework, the create command works --- lib/App/Hiveminder.pm | 6 ++ lib/App/Hiveminder/Base.pm | 13 +++ lib/App/Hiveminder/Command/create.pm | 31 +++++++ lib/App/Hiveminder/Utils.pm | 173 +++++++++++++++++++++++++++++++++++ 4 files changed, 223 insertions(+) create mode 100644 lib/App/Hiveminder.pm create mode 100644 lib/App/Hiveminder/Base.pm create mode 100644 lib/App/Hiveminder/Command/create.pm create mode 100644 lib/App/Hiveminder/Utils.pm (limited to 'lib') diff --git a/lib/App/Hiveminder.pm b/lib/App/Hiveminder.pm new file mode 100644 index 0000000..32f41d9 --- /dev/null +++ b/lib/App/Hiveminder.pm @@ -0,0 +1,6 @@ +#!/usr/bin/perl +package App::Hiveminder; +use Moose; +extends 'MooseX::App::Cmd'; + +1; diff --git a/lib/App/Hiveminder/Base.pm b/lib/App/Hiveminder/Base.pm new file mode 100644 index 0000000..7f40483 --- /dev/null +++ b/lib/App/Hiveminder/Base.pm @@ -0,0 +1,13 @@ +#!/usr/bin/perl +package App::Hiveminder::Base; +use Moose; +use Net::Hiveminder; +extends 'MooseX::App::Cmd::Command'; + +has hm => ( + isa => 'Net::Hiveminder', + is => 'ro', + default => sub { Net::Hiveminder->new(use_config => 1) }, +); + +1; diff --git a/lib/App/Hiveminder/Command/create.pm b/lib/App/Hiveminder/Command/create.pm new file mode 100644 index 0000000..ebdae82 --- /dev/null +++ b/lib/App/Hiveminder/Command/create.pm @@ -0,0 +1,31 @@ +#!/usr/bin/perl +package App::Hiveminder::Command::create; +use Moose; +use App::Hiveminder::Utils qw/get_text_from_editor_or_cmdline display_tasks + update_tasks/; +extends 'App::Hiveminder::Base'; + +sub run { + my ($self, $opt, $args) = @_; + print "Running create...\n"; + print "$_\n" for @$args; + $args = join " ", @$args; + + + my $text = get_text_from_editor_or_cmdline($args); + return '' if $text eq ''; + my @text = split "\n", $text; + + my $task = $self->hm->create_task(shift @text); + my $ret = display_tasks($self->hm, $task); + + if (@text > 0) { + $ret = display_tasks($self->hm, + @{ update_tasks($self->hm, [$self->hm->id2loc($task->{id})], + sub { (description => (join "\n", @text)) }) }); + } + + print $ret, "\n"; +} + +1; diff --git a/lib/App/Hiveminder/Utils.pm b/lib/App/Hiveminder/Utils.pm new file mode 100644 index 0000000..ab9cfd0 --- /dev/null +++ b/lib/App/Hiveminder/Utils.pm @@ -0,0 +1,173 @@ +#!/usr/bin/perl +package App::Hiveminder::Utils; +use strict; +use warnings; +use List::MoreUtils qw/any/; +use File::Temp qw/tempfile/; +use Fcntl qw/F_SETFD/; +require Exporter; +our @ISA = qw/Exporter/; +our @EXPORT_OK = qw/get_text_from_editor get_text_from_editor_or_cmdline in + parse_args update_tasks colorize display_tasks/; + +sub get_text_from_editor { # {{{ + my $editor = $ENV{EDITOR} || $ENV{VISUAL} || '/bin/nano'; + my ($fh, $fn) = tempfile; + my $device = '/dev/fd/' . fileno($fh); + + # use the filehandle if possible, fall back to the filename + if (-w $device && -l $device && readlink($device) eq $fn) { + fcntl($fh, F_SETFD, 0); + system($editor, $device); + } + else { + close $fh; + system($editor, $fn); + open $fh, '<', $fn or die "Couldn't reopen $fn"; + } + + local $/ = undef; + my $text = <$fh>; + unlink $fn; + + return $text; +} # }}} +sub get_text_from_editor_or_cmdline { # {{{ + return join ' ', @_ if @_ > 0; + return get_text_from_editor; +} # }}} +sub in { # {{{ + my $word = shift; + return any { $_ eq $word } @_; +} # }}} +sub parse_args { # {{{ + my $ret = {}; + + # XXX: handle 'will complete' and 'sort by *' + # XXX: support the new Net::Hiveminder capability of searching on multiple + # keys per value + # XXX: currently, searching by 'q' doesn't work, but this is a limitation + # of the current hiveminder REST interface i believe + my @filters = ('accepted', 'complete', 'completed', 'description', 'due', + 'group', 'owner', 'pending', 'priority', 'q', 'requestor', + 'starts', 'summary', 'tag', 'unaccepted', 'search', 'id'); + my @time_filters = ('completed', 'due', 'starts'); + my @num_filters = ('priority'); + my @arg_filters = ('completed', 'description', 'due', 'group', 'owner', + 'priority', 'q', 'requestor', 'starts', 'summary', + 'tag', 'id'); + + my %filter = ( + name => '', + is_neg => 0, + ); + for my $word (@_) { + if (!$filter{name}) { + if ($word eq 'not') { + $filter{is_neg} = 1; + next; + } + elsif ($word =~ m{^/}) { + $filter{name} = 'q'; + $word =~ s{^/(.*)}{$1}; + redo; + } + elsif (in($word, @filters)) { + $word = 'q' if $word eq 'search'; + $filter{name} = $word; + if (!in($filter{name}, @arg_filters)) { + if ($filter{is_neg}) { + $filter{name} .= '_not'; + } + $ret->{$filter{name}} = 1; + $filter{is_neg} = 0; + $filter{name} = ''; + } + next; + } + else { + $filter{name} = 'id'; + redo; + } + } + else { + if ((in($filter{name}, @time_filters) && + ($word eq 'after' || $word eq 'before')) || + (in($filter{name}, @num_filters) && + ($word eq 'above' || $word eq 'below')) || + $word eq 'not') { + $filter{name} .= "_$word"; + next; + } + + if (defined $ret->{$filter{name}}) { + push @{ $ret->{$filter{name}} }, $word; + } + else { + $ret->{$filter{name}} = [$word]; + } + $filter{name} = ''; + } + } + + return $ret; +} # }}} +sub update_tasks { # {{{ + my ($hm, $tasks, $updater) = @_; + my @tasks = (); + if (ref $tasks eq 'HASH') { + @tasks = $hm->get_tasks(%$tasks); + } + elsif (ref $tasks eq 'ARRAY') { + @tasks = @$tasks; + } + my $ret = []; + for my $task (@tasks) { + push @$ret, $hm->update_task($task, &$updater($task)); + } + return $ret; +} # }}} +sub colorize { # {{{ + my %priorities = ( + lowest => 34, + low => 36, + high => 33, + highest => 31, + ); + for my $line (@_) { + if ($line =~ /^\*/) { + $line = "\e[1;30;40m".$line."\e[0m"; + next; + } + my $task_color = "37"; + $task_color = "32" if + $line =~ s/ (\[(?:\"[^"]+\" ?)+\])/ \e[32m$1\e[0m/; + $task_color = "1;37" if + $line =~ s/ (\[by: [^\]]+\])/ \e[1;37m$1\e[0m/; + $task_color = "35" if + $line =~ s/ (\[due: [^\]]+\])/ \e[35m$1\e[0m/; + $task_color = "1;$priorities{$2}" if + $line =~ s/ (\[priority: (\w+)\])/" \e[1;$priorities{$2}m$1\e[0m"/e; + $task_color = "33" if + $line =~ s/ (\[starts: [^\]]+\])/ \e[33m$1\e[0m/; + $task_color = "1;30" if + $line =~ s/ (\[done\])/ \e[1;30m$1\e[0m/; + $line =~ s/^(#\w+)/\e[${task_color}m$1\e[0m/; + } + + return join "\n", @_; +} # }}} +sub display_tasks { # {{{ + my $hm = shift; + my @lines = $hm->display_tasks(@_); + my $text; + if (-t *STDOUT) { + $text = colorize @lines; + } + else { + $text = join "\n", @lines; + } + return $text; +} # }}} + +1; -- cgit v1.2.3-54-g00ecf