Browse Source

+ LDV::Filebin

master
Alex 'AdUser' Z 6 years ago
parent
commit
85e5e58680
  1. 180
      lib/LDV/Filebin.pm

180
lib/LDV/Filebin.pm

@ -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…
Cancel
Save