File Coverage

blib/lib/App/Notifier/Service.pm
Criterion Covered Total %
statement 32 43 74.4
branch 0 6 0.0
condition 0 5 0.0
subroutine 11 13 84.6
pod n/a
total 43 67 64.1


line stmt bran cond sub pod time code
1             package App::Notifier::Service;
2             $App::Notifier::Service::VERSION = '0.0902';
3 2     2   1204 use 5.014;
  2         8  
4              
5 2     2   11 use strict;
  2         4  
  2         41  
6 2     2   9 use warnings;
  2         3  
  2         47  
7              
8 2     2   1013 use Mojolicious::Lite;
  2         1068103  
  2         15  
9 2     2   50901 use Plack::Builder;
  2         18695  
  2         138  
10              
11 2     2   16 use File::Spec ();
  2         6  
  2         41  
12 2     2   13 use JSON::MaybeXS qw( decode_json );
  2         5  
  2         124  
13 2     2   1120 use YAML::XS qw( LoadFile );
  2         6029  
  2         136  
14 2     2   1198 use List::MoreUtils qw();
  2         26739  
  2         70  
15              
16 2     2   15 use POSIX ":sys_wait_h";
  2         5  
  2         22  
17 2     2   401 use Errno;
  2         4  
  2         2281  
18              
19             sub _REAPER
20             {
21 0     0     local $!; # don't let waitpid() overwrite current error
22 0   0       while ( ( my $pid = waitpid( -1, WNOHANG ) ) > 0 && WIFEXITED($?) )
23             {
24             }
25 0           $SIG{CHLD} = \&_REAPER; # loathe SysV
26             }
27              
28             # $SIG{CHLD} = \&_REAPER;
29              
30             my $config_fn = ( $ENV{'NOTIFIER_CONFIG'}
31             || File::Spec->catfile( $ENV{HOME}, '.app_notifier.yml' ) );
32              
33             my $config;
34              
35             sub _process_cmd_line_arg
36             {
37 0     0     my ( $arg, $text_params ) = @_;
38              
39 0 0         if ( ref($arg) eq '' )
    0          
40             {
41 0           return $arg;
42             }
43             elsif ( ref($arg) eq 'HASH' )
44             {
45 0 0         if ( $arg->{type} eq 'text_param' )
46             {
47 0   0       return ( $text_params->{ $arg->{param_name} } // '' );
48             }
49             else
50             {
51 0           die +{ msg => "Unknown special argument type $arg->{type}", };
52             }
53             }
54             else
55             {
56 0           die +{ msg =>
57             "Unhandled perl type for argument in command line template (should be string or hash.",
58             };
59             }
60              
61 0           return;
62             }
63              
64             get '/notify' => sub {
65             my $c = shift;
66              
67             $config ||= LoadFile($config_fn);
68              
69             my $cmd_id = ( $c->req->param('cmd_id') || 'default' );
70             my $text_params = {};
71             if ( defined( my $text_params_as_json = $c->req->param('text_params') ) )
72             {
73             $text_params = decode_json($text_params_as_json);
74             if ( ref($text_params) ne 'HASH' )
75             {
76             return "Invalid text_params - should be a JSON hash.\n";
77             }
78             elsif ( List::MoreUtils::any { ref($_) ne '' } values(%$text_params) )
79             {
80             return "Invalid text_params - all values must be strings.\n";
81             }
82             }
83             my $cmd = $config->{commands}->{$cmd_id};
84              
85             if ( defined($cmd) )
86             {
87             my @before_cmd_line = ( ( ref($cmd) eq 'ARRAY' ) ? @$cmd : $cmd );
88              
89             my @cmd_line = eval {
90             map { _process_cmd_line_arg( $_, $text_params ); } @before_cmd_line;
91             };
92              
93             if ( my $Err = $@ )
94             {
95             if ( ref($Err) eq 'HASH' and ( exists( $Err->{msg} ) ) )
96             {
97             return ( $Err->{msg} . "\n" );
98             }
99             else
100             {
101             die $Err;
102             }
103             }
104              
105             my $pid;
106             if ( !defined( $pid = fork() ) )
107             {
108             die "Cannot fork: $!";
109             }
110             elsif ( !$pid )
111             {
112             # I'm the child.
113             if ( fork() eq 0 )
114             {
115             # I'm the grandchild.
116             system { $cmd_line[0] } @cmd_line;
117             }
118             POSIX::_exit(0);
119             }
120             else
121             {
122             waitpid( $pid, 0 );
123             }
124             $c->render( text => "Success.\n" );
125             }
126             else
127             {
128             $c->log("Unknown Command ID '$cmd_id'.");
129             return "Unknown Command ID.\n";
130             }
131             };
132              
133             get '/' => sub {
134             my $c = shift;
135             $c->render( text => "OK\n" );
136             };
137              
138             builder
139             {
140             # enable 'Deflater';
141             app->start;
142             };
143              
144             # "true";
145              
146             # start;
147              
148             __END__