line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Mojolicious::Plugin::StaticShare::Controller; |
2
|
1
|
|
|
1
|
|
17652
|
use Mojo::Base 'Mojolicious::Controller'; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
7
|
|
3
|
1
|
|
|
1
|
|
260
|
use Mojo::File qw(path); |
|
1
|
|
|
|
|
27
|
|
|
1
|
|
|
|
|
62
|
|
4
|
1
|
|
|
1
|
|
577
|
use HTTP::AcceptLanguage; |
|
1
|
|
|
|
|
2507
|
|
|
1
|
|
|
|
|
31
|
|
5
|
1
|
|
|
1
|
|
10
|
use Mojo::Path; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
6
|
1
|
|
|
1
|
|
33
|
use Mojo::Util qw ( decode encode url_unescape xml_escape);# |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
71
|
|
7
|
1
|
|
|
1
|
|
612
|
use Time::Piece;# module replaces the standard localtime and gmtime functions with implementations that return objects |
|
1
|
|
|
|
|
7305
|
|
|
1
|
|
|
|
|
5
|
|
8
|
|
|
|
|
|
|
#~ use Mojo::Asset::File; |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
has plugin => sub { shift->stash('plugin') }; |
11
|
|
|
|
|
|
|
has public_uploads => sub { shift->plugin->public_uploads }; |
12
|
|
|
|
|
|
|
has is_admin => sub { |
13
|
|
|
|
|
|
|
my $c = shift; |
14
|
|
|
|
|
|
|
$c->plugin->is_admin($c); |
15
|
|
|
|
|
|
|
}; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
sub get { |
18
|
1
|
|
|
1
|
0
|
402
|
my ($c) = @_; |
19
|
|
|
|
|
|
|
|
20
|
1
|
|
|
|
|
5
|
$c->_stash(); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
return $c->not_found |
23
|
1
|
50
|
33
|
|
|
59
|
if !$c->is_admin && grep {/^\./} @{$c->stash('url_path')->parts}; |
|
0
|
|
|
|
|
0
|
|
|
1
|
|
|
|
|
19
|
|
24
|
|
|
|
|
|
|
|
25
|
1
|
50
|
|
|
|
27
|
if ($c->plugin->access) { |
26
|
0
|
0
|
|
|
|
0
|
my $access = ref $c->plugin->access eq 'CODE' ? $c->plugin->access->($c) : $c->plugin->access; |
27
|
|
|
|
|
|
|
|
28
|
0
|
0
|
|
|
|
0
|
return $c->not_found |
29
|
|
|
|
|
|
|
unless $access; |
30
|
|
|
|
|
|
|
|
31
|
0
|
0
|
|
|
|
0
|
return $c->render(%$access) |
32
|
|
|
|
|
|
|
if ref $access eq 'HASH'; |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
1
|
50
|
33
|
|
|
8
|
if ($c->is_admin && $c->param('admin')) { |
36
|
|
|
|
|
|
|
# Temporary Redirect |
37
|
0
|
|
|
|
|
0
|
$c->res->code(307); |
38
|
0
|
|
|
|
|
0
|
return $c->redirect_to($c->req->url->to_abs->path); |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
1
|
|
|
|
|
8
|
my $file_path = $c->stash('file_path'); |
42
|
|
|
|
|
|
|
|
43
|
1
|
50
|
|
|
|
12
|
return $c->dir($file_path) |
44
|
|
|
|
|
|
|
if -d $file_path; |
45
|
0
|
0
|
|
|
|
0
|
return $c->file($file_path) |
46
|
|
|
|
|
|
|
if -f $file_path; |
47
|
|
|
|
|
|
|
|
48
|
0
|
|
|
|
|
0
|
$c->not_found; |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub post { |
52
|
0
|
|
|
0
|
0
|
0
|
my ($c) = @_; |
53
|
0
|
|
|
|
|
0
|
$c->_stash(); |
54
|
|
|
|
|
|
|
|
55
|
0
|
|
|
|
|
0
|
my $file_path = $c->stash('file_path'); |
56
|
0
|
|
|
|
|
0
|
my $url_path = $c->stash('url_path'); |
57
|
|
|
|
|
|
|
|
58
|
0
|
0
|
|
|
|
0
|
$c->app->log->debug($file_path, $url_path->to_route, $c->dumper($c->req->params->to_hash)) |
59
|
|
|
|
|
|
|
if $c->plugin->debug; |
60
|
|
|
|
|
|
|
|
61
|
0
|
0
|
0
|
|
|
0
|
if (my $dir = $c->param('dir')) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
62
|
0
|
0
|
|
|
|
0
|
return $c->new_dir($file_path, $dir) |
63
|
|
|
|
|
|
|
if $c->is_admin; |
64
|
0
|
|
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('you cant create dir')}); |
65
|
|
|
|
|
|
|
} elsif (my $rename = $c->param('rename')) { |
66
|
0
|
0
|
|
|
|
0
|
return $c->rename($file_path, $rename) |
67
|
|
|
|
|
|
|
if $c->is_admin; |
68
|
0
|
|
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('you cant rename')}); |
69
|
|
|
|
|
|
|
} elsif (my $delete = $c->param('delete[]') && $c->every_param('delete[]')) { |
70
|
0
|
0
|
|
|
|
0
|
return $c->delete($file_path, $delete) |
71
|
|
|
|
|
|
|
if $c->is_admin; |
72
|
0
|
|
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('you cant delete')}); |
73
|
|
|
|
|
|
|
} elsif (defined (my $edit = $c->param('edit'))) { |
74
|
0
|
0
|
|
|
|
0
|
return $c->_edit($file_path, $edit) |
75
|
|
|
|
|
|
|
if $c->is_admin; |
76
|
0
|
|
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('you cant edit')}); |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
return $c->render(json=>{error=>$c->i18n('target directory not found')}) |
80
|
0
|
0
|
0
|
|
|
0
|
if !$c->is_admin && grep {/^\./} @{$c->stash('url_path')->parts}; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
81
|
|
|
|
|
|
|
|
82
|
0
|
0
|
0
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('you cant upload')}) |
83
|
|
|
|
|
|
|
unless $c->is_admin || $c->public_uploads; |
84
|
|
|
|
|
|
|
|
85
|
0
|
|
0
|
|
|
0
|
my $name = url_unescape($c->param('name') || '');#$file->filename |
86
|
0
|
|
|
|
|
0
|
utf8::upgrade($name); |
87
|
|
|
|
|
|
|
#~ return $c->render(json=>{error=>$c->i18n('Provide the name of upload file')}) |
88
|
|
|
|
|
|
|
#~ unless $name =~ /\S/i; |
89
|
|
|
|
|
|
|
|
90
|
0
|
0
|
0
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('Cant open target directory')}) |
91
|
|
|
|
|
|
|
unless !$name || -w $file_path; |
92
|
|
|
|
|
|
|
#~ $c->req->max_message_size(0); |
93
|
|
|
|
|
|
|
# Check file size |
94
|
0
|
0
|
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('upload is too big')}, status=>417) |
95
|
|
|
|
|
|
|
if $c->req->is_limit_exceeded; |
96
|
|
|
|
|
|
|
|
97
|
0
|
0
|
|
|
|
0
|
my $file = $c->req->upload('file') |
98
|
|
|
|
|
|
|
or return $c->render(json=>{error=>$c->i18n('Where is your upload file?')}); |
99
|
|
|
|
|
|
|
|
100
|
0
|
0
|
|
|
|
0
|
my $to = $name ? $file_path->child($name) : $file_path; |
101
|
|
|
|
|
|
|
|
102
|
0
|
0
|
0
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('path is not a directory')}) |
103
|
|
|
|
|
|
|
unless !$name || -d $file_path; |
104
|
0
|
0
|
0
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('path is a directory')}) |
105
|
|
|
|
|
|
|
if !$name && -d $to; |
106
|
|
|
|
|
|
|
|
107
|
0
|
0
|
0
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('file already exists')}) |
108
|
|
|
|
|
|
|
if !$c->param('replace') && -e $to; |
109
|
|
|
|
|
|
|
|
110
|
0
|
0
|
|
|
|
0
|
eval { $file->asset->move_to($to) } |
|
0
|
|
|
|
|
0
|
|
111
|
|
|
|
|
|
|
or return $c->render(json=>{error=>$@ =~ /(.+) at /}); |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
|
114
|
0
|
0
|
|
|
|
0
|
$url_path->merge($name) |
115
|
|
|
|
|
|
|
if $name; |
116
|
|
|
|
|
|
|
|
117
|
0
|
|
|
|
|
0
|
$c->render(json=>{ok=> $url_path->trailing_slash(0)->to_route}); |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# TODO DELETE request |
121
|
|
|
|
|
|
|
sub delete { |
122
|
|
|
|
|
|
|
my ($c) = @_; |
123
|
|
|
|
|
|
|
$c->_stash(); |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
my $file_path = $c->stash('file_path'); |
126
|
|
|
|
|
|
|
my $url_path = $c->stash('url_path'); |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
$c->app->log->debug($file_path, $url_path->to_route, $c->dumper($c->req->params->to_hash)) |
129
|
|
|
|
|
|
|
if $c->plugin->debug; |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub _stash { |
134
|
1
|
|
|
1
|
|
3
|
my ($c) = @_; |
135
|
|
|
|
|
|
|
|
136
|
1
|
|
50
|
|
|
6
|
my $lang = HTTP::AcceptLanguage->new($c->req->headers->accept_language || 'en;q=0.5'); |
137
|
1
|
|
|
|
|
148
|
$c->stash('language' => $lang); |
138
|
|
|
|
|
|
|
|
139
|
1
|
|
|
|
|
32
|
my $pth = Mojo::Path->new($c->stash('pth'))->leading_slash(0)->trailing_slash(0); |
140
|
1
|
50
|
|
|
|
97
|
$pth = $pth->trailing_slash(1)->merge('.'.$c->stash('format')) |
141
|
|
|
|
|
|
|
if $c->stash('format'); |
142
|
1
|
|
|
|
|
14
|
$c->stash('pth' => $pth); |
143
|
1
|
|
|
|
|
31
|
my $url_path = $c->plugin->root_url->clone->merge($pth)->trailing_slash(1); |
144
|
1
|
|
|
|
|
252
|
$c->stash('url_path' => $url_path); |
145
|
|
|
|
|
|
|
#~ $c->stash('file_path' => $c->plugin->root_dir->clone->merge($c->stash('pth'))); |
146
|
1
|
|
|
|
|
18
|
$c->stash('file_path' => path(decode('UTF-8', url_unescape($c->plugin->root_dir->clone->merge($pth))))); |
147
|
1
|
|
|
|
|
710
|
$c->stash('title' => $c->i18n('Share')." ".$url_path->to_route); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
sub dir { |
152
|
1
|
|
|
1
|
0
|
28
|
my ($c, $path) = @_; |
153
|
|
|
|
|
|
|
|
154
|
1
|
50
|
50
|
|
|
4
|
return $c->not_found |
155
|
|
|
|
|
|
|
if ($c->plugin->render_dir // '') eq 0; |
156
|
|
|
|
|
|
|
|
157
|
1
|
|
|
|
|
17
|
my $ex = Mojo::Exception->new($c->i18n(qq{Cant open directory})); |
158
|
1
|
50
|
0
|
|
|
20
|
opendir(my $dir, $path) |
159
|
|
|
|
|
|
|
or return $c->render_maybe('Mojolicious-Plugin-StaticShare/exception', format=>'html', handler=>'ep', status=>500, exception=>$ex) |
160
|
|
|
|
|
|
|
|| $c->reply->exception($ex); |
161
|
|
|
|
|
|
|
|
162
|
1
|
|
|
|
|
56
|
my $files = $c->stash('files' => [])->stash('files'); |
163
|
1
|
|
|
|
|
28
|
my $dirs = $c->stash('dirs' => [])->stash('dirs'); |
164
|
|
|
|
|
|
|
|
165
|
1
|
|
|
|
|
59
|
while (readdir $dir) { |
166
|
|
|
|
|
|
|
next |
167
|
17
|
100
|
100
|
|
|
1634
|
if $_ eq '.' || $_ eq '..'; |
168
|
|
|
|
|
|
|
next |
169
|
15
|
50
|
33
|
|
|
51
|
if !$c->is_admin && /^\./; |
170
|
|
|
|
|
|
|
|
171
|
15
|
|
|
|
|
119
|
my $child = $path->child(decode('UTF-8', $_)); |
172
|
|
|
|
|
|
|
|
173
|
15
|
100
|
50
|
|
|
520
|
push @$dirs, decode('UTF-8', $_) |
|
|
|
66
|
|
|
|
|
174
|
|
|
|
|
|
|
and next |
175
|
|
|
|
|
|
|
if -d $child && -r _; |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
next |
178
|
11
|
50
|
|
|
|
267
|
unless -f _; |
179
|
|
|
|
|
|
|
|
180
|
11
|
|
|
|
|
40
|
my @stat = stat $child; |
181
|
|
|
|
|
|
|
|
182
|
11
|
|
100
|
|
|
188
|
push @$files, { |
183
|
|
|
|
|
|
|
name => decode('UTF-8', $_), |
184
|
|
|
|
|
|
|
size => $stat[7] || 0, |
185
|
|
|
|
|
|
|
#~ type => $c->plugin->mime->type( (/\.([0-9a-zA-Z]+)$/)[0] || 'txt' ) || 'application/octet-stream', |
186
|
|
|
|
|
|
|
mtime => decode('UTF-8', localtime( $stat[9] )->strftime), #->to_datetime, #to_string(), |
187
|
|
|
|
|
|
|
#~ mode=> $stat[2] & 07777, #-r _, |
188
|
|
|
|
|
|
|
}; |
189
|
|
|
|
|
|
|
} |
190
|
1
|
|
|
|
|
144
|
closedir $dir; |
191
|
|
|
|
|
|
|
|
192
|
1
|
50
|
|
|
|
7
|
for my $index ($c->plugin->dir_index ? @{$c->plugin->dir_index} : ()) { |
|
1
|
|
|
|
|
27
|
|
193
|
3
|
|
|
|
|
83
|
my $file = $path->child($index); |
194
|
|
|
|
|
|
|
next |
195
|
3
|
100
|
|
|
|
65
|
unless -f $file; |
196
|
|
|
|
|
|
|
|
197
|
1
|
50
|
0
|
|
|
21
|
$c->_stash_markdown($file) |
|
|
|
0
|
|
|
|
|
198
|
|
|
|
|
|
|
and $c->stash(index=>$index) |
199
|
|
|
|
|
|
|
and last |
200
|
|
|
|
|
|
|
if $index =~ $c->plugin->re_markdown; |
201
|
|
|
|
|
|
|
|
202
|
1
|
50
|
33
|
|
|
7
|
$c->_stash_pod($file) |
|
|
|
50
|
|
|
|
|
203
|
|
|
|
|
|
|
and $c->stash(index=>$index) |
204
|
|
|
|
|
|
|
and last |
205
|
|
|
|
|
|
|
if $index =~ $c->plugin->re_pod; |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
|
209
|
1
|
0
|
|
|
|
4479
|
return $c->render(ref $c->plugin->render_dir ? %{$c->plugin->render_dir} : $c->plugin->render_dir,) |
|
0
|
50
|
|
|
|
0
|
|
210
|
|
|
|
|
|
|
if $c->plugin->render_dir; |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
$c->render_maybe("Mojolicious-Plugin-StaticShare/$_/dir", format=>'html', handler=>'ep',) |
213
|
|
|
|
|
|
|
and return |
214
|
1
|
|
50
|
|
|
18
|
for $c->stash('language')->languages; |
215
|
|
|
|
|
|
|
|
216
|
1
|
|
|
|
|
4982
|
return $c->render('Mojolicious-Plugin-StaticShare/dir', format=>'html', handler=>'ep',); |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
#~ $c->render_maybe('Mojolicious-Plugin-StaticShare/exception', format=>'html', handler=>'ep', status=>500,exception=>Mojo::Exception->new(qq{Template rendering for dir content not found})) |
220
|
|
|
|
|
|
|
#~ or $c->reply->exception(); |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub new_dir { |
224
|
0
|
|
|
0
|
0
|
0
|
my ($c, $path, $dir) = @_; |
225
|
|
|
|
|
|
|
|
226
|
0
|
|
|
|
|
0
|
my $edir = url_unescape($dir); |
227
|
0
|
|
|
|
|
0
|
utf8::upgrade($edir); |
228
|
|
|
|
|
|
|
|
229
|
0
|
0
|
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('provide the name of new directory')}) |
230
|
|
|
|
|
|
|
unless $edir =~ /\S/; |
231
|
|
|
|
|
|
|
|
232
|
0
|
|
|
|
|
0
|
my $to = $path->child($edir);# |
233
|
|
|
|
|
|
|
|
234
|
0
|
0
|
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('dir or file exists')}) |
235
|
|
|
|
|
|
|
if -e $to; |
236
|
|
|
|
|
|
|
|
237
|
0
|
|
|
|
|
0
|
$to->make_path; |
238
|
|
|
|
|
|
|
|
239
|
0
|
|
|
|
|
0
|
$c->render(json=>{ok=> $c->stash('url_path')->clone->merge($dir)->trailing_slash(1)->to_route}); |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
sub rename { |
244
|
0
|
|
|
0
|
0
|
0
|
my ($c, $path, $rename) = @_; |
245
|
|
|
|
|
|
|
|
246
|
0
|
|
|
|
|
0
|
my $ename = url_unescape($rename); |
247
|
0
|
|
|
|
|
0
|
utf8::upgrade($ename); |
248
|
|
|
|
|
|
|
|
249
|
0
|
0
|
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('provide new name')}) |
250
|
|
|
|
|
|
|
unless $ename =~ /\S/; |
251
|
|
|
|
|
|
|
|
252
|
0
|
|
|
|
|
0
|
my $to = $path->sibling($ename); |
253
|
|
|
|
|
|
|
|
254
|
0
|
0
|
|
|
|
0
|
return $c->render(json=>{error=>$c->i18n('dir or file exists')}) |
255
|
|
|
|
|
|
|
if -e $to; |
256
|
|
|
|
|
|
|
|
257
|
0
|
0
|
|
|
|
0
|
my $move = eval { $path->move_to($to) } |
|
0
|
|
|
|
|
0
|
|
258
|
|
|
|
|
|
|
or return $c->render(json=>{error=>$@ =~ /(.+) at /}); |
259
|
|
|
|
|
|
|
|
260
|
0
|
|
|
|
|
0
|
$c->render(json=>{ok=> $c->stash('url_path')->trailing_slash(0)->to_dir->merge($rename)->to_route}); |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
sub delete { |
265
|
0
|
|
|
0
|
0
|
0
|
my ($c, $path, $delete) = @_; |
266
|
0
|
|
|
|
|
0
|
my @delete = (); |
267
|
0
|
|
|
|
|
0
|
for (@$delete) { |
268
|
0
|
|
|
|
|
0
|
my $del = url_unescape($_); |
269
|
0
|
|
|
|
|
0
|
utf8::upgrade($del); |
270
|
0
|
0
|
0
|
|
|
0
|
push @delete, $c->i18n('provide the name of deleted dir') |
271
|
|
|
|
|
|
|
and next |
272
|
|
|
|
|
|
|
unless $del =~ /\S/; |
273
|
0
|
|
|
|
|
0
|
my $d = $path->sibling($del); |
274
|
0
|
0
|
0
|
|
|
0
|
push @delete, $c->i18n('dir or file does not exists') |
275
|
|
|
|
|
|
|
and next |
276
|
|
|
|
|
|
|
unless -e $d; |
277
|
0
|
0
|
|
|
|
0
|
push @delete, eval {$d->remove_tree()} ? 1 : 0, |
|
0
|
|
|
|
|
0
|
|
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
0
|
|
|
|
|
0
|
$c->render(json=>{ok=>\@delete}); |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
sub file { |
284
|
0
|
|
|
0
|
0
|
0
|
my ($c, $path) = @_; |
285
|
|
|
|
|
|
|
|
286
|
0
|
|
|
|
|
0
|
my $ex = Mojo::Exception->new($c->i18n(qq{Permission denied})); |
287
|
0
|
0
|
0
|
|
|
0
|
return $c->render_maybe('Mojolicious-Plugin-StaticShare/exception', format=>'html', handler=>'ep', status=>500,exception=>$ex) |
288
|
|
|
|
|
|
|
|| $c->reply->exception($ex) |
289
|
|
|
|
|
|
|
unless -r $path; |
290
|
|
|
|
|
|
|
|
291
|
0
|
0
|
0
|
|
|
0
|
return $c->_edit($path) |
292
|
|
|
|
|
|
|
if $c->is_admin && $c->param('edit'); |
293
|
|
|
|
|
|
|
|
294
|
0
|
|
|
|
|
0
|
my $filename = $path->basename; |
295
|
|
|
|
|
|
|
|
296
|
0
|
0
|
0
|
|
|
0
|
return $c->_markdown($path) |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
297
|
|
|
|
|
|
|
unless ($c->plugin->render_markdown || '') eq 0 || $c->param('attachment') || $filename !~ $c->plugin->re_markdown; |
298
|
|
|
|
|
|
|
|
299
|
0
|
0
|
0
|
|
|
0
|
return $c->_pod($path) |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
300
|
|
|
|
|
|
|
unless ($c->plugin->render_pod || '') eq 0 || $c->param('attachment') || $filename !~ $c->plugin->re_pod; |
301
|
|
|
|
|
|
|
|
302
|
0
|
0
|
0
|
|
|
0
|
my $asset = $c->_html($path) |
303
|
|
|
|
|
|
|
unless $c->param('attachment') || $filename !~ $c->plugin->re_html; |
304
|
|
|
|
|
|
|
|
305
|
0
|
0
|
|
|
|
0
|
$c->res->headers->content_disposition($c->param('attachment') ? "attachment; filename=$filename;" : "inline"); |
306
|
0
|
|
0
|
|
|
0
|
my $type =$c->plugin->mime->type( ( $path =~ /\.([0-9a-zA-Z]+)$/)[0] || 'txt' ) || $c->plugin->mime->type('txt');#'application/octet-stream'; |
307
|
0
|
|
|
|
|
0
|
$c->res->headers->content_type($type); |
308
|
0
|
|
0
|
|
|
0
|
$c->reply->asset($asset || Mojo::Asset::File->new(path => $path)); |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub _html {# disable scripts inside html |
312
|
0
|
|
|
0
|
|
0
|
my ($c, $path) = @_; |
313
|
0
|
|
|
|
|
0
|
my $file = Mojo::Asset::File->new(path => $path); |
314
|
0
|
|
|
|
|
0
|
my $content = $file->slurp; |
315
|
0
|
|
|
|
|
0
|
my $dom = Mojo::DOM->new($content); |
316
|
0
|
0
|
|
|
|
0
|
$dom->find('script')->each(\&_sanitize_script)->size |
317
|
|
|
|
|
|
|
or return $file; |
318
|
|
|
|
|
|
|
|
319
|
0
|
|
|
|
|
0
|
my $asset = Mojo::Asset::Memory->new; |
320
|
0
|
|
|
|
|
0
|
$asset->add_chunk($dom)->mtime($file->mtime); |
321
|
0
|
|
|
|
|
0
|
return $asset; |
322
|
|
|
|
|
|
|
} |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
sub _markdown {# file |
325
|
0
|
|
|
0
|
|
0
|
my ($c, $path) = @_; |
326
|
|
|
|
|
|
|
|
327
|
0
|
|
|
|
|
0
|
my $ex = Mojo::Exception->new($c->i18n(qq{Please install or verify markdown module (default to Text::Markdown::Hoedown) with markdown(\$str) sub or parse(\$str) method})); |
328
|
|
|
|
|
|
|
|
329
|
0
|
0
|
0
|
|
|
0
|
$c->_stash_markdown($path) |
330
|
|
|
|
|
|
|
or return $c->render_maybe('Mojolicious-Plugin-StaticShare/exception', format=>'html', handler=>'ep', status=>500,exception=>$ex) |
331
|
|
|
|
|
|
|
|| $c->reply->exception($ex); |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
return $c->plugin->render_markdown |
334
|
0
|
0
|
|
|
|
0
|
? $c->render(ref $c->plugin->render_markdown ? %{$c->plugin->render_markdown} : $c->plugin->render_markdown,) |
|
0
|
0
|
|
|
|
0
|
|
335
|
|
|
|
|
|
|
: $c->render('Mojolicious-Plugin-StaticShare/markdown', format=>'html', handler=>'ep',); |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
my $layout_re = qr|^(?:\s*%+\s*layouts/(.+)[;\s]+)|; |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
sub _stash_markdown { |
341
|
0
|
|
|
0
|
|
0
|
my ($c, $path) = @_; |
342
|
0
|
0
|
|
|
|
0
|
my $md = $c->plugin->markdown |
343
|
|
|
|
|
|
|
or return; # not installed |
344
|
0
|
|
|
|
|
0
|
my $content = decode('UTF-8', $path->slurp); |
345
|
0
|
|
|
|
|
0
|
$content =~ s|$layout_re|$c->_layout_index($1)|e;#) {# || $content =~ s/(?:%\s*layout\s+"([^"]+)";?)//m |
|
0
|
|
|
|
|
0
|
|
346
|
0
|
|
|
|
|
0
|
my $dom = Mojo::DOM->new($md->parse($content)); |
347
|
0
|
|
|
|
|
0
|
$dom->find('script')->each(\&_sanitize_script); |
348
|
0
|
|
|
|
|
0
|
$dom->find('*')->each(\&_dom_attrs); |
349
|
0
|
|
0
|
|
|
0
|
$c->stash(markdown => $dom->at('body') || $dom); |
350
|
|
|
|
|
|
|
#~ my $filename = $path->basename; |
351
|
|
|
|
|
|
|
#~ $c->stash('title'=>$filename); |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
my $layout_ext_re = qr|\.([^/\.;\s]+)?\.?([^/\.;\s]+)?$|; # .html.ep |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
sub _layout_index {# from regexp execute |
357
|
0
|
|
|
0
|
|
0
|
my ($c, @match) = @_;# |
358
|
0
|
|
|
|
|
0
|
$match[0] =~ s|[;\s]+$||; |
359
|
|
|
|
|
|
|
#~ utf8::encode($match[0]); |
360
|
0
|
0
|
|
|
|
0
|
push @match, $1, $2 |
361
|
|
|
|
|
|
|
if $match[0] =~ s|$layout_ext_re||; |
362
|
0
|
|
0
|
|
|
0
|
my $found = $c->app->renderer->template_path({ |
|
|
|
0
|
|
|
|
|
363
|
|
|
|
|
|
|
template => "layouts/$match[0]", |
364
|
|
|
|
|
|
|
format => $match[1] || 'html', |
365
|
|
|
|
|
|
|
handler => $match[2] || 'ep', |
366
|
|
|
|
|
|
|
}); |
367
|
0
|
0
|
0
|
|
|
0
|
$c->layout($match[0])#encode('UTF-8', $match[0])) |
368
|
|
|
|
|
|
|
and return '' |
369
|
|
|
|
|
|
|
if $found; |
370
|
0
|
|
|
|
|
0
|
my $err = "layout [$match[0]].$match[1].$match[2] not found"; |
371
|
0
|
|
|
|
|
0
|
$c->app->log->error("$err", "\t app->renderer->paths: ", @{$c->app->renderer->paths}); |
|
0
|
|
|
|
|
0
|
|
372
|
0
|
|
|
|
|
0
|
return " $err "; |
373
|
|
|
|
|
|
|
} |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
sub _sanitize_script {# for markdown |
376
|
0
|
|
|
0
|
|
0
|
my $el = shift; |
377
|
0
|
|
|
|
|
0
|
my $text = xml_escape $el->text; |
378
|
0
|
|
|
|
|
0
|
$el->replace("$text "); |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
sub _dom_attrs {# for markdown |
382
|
|
|
|
|
|
|
# translate ^{...} to id, style, class attributes |
383
|
|
|
|
|
|
|
# берем только первый child и он должен быть текстом |
384
|
162
|
|
|
162
|
|
9646
|
my $el = shift; |
385
|
162
|
100
|
|
|
|
336
|
my $text = $el->text |
386
|
|
|
|
|
|
|
or return; |
387
|
144
|
|
|
|
|
4291
|
my $child1 = $el->child_nodes->first; |
388
|
144
|
|
|
|
|
10044
|
my $parent = $child1->parent; |
389
|
|
|
|
|
|
|
return |
390
|
144
|
100
|
33
|
|
|
5934
|
unless $parent && $parent->type eq 'tag' && $child1->type eq 'text'; |
|
|
|
66
|
|
|
|
|
391
|
141
|
|
|
|
|
2977
|
my $content = $child1->content; |
392
|
141
|
50
|
|
|
|
3006
|
if ($content =~ s|^(?:\s*\{([^\}]+)\}\s*)||) { |
393
|
0
|
|
|
|
|
0
|
my $attrs = $1; |
394
|
0
|
|
|
|
|
0
|
utf8::upgrade($attrs); |
395
|
|
|
|
|
|
|
# styles |
396
|
0
|
|
|
|
|
0
|
$parent->{style} .= " $1" |
397
|
|
|
|
|
|
|
while $attrs =~ s|(\S+\s*:\s*[^;]+;)||; |
398
|
|
|
|
|
|
|
# id |
399
|
0
|
|
|
|
|
0
|
$parent->{id} = $1 |
400
|
|
|
|
|
|
|
while $attrs =~ s|#(\S+)||; |
401
|
|
|
|
|
|
|
# classes |
402
|
0
|
|
|
|
|
0
|
$parent->{class} .= " $1" |
403
|
|
|
|
|
|
|
while $attrs =~ s|\.?([^\.\s]+)||; |
404
|
0
|
|
|
|
|
0
|
$child1->content($content);# replace |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
} |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
sub _pod {# file |
409
|
0
|
|
|
0
|
|
0
|
my ($c, $path) = @_; |
410
|
|
|
|
|
|
|
|
411
|
0
|
0
|
|
|
|
0
|
$c->_stash_pod($path) |
412
|
|
|
|
|
|
|
or return;# $c->render_maybe('Mojolicious-Plugin-StaticShare/exception', format=>'html', handler=>'ep', status=>500,exception=>$ex) |
413
|
|
|
|
|
|
|
#~ || $c->reply->exception($ex); |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
return $c->plugin->render_pod |
416
|
0
|
0
|
|
|
|
0
|
? $c->render(ref $c->plugin->render_pod ? %{$c->plugin->render_pod} : $c->plugin->render_pod,) |
|
0
|
0
|
|
|
|
0
|
|
417
|
|
|
|
|
|
|
: $c->render('Mojolicious-Plugin-StaticShare/pod', format=>'html', handler=>'ep',); |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
} |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
sub _stash_pod { |
422
|
1
|
|
|
1
|
|
3
|
my ($c, $path) = @_; |
423
|
|
|
|
|
|
|
return |
424
|
1
|
50
|
|
|
|
9
|
unless $c->app->renderer->helpers->{'pod_to_html'}; |
425
|
|
|
|
|
|
|
|
426
|
1
|
|
|
|
|
32
|
my $content = decode('UTF-8', $path->slurp); |
427
|
1
|
|
|
|
|
357
|
$content =~ s|$layout_re|$c->_layout_index($1)|e;#) {# || $content =~ s/(?:%\s*layout\s+"([^"]+)";?)//m |
|
0
|
|
|
|
|
0
|
|
428
|
1
|
|
|
|
|
16
|
my $dom = Mojo::DOM->new($c->pod_to_html($content)); |
429
|
1
|
|
|
|
|
21685
|
$dom->find('script')->each(\&_sanitize_script); |
430
|
1
|
|
|
|
|
4720
|
$dom->find('*')->each(\&_dom_attrs); |
431
|
1
|
|
33
|
|
|
54
|
$c->stash(pod => $dom->at('body') || $dom); |
432
|
|
|
|
|
|
|
#~ my $filename = $path->basename; |
433
|
|
|
|
|
|
|
#~ $c->stash('title'=>$filename); |
434
|
|
|
|
|
|
|
} |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
sub not_found { |
437
|
0
|
|
|
0
|
0
|
|
my $c = shift; |
438
|
0
|
0
|
|
|
|
|
$c->render_maybe('Mojolicious-Plugin-StaticShare/not_found', format=>'html', handler=>'ep', status=>404,) |
439
|
|
|
|
|
|
|
or $c->reply->not_found; |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
}; |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
sub _edit { |
444
|
0
|
|
|
0
|
|
|
my ($c, $path, $edit) = @_; |
445
|
0
|
0
|
|
|
|
|
unless (defined $edit) {# get |
446
|
0
|
|
|
|
|
|
$c->stash('edit'=> decode('UTF-8', $path->slurp)); |
447
|
0
|
|
|
|
|
|
$c->stash('title' => $c->i18n('Edit')." ".$c->stash('url_path')->to_route); |
448
|
0
|
|
|
|
|
|
return $c->render('Mojolicious-Plugin-StaticShare/edit', format=>'html', handler=>'ep',); |
449
|
|
|
|
|
|
|
} |
450
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
# save |
452
|
0
|
|
|
|
|
|
$path->spurt(encode('UTF-8', $edit)); |
453
|
0
|
|
|
|
|
|
$c->render(json=>{ok=>$path->to_string}); |
454
|
|
|
|
|
|
|
} |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
1; |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=pod |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
=encoding utf8 |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
Доброго всем |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=head1 Mojolicious::Plugin::StaticShare::Controller |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
¡ ¡ ¡ ALL GLORY TO GLORIA ! ! ! |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
=head1 NAME |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
Mojolicious::Plugin::StaticShare::Controller - is an internal controller for L. |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
=cut |