File Coverage

lib/App/TimeTracker/Command/TellRemote.pm
Criterion Covered Total %
statement 29 40 72.5
branch 0 10 0.0
condition n/a
subroutine 10 11 90.9
pod n/a
total 39 61 63.9


line stmt bran cond sub pod time code
1             package App::TimeTracker::Command::TellRemote;
2 1     1   617 use strict;
  1         2  
  1         27  
3 1     1   5 use warnings;
  1         3  
  1         23  
4 1     1   17 use 5.010;
  1         3  
5              
6             our $VERSION = "3.001";
7             # ABSTRACT: App::TimeTracker plugin for telling generic remotes
8              
9 1     1   481 use Moose::Role;
  1         488979  
  1         4  
10 1     1   6714 use LWP::UserAgent;
  1         47343  
  1         42  
11 1     1   605 use Digest::SHA qw(sha1_hex);
  1         3390  
  1         91  
12 1     1   12 use URI::Escape;
  1         1  
  1         77  
13 1     1   541 use App::TimeTracker::Utils qw(error_message);
  1         10358  
  1         68  
14 1     1   649 use Encode;
  1         11349  
  1         447  
15              
16             has 'tell_remote' => (
17             is => 'ro',
18             isa => 'Bool',
19             default => 1,
20             documentation => 'TellRemote: tell generic remote',
21             traits => ['Getopt'],
22             );
23              
24             after [ 'cmd_start', 'cmd_continue' ] => sub {
25             my $self = shift;
26             return unless $self->tell_remote;
27             my $task = $self->_current_task;
28             $self->_tell_remote( start => $task );
29             };
30              
31             after 'cmd_stop' => sub {
32             my $self = shift;
33             return unless $self->tell_remote;
34             return unless $self->_current_command eq 'cmd_stop';
35             my $task = App::TimeTracker::Data::Task->previous( $self->home );
36             $self->_tell_remote( stop => $task );
37             };
38              
39             sub _tell_remote {
40 0     0     my ( $self, $status, $task ) = @_;
41 0           my $cfg = $self->config->{tell_remote};
42 0 0         return unless $cfg;
43              
44 0           my $ua = LWP::UserAgent->new( timeout => 3 );
45 0 0         my $message
46             = $task->user
47             . ( $status eq 'start' ? ' is now' : ' stopped' )
48             . ' working on '
49             . $task->say_project_tags;
50             # Use bytes for creating the digest, otherwise we'll get into trouble
51             # https://rt.cpan.org/Public/Bug/Display.html?id=93139
52 0 0         my $token = sha1_hex( encode_utf8($message), $cfg->{secret} ) if $cfg->{secret} ;
53              
54 0           my $url = $cfg->{url} . '?message=' . uri_escape_utf8($message);
55 0 0         $url .= '&token='. $token if $cfg->{secret};
56              
57 0           my $res = $ua->get($url);
58 0 0         unless ( $res->is_success ) {
59 0           error_message( 'Could not post to remote status via %s: %s',
60             $url, $res->status_line );
61             }
62             }
63              
64 1     1   9 no Moose::Role;
  1         1  
  1         11  
65             1;
66              
67             __END__
68              
69             =pod
70              
71             =encoding UTF-8
72              
73             =head1 NAME
74              
75             App::TimeTracker::Command::TellRemote - App::TimeTracker plugin for telling generic remotes
76              
77             =head1 VERSION
78              
79             version 3.001
80              
81             =head1 DESCRIPTION
82              
83             We use an internal IRC channel for internal communication. And we all want (need) to know what other team members are currently doing. This plugin helps us making sharing this information easy. B<Update:> We moved to a L<matrix|https://matrix.org> chat, and this plugin still works..
84              
85             After running some commands, this plugin prepares a short message and sends it (together with an authentification token) to a small webserver-cum-irc-bot (C<Bot::FromHTTP>, not yet on CPAN, but basically just a slightly customized/enhanced pastebin).
86              
87             In fact, you can post the message to any Webhook, eg C<Net::Matrix::Webhook>
88              
89             The messages is transfered as a GET-Request like this:
90              
91             http://yourserver/?message=some message&token=a58875d576e8c09a...
92              
93             =head1 CONFIGURATION
94              
95             =head2 plugins
96              
97             add C<TellRemote> to your list of plugins
98              
99             =head2 tell_remote
100              
101             add a hash named C<tell_remote>, containing the following keys:
102              
103             =head3 url
104              
105             The URL where the webhook is running. Might also contain a special port number (C<http://ircbox.vpn.yourcompany.com:9090>)
106              
107             =head3 secret
108              
109             An optional shared secret used to calculate the authentification token. The token is calculated like this:
110              
111             my $token = Digest::SHA::sha1_hex($message, $secret);
112              
113             If no secret is used, no token added to the request to the webhook
114              
115             =head1 NEW COMMANDS
116              
117             none
118              
119             =head1 CHANGES TO OTHER COMMANDS
120              
121             =head2 start, stop, continue
122              
123             After running the respective command, a message is sent to the
124             remote that could for example post the message to IRC.
125              
126             =head3 New Options
127              
128             =head4 --tell_remote
129              
130             Defaults to true, but you can use:
131              
132             ~/perl/Your-Secret-Project$ tracker start --no_tell_remote
133              
134             to B<not> send a message
135              
136             =head1 AUTHOR
137              
138             Thomas Klausner <domm@cpan.org>
139              
140             =head1 COPYRIGHT AND LICENSE
141              
142             This software is copyright (c) 2014 - 2019 by Thomas Klausner.
143              
144             This is free software; you can redistribute it and/or modify it under
145             the same terms as the Perl 5 programming language system itself.
146              
147             =cut