App-TimeTracker-Command-Trello
view release on metacpan or search on metacpan
lib/App/TimeTracker/Command/Trello.pm view on Meta::CPAN
package App::TimeTracker::Command::Trello;
# ABSTRACT: App::TimeTracker Trello plugin
our $VERSION = '1.008'; # VERSION
use strict;
use warnings;
use 5.010;
use App::TimeTracker::Utils qw(error_message warning_message);
use Moose::Role;
use WWW::Trello::Lite;
use JSON::XS qw(encode_json decode_json);
use Path::Class;
has 'trello' => (
is => 'rw',
isa => 'Str',
documentation => 'Trello card id',
predicate => 'has_trello'
);
has 'trello_client' => (
is => 'rw',
isa => 'Maybe[WWW::Trello::Lite]',
lazy_build => 1,
traits => ['NoGetopt'],
);
has 'trello_card' => (
is => 'ro',
lazy_build => 1,
traits => ['NoGetopt'],
predicate => 'has_trello_card'
);
sub _build_trello_card {
my ($self) = @_;
return unless $self->has_trello;
return $self->_trello_fetch_card( $self->trello );
}
sub _build_trello_client {
my $self = shift;
my $config = $self->config->{trello};
unless ( $config->{key} && $config->{token} ) {
error_message(
"Please configure Trello in your TimeTracker config or run 'tracker setup_trello'"
);
return;
}
return WWW::Trello::Lite->new(
key => $self->config->{trello}{key},
token => $self->config->{trello}{token},
);
}
around BUILDARGS => sub {
my $orig = shift;
my $class = shift;
my %args;
if (scalar @_ == 1) {
my $ref = shift(@_);
%args = %$ref;
}
else {
%args = @_;
}
if ( $args{trello} && $args{trello} =~ /^https/ ) {
lib/App/TimeTracker/Command/Trello.pm view on Meta::CPAN
$in =~ s/\s+//;
if ( $in =~ /^y/i ) {
say "Your Boards:";
my $boards = $self->_do_trello( 'get',
'members/' . $conf->{member_id} . '/boards' );
my $cnt = 1;
foreach (@$boards) {
printf( "%i: %s\n", $cnt, $_->{name} );
$cnt++;
}
print "Your selection (number or nothing to skip): ";
my $in = <STDIN>;
$in =~ s/\D//;
if ($in) {
$conf->{board_id} = $local{board_id} =
$boards->[ $in - 1 ]->{id};
}
}
}
if ( keys %global ) {
$self->_trello_update_config( \%global,
$self->config->{_used_config_files}->[-1], 'global' );
}
if ( keys %local ) {
$self->_trello_update_config( \%local,
$self->config->{_used_config_files}->[0], 'local' );
}
}
sub _do_trello {
my ( $self, $method, $endpoint, @args ) = @_;
my $client = $self->trello_client;
exit 1 unless $client;
my $res = $client->$method( $endpoint, @args );
if ( $res->failed ) {
error_message(
"Cannot talk to Trello API: " . $res->error . ' ' . $res->code );
if ( $res->code == 401 ) {
say "Maybe running 'tracker setup_trello' will help...";
}
exit 1;
}
else {
return $res->data;
}
}
sub _trello_update_config {
my ( $self, $update, $file, $type ) = @_;
print "I will store the following keys\n\t"
. join( ', ', sort keys %$update )
. "\nin your $type config file\n$file\n";
print "(Y|n): ";
my $in = <STDIN>;
$in =~ s/\s+//;
unless ( $in =~ /^n/i ) {
my $f = file($file);
my $old = JSON::XS->new->utf8->relaxed->decode(
scalar $f->slurp( iomode => '<:encoding(UTF-8)' ) );
while ( my ( $k, $v ) = each %$update ) {
$old->{trello}{$k} = $v;
}
$f->spew(
iomode => '>:encoding(UTF-8)',
JSON::XS->new->utf8->pretty->encode($old)
);
}
}
sub _trello_fetch_card {
my ( $self, $trello_tag ) = @_;
my %search = (
query => $trello_tag,
card_fields => 'shortLink',
modelTypes => 'cards'
);
if ( my $board_id = $self->config->{trello}{board_id} ) {
$search{idBoards} = $board_id;
}
my $result = $self->_do_trello( 'get', 'search', \%search );
my $cards = $result->{cards};
unless ( @$cards == 1 ) {
warning_message(
"Could not identify trello card via '" . $trello_tag . "'" );
return;
}
my $id = $cards->[0]{id};
my $card = $self->_do_trello( 'get', 'cards/' . $id );
return $card;
}
sub _trello_fetch_lists {
my $self = shift;
my $board_id = $self->config->{trello}{board_id};
return unless $board_id;
my $rv = $self->_do_trello( 'get', 'boards/' . $board_id . '/lists' );
my %lists;
my $map = $self->config->{trello}{list_map}
|| {
'To Do' => 'todo',
'Doing' => 'doing',
'Done' => 'done',
};
foreach my $list (@$rv) {
next unless my $tracker_name = $map->{ $list->{name} };
$lists{$tracker_name} = $list;
}
return \%lists;
}
sub _trello_just_the_name {
my ( $self, $card ) = @_;
my $name = $card->{name};
my $tr = $self->trello;
$name =~ s/$tr:\s?//;
$name =~ s/\[(.*?)\]//g;
return $name;
}
sub _tag_listname {
my ( $self, $card ) = @_;
( run in 1.332 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )