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 )