Alex 'AdUser' Z
7 years ago
1 changed files with 180 additions and 0 deletions
@ -0,0 +1,180 @@
|
||||
package LDV::Filebin; |
||||
|
||||
use strict; |
||||
use warnings; |
||||
use utf8; |
||||
|
||||
use Mojo::Base 'Mojolicious::Controller'; |
||||
use Mojo::Asset::File; |
||||
|
||||
use File::MimeInfo::Magic qw(mimetype); |
||||
use Imager; |
||||
|
||||
sub _file_path { |
||||
my ($self, $fname, $fext, $full) = @_; |
||||
|
||||
my $path = sprintf "/files/%s.%s", $fname, $fext; |
||||
return $full ? $self->app->home->rel_file("public/$path") : $path; |
||||
} |
||||
|
||||
sub create { |
||||
my ($self) = @_; |
||||
|
||||
$self->access_allowed($self->app->config->{filebin}->{access}) |
||||
or return; |
||||
|
||||
$self->render; |
||||
} |
||||
|
||||
sub view { |
||||
my ($self) = @_; |
||||
my $time = $self->stash('time') || 0; |
||||
|
||||
eval { |
||||
my $now = time(); |
||||
my $file = $self->app->db->select('filebin', '*', {created => $time, expire => {'>=' => $now}})->hash |
||||
or die "file not found\n"; |
||||
$file->{path} = $self->_file_path($time, $file->{fext}); |
||||
|
||||
$self->stash({file => $file}); 1; |
||||
$self->render; 1; |
||||
} or do { |
||||
chomp $@; |
||||
$self->flash({error => $@}); |
||||
$self->app->log->error($@); |
||||
$self->redirect_to('/filebin'); |
||||
}; |
||||
|
||||
$self->rendered; |
||||
} |
||||
|
||||
sub save { |
||||
my ($self) = @_; |
||||
|
||||
$self->access_allowed($self->app->config->{filebin}->{access}) |
||||
or return; |
||||
|
||||
eval { |
||||
my $time = time(); |
||||
my $conf = $self->app->config->{filebin}; |
||||
|
||||
die "request too large\n" |
||||
if $self->req->is_limit_exceeded; |
||||
|
||||
my $expire = $self->req->param('expire') || 7; # days |
||||
my $upload = $self->req->upload('file'); |
||||
die "no file uploaded\n" unless ($upload and $upload->size > 0); |
||||
die "file too large\n" if ($upload->size > $conf->{file_maxsize}); |
||||
|
||||
{ # hack: don't use memory backend |
||||
my $path = POSIX::tmpnam; |
||||
$upload->move_to($path); |
||||
$upload->asset(Mojo::Asset::File->new(path => $path)); |
||||
$upload->asset->cleanup(1); # rearm self-destruction |
||||
} |
||||
|
||||
my $file = { |
||||
created => $time, expire => $time + $expire * 86400, |
||||
ftype => 'b', # default -- generic binary |
||||
fsize => $upload->size, |
||||
fname => $upload->filename, |
||||
fmime => mimetype($upload->asset->path), |
||||
fext => '', |
||||
res_w => 0, |
||||
res_h => 0, |
||||
}; |
||||
|
||||
if ($file->{fname} =~ m<\.([a-z0-9]{1,5})$>oi) { |
||||
$file->{fext} = lc($1); |
||||
} |
||||
if ($file->{fmime} =~ m{^image/}o) { |
||||
my ($max_w, $max_h) = ($conf->{image_maxres} =~ m/(\d+)x(\d+)/oi); |
||||
Imager->set_file_limits( |
||||
width => $max_w, height => $max_h, |
||||
bytes => $conf->{image_maxmem}, |
||||
); |
||||
# query image |
||||
my $image = Imager->new(file => $upload->asset->path) |
||||
or die(Imager->errstr() . "\n"); |
||||
$file->{ftype} = 'i'; |
||||
$file->{fext} = $image->tags(name => 'i_format'), |
||||
$file->{res_w} = $image->getwidth, |
||||
$file->{res_h} = $image->getheight, |
||||
# make thumb |
||||
my ($th_w, $th_h) = ($conf->{thumbs_size} =~ m/(\d+)x(\d+)/oi); |
||||
my $thumb = $image->scale(xpixels => $th_w, ypixels => $th_h, type => 'min'); |
||||
my $path = $self->_file_path("${time}_th", $conf->{thumbs_ext}, 'fullpath'); |
||||
$thumb->write(file => $path) |
||||
or die $thumb->errstr; |
||||
} elsif ($file->{fmime} =~ m{^video/}o) { |
||||
$file->{ftype} = 'v'; |
||||
} elsif ($file->{fmime} =~ m{^audio/}o) { |
||||
$file->{ftype} = 'a'; |
||||
} elsif ($file->{fmime} =~ m{^text/}o) { |
||||
$file->{ftype} = 't'; |
||||
} |
||||
|
||||
$upload->move_to($self->_file_path($time, $file->{fext}, 'fullpath')); |
||||
$self->app->db->insert('filebin', $file); |
||||
|
||||
$self->redirect_to("/filebin/$time"); |
||||
} or do { |
||||
chomp $@; |
||||
$self->app->log->error($@); |
||||
$@ =~ s/\s+ at \s+ .+ \s+ line \s+ \d+//oxi; |
||||
$self->flash({error => $@}); |
||||
$self->redirect_to('/filebin'); |
||||
}; |
||||
|
||||
$self->rendered; |
||||
} |
||||
|
||||
sub latest { |
||||
my ($self) = @_; |
||||
|
||||
eval { |
||||
my $now = time(); |
||||
my @files = $self->app->db->select('filebin', '*', {expire => {'>=' => $now}}, {-desc => 'created'})->hashes; |
||||
splice(@files, 15); # first 15 elements |
||||
foreach my $file (@files) { |
||||
$file->{thumb} = $self->_file_path($file->{created}, $file->{fext}); |
||||
$file->{url} = sprintf '/filebin/%d', $file->{created}; |
||||
} |
||||
$self->stash(files => \@files); |
||||
$self->render; |
||||
} or do { |
||||
chomp $@; |
||||
$self->flash({error => $@}); |
||||
$self->app->log->error($@); |
||||
$self->redirect_to('/filebin'); |
||||
}; |
||||
} |
||||
|
||||
sub prune { |
||||
my ($self) = @_; |
||||
|
||||
$self->access_allowed($self->app->config->{filebin}->{access}) |
||||
or return; |
||||
|
||||
eval { |
||||
my $now = time(); |
||||
my $conf = $self->app->config->{filebin}; |
||||
my @files = $self->app->db->select('filebin', '*', {expire => {'<=' => $now}})->hashes; |
||||
foreach my $file (@files) { |
||||
unlink $self->_file_path($file->{created}, $file->{fext}, 1); |
||||
if ($file->{ftype} eq 'i') { |
||||
unlink $self->_file_path("$file->{created}_tn", $conf->{thumbs_ext}, 1); |
||||
} |
||||
$self->app->db->delete('filebin', {id => $file->{id}}); |
||||
} 1; |
||||
} or do { |
||||
chomp $@; |
||||
$self->flash({error => $@}); |
||||
$self->app->log->error($@); |
||||
}; |
||||
|
||||
$self->redirect_to('/filebin'); |
||||
$self->rendered; |
||||
} |
||||
|
||||
1; |
Loading…
Reference in new issue