File Coverage

script/screenorama
Criterion Covered Total %
statement 11 21 52.3
branch 0 6 0.0
condition n/a
subroutine 3 5 60.0
pod n/a
total 14 32 43.7


line stmt bran cond sub pod time code
1             #!/usr/bin/env perl
2             BEGIN {
3 1     1   496 @Screenorama::ARGV = do {
4 1         1 my $i = 0;
5 1         3 for my $arg (@ARGV) {
6 0 0       0 last if $arg eq '--';
7 0         0 $i++;
8             }
9 1         3 splice @ARGV, $i, @ARGV, ();
10             };
11 1         19 shift @Screenorama::ARGV;
12             }
13 1     1   364 use Mojolicious::Lite;
  1         68071  
  1         4  
14 1     1   10080 use Mojo::IOLoop::ReadWriteFork;
  1         7248  
  1         12  
15              
16             my $config = $ENV{MOJO_CONFIG} ? plugin 'Config' : app->config;
17             my ($program, @program_args) = @Screenorama::ARGV ? @Screenorama::ARGV : split /\s/, ($ENV{SCREENORAMA_COMMAND} || '');
18              
19             $config->{conduit} ||= $ENV{SCREENORAMA_CONDUIT} || 'pty';
20             $config->{kill_signal} ||= $ENV{SCREENORAMA_KILL_SIGNAL} || 15;
21             $config->{program_args} ||= \@program_args;
22             $config->{program} ||= $program;
23             $config->{single} //= $ENV{SCREENORAMA_SINGLE} || 0;
24             $config->{stdin} //= $ENV{SCREENORAMA_STDIN} || 0;
25              
26             $program or die "Usage: $0 -- [args]\n";
27              
28             get '/' => sub {
29             my $c = shift;
30             my $url = $c->req->url->to_abs;
31              
32             $c->render('index', stream_base => $url->clone->base->scheme($url->scheme =~ /https/ ? 'wss' : 'ws'));
33             };
34              
35             if ($config->{single}) {
36             my $plugins = app->plugins;
37             my ($fork, $last);
38              
39             websocket '/stream' => sub {
40             my $c = shift;
41             my $cb = sub { $c->send({json => $_[1]}) };
42              
43             unless ($fork) {
44             $fork = _start_application($c);
45             $fork->on(close => sub { $plugins->emit(output => $last = {exit_value => $_[1], signal => $_[2]}) });
46             $fork->on(error => sub { $plugins->emit(output => $last = {error => $_[1]}) });
47             $fork->on(read => sub { $plugins->emit(output => {output => $_[1]}) });
48             }
49              
50             $plugins->on(output => $cb);
51             $c->on(finish => sub { $plugins->unsubscribe(output => $cb); });
52             $c->send({json => $last}) if $last;
53             };
54             }
55             else {
56             websocket '/stream' => sub {
57             my $c = shift;
58             my $fork = _start_application($c);
59              
60             Scalar::Util::weaken($c);
61             $c->on(finish => sub { $fork->kill($config->{kill_signal}); undef $fork; });
62             $fork->on(close => sub { $c->send({json => {exit_value => $_[1], signal => $_[2]}})->finish });
63             $fork->on(error => sub { $c->send({json => {error => $_[1]}})->finish });
64             $fork->on(read => sub { $c->send({json => {output => $_[1]}}) });
65             };
66             }
67              
68             app->start;
69              
70             #=============================================================================
71              
72             sub _start_application {
73 0     0     my $c = shift;
74 0           my $fork = Mojo::IOLoop::ReadWriteFork->new;
75              
76 0           Mojo::IOLoop->stream($c->tx->connection)->timeout(60);
77 0           $fork->start(conduit => $config->{conduit}, program => $config->{program}, program_args => $config->{program_args});
78 0 0   0     $c->on(json => sub { $fork->write(chr $_[1]->{key}) if $_[1]->{key} }) if $c->app->config->{stdin};
  0 0          
79 0           $c->send({json => {program => $program, program_args => \@program_args}});
80 0           $fork;
81             }
82             __DATA__