summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorjluehrs2 <jluehrs2@uiuc.edu>2008-05-08 20:48:44 -0500
committerjluehrs2 <jluehrs2@uiuc.edu>2008-05-08 20:48:44 -0500
commita470747864e9774c512e611ecc39e389c242af80 (patch)
tree30063b26061f48358d747977a77e308f07192655 /lib
downloadapp-hiveminder-a470747864e9774c512e611ecc39e389c242af80.tar.gz
app-hiveminder-a470747864e9774c512e611ecc39e389c242af80.zip
initial framework, the create command works
Diffstat (limited to 'lib')
-rw-r--r--lib/App/Hiveminder.pm6
-rw-r--r--lib/App/Hiveminder/Base.pm13
-rw-r--r--lib/App/Hiveminder/Command/create.pm31
-rw-r--r--lib/App/Hiveminder/Utils.pm173
4 files changed, 223 insertions, 0 deletions
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;