File Coverage

blib/lib/Mojolicious/Plugin/Images/Util.pm
Criterion Covered Total %
statement 76 87 87.3
branch 31 48 64.5
condition 6 10 60.0
subroutine 11 13 84.6
pod 6 6 100.0
total 130 164 79.2


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Images::Util;
2 9     9   721793 use Mojo::Base -base;
  9         25  
  9         54  
3 9     9   1271 use 5.20.0;
  9         28  
  9         273  
4 9     9   975 use experimental 'signatures';
  9         1362  
  9         41  
5              
6 9     9   873 use Exporter 'import';
  9         12  
  9         237  
7 9     9   1929 use IO::All;
  9         35177  
  9         63  
8              
9             our @EXPORT_OK = (
10             qw(install_route expand_static calc_static plugin_log check_dir check_id));
11             our %EXPORT_TAGS = (all => \@EXPORT_OK);
12              
13             my $INSECURE_IDS = $ENV{IMAGES_ALLOW_INSECURE_IDS};
14             my $INSECURE_DIRS = $ENV{IMAGES_ALLOW_INSECURE_DIRS};
15              
16 69 50   69 1 5151 sub check_dir($dir, $app) {
  69 50       121  
  69         88  
  69         69  
  69         69  
17 69 100       161 return $dir if $INSECURE_DIRS;
18 50         43 my $msg
19 50   100     195 = "insecure dir ${\ ( $dir // 'undef' ) }, set IMAGES_ALLOW_INSECURE_DIRS env to allow it";
20 50 100 100     1047 die $msg if !$dir || Mojo::Path->new($app->home)->contains("$dir");
21 31         4830 return $dir;
22             }
23              
24             # maybe too hard
25 72 50   72 1 171 sub check_id($id) {
  72 50       131  
  72         98  
  72         55  
26 72 100       187 return $id if $INSECURE_IDS;
27 50 100       350 die "insecure id $id, set IMAGES_ALLOW_INSECURE_IDS env to allow it"
28             unless $id =~ /^[\ \-\w\/]+$/;
29 45         266 return $id;
30             }
31              
32 45 50   45 1 1687 sub plugin_log($app, $tmpl, @args) {
  45         51  
  45         50  
  45         120  
  45         46  
33 45         131 my $msg = sprintf($tmpl, @args);
34 45         852 $app->log->debug("Mojolicious::Plugin::Images $msg");
35             }
36              
37 45 50   45 1 21031 sub calc_static($dir, $url_prefix, $home) {
  45 50       90  
  45         57  
  45         49  
  45         41  
  45         40  
38 45 100       91 return unless defined $url_prefix;
39              
40 43         126 $dir = io->dir($dir)->canonpath;
41 43 100       60001 $dir = $home->rel_dir($dir) unless io->dir($dir)->is_absolute;
42              
43 43         6209 my $prefix = Mojo::Path->new($url_prefix)->canonicalize->to_route;
44 43         5847 $prefix = Mojo::Path->new($prefix)->leading_slash(0)->trailing_slash(0);
45              
46 43 100       2755 $dir =~ s/$prefix$// or return;
47              
48 31         1962 io->dir($dir)->canonpath;
49             }
50              
51 34 50   34 1 20103 sub expand_static($dir, $url_prefix, $app) {
  34 50       84  
  34         50  
  34         45  
  34         35  
  34         31  
52 34 100       742 my $static_path = calc_static($dir, $url_prefix, $app->home) or return;
53 23         3852 $static_path = check_dir($static_path, $app);
54 20         404 my $paths = $app->static->paths;
55 20 100       538 push @$paths, $static_path unless grep { $_ eq $static_path } @$paths;
  30         155  
56             }
57              
58             # install route /$prefix/(*key)-$suffix.$ext
59 21 50   21 1 50 sub install_route($app, $moniker, $opts) {
  21 50       42  
  21         32  
  21         50  
  21         26  
  21         23  
60 21         148 my $placeholder = '(*images_id)';
61 21   50     57 my $end = $opts->{suffix} // '';
62 21 100       46 $end .= ".${\$opts->{ext}}" if $opts->{ext};
  20         41  
63 21         105 my $path = Mojo::Path->new($opts->{url_prefix})->leading_slash(1)
64             ->trailing_slash(1)->merge("${placeholder}${end}");
65              
66 21         4904 plugin_log($app, "Installing route GET $path for Images '$moniker'");
67 21     0   1100 $app->routes->get("$path")->to(cb => sub { _action(shift, $moniker) });
  0            
68             }
69              
70 0 0   0     sub _action($c, $moniker) {
  0 0          
  0            
  0            
  0            
71 0           my $id = $c->stash('images_id');
72 0           my $img = $c->images->$moniker;
73              
74 0           plugin_log($c->app, "Generating $moniker: $id");
75 0 0 0       return $c->reply->static($img->url($id))
76             if $img->exists($id) || $img->sync($id);
77              
78 0           return $c->reply->not_found;
79             }
80              
81             1;
82              
83             __END__