File Coverage

script/docsisious
Criterion Covered Total %
statement 28 28 100.0
branch n/a
condition n/a
subroutine 10 10 100.0
pod n/a
total 38 38 100.0


line stmt bran cond sub pod time code
1             #!/usr/bin/env perl
2 1     1   1590 use Mojolicious::Lite;
  1         38845  
  1         7  
3              
4 1     1   10206 use Mojo::File 'path';
  1         2  
  1         50  
5 1     1   5 use Mojo::Util 'steady_time';
  1         2  
  1         33  
6 1     1   393 use DOCSIS::ConfigFile qw( decode_docsis encode_docsis );
  1         45524  
  1         62  
7 1     1   8 use File::Basename;
  1         1  
  1         68  
8 1     1   6 use File::Spec::Functions qw( catdir catfile );
  1         2  
  1         38  
9 1     1   579 use FindBin;
  1         868  
  1         38  
10 1     1   341 use YAML::XS;
  1         1910  
  1         62  
11 1     1   29 BEGIN { unshift @INC, "$FindBin::Bin/../lib" }
12 1     1   391 use App::docsisious;
  1         2  
  1         7  
13              
14             my $STORAGE = $ENV{DOCSIS_STORAGE} || ($ENV{HOME} ? catdir $ENV{HOME}, '.docsisious' : '');
15             die "DOCSIS_STORAGE=/path/to/docsis/files need to be set" unless $STORAGE;
16             mkdir $STORAGE or die "mkdir $STORAGE: $!" unless -d $STORAGE;
17             app->log->info("Will store DOCSIS config files in $STORAGE");
18              
19             get '/' => {layout => 'default'} => 'editor';
20             get '/css/docsis/:version' => [format => ['css']] => {template => 'css/docsis'};
21             get '/js/docsis/:version' => [format => ['js']] => {template => 'js/docsis'};
22              
23             my $download = sub {
24             my $c = shift;
25              
26             eval {
27             my $config = YAML::XS::Load($c->param('config'));
28             delete $config->{$_} for qw( CmMic CmtsMic );
29             my $binary = encode_docsis $config, {shared_secret => $c->param('shared_secret')};
30             my $filename = $c->param('filename') || $config->{filename} || sprintf '%s.bin', $c->paste_id;
31             $filename =~ s![^\w\.-]!-!g;
32             $c->res->headers->content_disposition("attachment; filename=$filename");
33             $c->render(data => $binary, format => 'binary');
34             } or do {
35             my $err = $@;
36             chomp $err;
37             $c->app->log->warn("Could not encode_docsis: $err");
38             $err =~ s! at \S+.*$!!s;
39             $c->render(error => "Cannot encode config file: $err", status => 400);
40             };
41             };
42              
43             my $save = sub {
44             my $c = shift;
45             my $id = $c->paste_id;
46             my $config = $c->param('config');
47             my %data;
48              
49             eval {
50             die 'Empty config' unless length $config;
51             $data{filename} = $c->param('filename');
52             $data{shared_secret} = $c->param('shared_secret');
53             $data{ts} = Mojo::Date->new->to_datetime;
54             $data{config} = YAML::XS::Load($config);
55             path($STORAGE, "$id.yaml")->spurt(YAML::XS::Dump(\%data));
56             $c->redirect_to('edit' => id => $id);
57             } or do {
58             my $err = $@;
59             chomp $err;
60             $err =~ s! at \S+.*$!!s;
61             $c->app->log->debug("Cannot encode config file: $err");
62             $c->render(error => "Cannot encode config file: $err", status => 400);
63             };
64             };
65              
66             my $upload = sub {
67             my $c = shift;
68             my $binary = $c->req->upload('binary');
69              
70             eval {
71             my $config = decode_docsis($binary->slurp);
72             $c->param(config => YAML::XS::Dump($config));
73             $c->param(filename => basename $binary->filename);
74             } or do {
75             my $err = $@;
76             chomp $err;
77             $err =~ s! at \S+.*$!!s;
78             $c->render(error => "Cannot decode config file: $err", status => 400);
79             };
80             };
81              
82             get(
83             '/edit/example' => {layout => 'default', template => 'editor'} => sub {
84             my $c = shift;
85             $c->param(config => Mojo::Loader::data_section(__PACKAGE__, 'example.yaml'));
86             $c->param(filename => 'example.bin');
87             },
88             'example',
89             );
90              
91             get(
92             '/edit/:id' => {layout => 'default', template => 'editor'} => sub {
93             my $c = shift;
94             my $id = $c->paste_id;
95             my $data = YAML::XS::Load(path($STORAGE, "$id.yaml")->slurp);
96             $c->param(config => YAML::XS::Dump($data->{config}));
97             $c->param(filename => $data->{filename});
98             $c->param(shared_secret => $data->{shared_secret});
99             },
100             'edit'
101             );
102              
103             post(
104             '/' => {layout => 'default', template => 'editor'} => sub {
105             my $c = shift;
106             return $c->$save if $c->param('save');
107             return $c->$download if $c->param('download');
108             return $c->$upload if $c->req->upload('binary');
109             return $c->render(text => "Either download, binary or save need to be present.\n", status => 400);
110             },
111             'save'
112             );
113              
114             helper paste_id => sub {
115             my $c = shift;
116             my $id = $c->param('id') || Mojo::Util::md5_sum($^T . $$ . steady_time);
117             die "Invalid id: $id" unless $id =~ /^\w+$/;
118             die "Invalid id: $id" if $id eq 'example';
119             return $id;
120             };
121              
122             app->home(Mojo::Home->new(App::docsisious->HOME));
123             app->static->paths([app->home->child('public')]);
124             app->defaults(error => '', VERSION => App::docsisious->VERSION);
125             app->defaults->{VERSION} =~ s!\W+!-!g;
126             app->start;
127              
128             __DATA__