Browse Source

* LDV::Zerobin : separate content from metadata

master
Alex 'AdUser' Z 9 years ago
parent
commit
d73b713c08
  1. 1
      conf/ldv.conf.sample
  2. 117
      lib/LDV/Zerobin.pm

1
conf/ldv.conf.sample

@ -39,7 +39,6 @@
}, },
zerobin => { zerobin => {
root => 'data/zerobin',
syntax => ['bash', 'c', 'css', 'html', 'perl', 'php', 'python', 'other'], syntax => ['bash', 'c', 'css', 'html', 'perl', 'php', 'python', 'other'],
maxsize => 10 * 1024 * 1024, maxsize => 10 * 1024 * 1024,
}, },

117
lib/LDV/Zerobin.pm

@ -10,11 +10,63 @@ use Mojo::Base 'Mojolicious::Controller';
use Mojo::Asset::File; use Mojo::Asset::File;
use Mojo::Util qw(b64_encode b64_decode decode encode); use Mojo::Util qw(b64_encode b64_decode decode encode);
sub _paste_path { sub _metadata_path {
my ($self, $time) = @_; my ($self, $time) = @_;
my $root ||= $self->app->config->{zerobin}->{root};
return $self->app->home->rel_file("$root/$time.json"); return $self->app->home->rel_file("data/zerobin/$time.json");
}
sub _metadata_save {
my ($self, $time, $data) = @_;
my $path = $self->_metadata_path($time);
my $asset = Mojo::Asset::File->new;
$asset->add_chunk(encode_json($data));
$asset->move_to($path);
return 1;
}
sub _metadata_load {
my ($self, $time) = @_;
my $path = $self->_metadata_path($time);
die("paste metadata not found\n") unless (-f $path);
my $asset = Mojo::Asset::File->new(path => $path);
$asset->cleanup(0);
return decode_json($asset->slurp);
}
sub _content_path {
my ($self, $time) = @_;
return $self->app->home->rel_file("public/zerobin/$time.txt");
}
sub _content_save {
my ($self, $time, $content) = @_;
unless (ref $content) {
my $asset = Mojo::Asset::File->new;
$asset->add_chunk($content);
$content = $asset; # wrap plaintext to Mojo::Asset
}
my $path = $self->_content_path($time);
$content->move_to($path);
return 1;
}
sub _content_load {
my ($self, $time) = @_;
my $path = $self->_content_path($time);
die("paste content not found\n") unless (-f $path);
my $asset = Mojo::Asset::File->new(path => $path);
$asset->cleanup(0);
return $asset->slurp;
} }
sub create { sub create {
@ -26,7 +78,7 @@ sub create {
if (ref($langs) eq 'ARRAY'); if (ref($langs) eq 'ARRAY');
$self->stash({syntax => \@syntax}); $self->stash({syntax => \@syntax});
$self->render(); $self->render;
} }
sub view { sub view {
@ -34,17 +86,13 @@ sub view {
my $time = $self->stash('time'); my $time = $self->stash('time');
eval { eval {
die("paste not found\n") unless ($time); die("paste not found\n") unless $time;
my $path = $self->_paste_path($time); my $paste = $self->_metadata_load($time);
die("paste not found\n") unless (-f $path); $paste->{data} = $self->_content_load($time);
my $asset = Mojo::Asset::File->new(path => $path); $paste->{time} = $time;
my $json = decode_json($asset->slurp()); utf8::decode($paste->{data});
$json->{data} = decode('UTF-8', b64_decode($json->{data})); $self->stash({paste => $paste});
if (time() > $json->{expire}) { 1;
unlink($path);
die("paste expired\n");
}
$self->stash({paste => $json});
} or do { } or do {
chomp $@; chomp $@;
$self->app->log->error($@); $self->app->log->error($@);
@ -54,7 +102,7 @@ sub view {
return; return;
}; };
$self->render(); $self->render;
} }
sub save { sub save {
@ -62,7 +110,7 @@ sub save {
eval { eval {
my $source = $self->req->param('source') || '-'; my $source = $self->req->param('source') || '-';
my $expire = $self->req->param('expire') || 30; # 1 month my $expire = $self->req->param('expire') || 30; # 30 days or 1 month
my $syntax = $self->req->param('syntax') || ''; my $syntax = $self->req->param('syntax') || '';
my $paste; my $paste;
if ($source eq 'form') { if ($source eq 'form') {
@ -83,7 +131,7 @@ sub save {
my $mime = File::MimeInfo::Magic::mimetype($tmpfile); my $mime = File::MimeInfo::Magic::mimetype($tmpfile);
die("uploaded file not looks like text\n") die("uploaded file not looks like text\n")
unless $mime =~ m{^text/}; unless $mime =~ m{^text/};
$paste = $upload->asset->slurp; $paste = $upload->asset;
unlink $tmpfile; unlink $tmpfile;
} else { } else {
die("unknown 'source'\n"); die("unknown 'source'\n");
@ -92,14 +140,11 @@ sub save {
$syntax = 'auto' unless ($syntax =~ m|^[a-z0-9]+$|oi); $syntax = 'auto' unless ($syntax =~ m|^[a-z0-9]+$|oi);
my $time = time(); my $time = time();
my $json = { $self->_metadata_save($time, {
expire => $time + ($expire * 86400), expire => $time + ($expire * 86400),
syntax => $syntax, syntax => $syntax,
data => b64_encode(encode('UTF-8', $paste)), });
}; $self->_content_save($time, $paste);
my $asset = Mojo::Asset::File->new;
$asset->add_chunk(encode_json($json));
$asset->move_to($self->_paste_path($time));
$self->redirect_to("/zerobin2/$time"); 1; $self->redirect_to("/zerobin2/$time"); 1;
} or do { } or do {
chomp $@; chomp $@;
@ -109,38 +154,34 @@ sub save {
$self->redirect_to("/zerobin2"); $self->redirect_to("/zerobin2");
}; };
$self->rendered(); $self->rendered;
return 1;
} }
sub prune { sub prune {
my ($self) = @_; my ($self) = @_;
eval { eval {
my $time = time(); my $currtime = time();
my $storage = $self->app->config->{zerobin}->{root}; my $files = $self->app->home->list_files("data/zerobin");
my $files = $self->app->home->list_files($storage); foreach my $file (@{ $files }) {
foreach my $file (@$files) {
next unless $file =~ m/^(\d+)\.json$/oi; next unless $file =~ m/^(\d+)\.json$/oi;
my $time = $1; my $time = $1;
my $path = $self->app->home->rel_file("$storage/$file"); my $data = $self->_metadata_load($time);
my $asset = Mojo::Asset::File->new(path => $path); next if $data->{expire} > $time; # not yet
my $data = decode_json($asset->slurp);
next if ($data->{expire} > $time); # not yet
my $date = strftime("%Y-%m-%d %H:%M", localtime($data->{expire})); my $date = strftime("%Y-%m-%d %H:%M", localtime($data->{expire}));
$self->app->log->info("Removing expired paste: $file ($date)"); $self->app->log->info("Removing expired paste: $file ($date)");
unlink $path; unlink $self->_metadata_path($time);
unlink $self->_content_path($time);
} 1; } 1;
} or do { } or do {
chomp $@; chomp $@;
$self->app->log->error($@); $self->app->log->error($@);
$@ = "internal error" if ($@ =~ m|at \S+ line \d+|oi); $@ = "internal error" if ($@ =~ m|at \S+ line \d+|oi);
$self->stash({'result' => $@}); $self->stash({result => $@});
}; };
$self->redirect_to("/zerobin2"); $self->redirect_to("/zerobin2");
$self->rendered(); $self->rendered;
return 1;
} }
1; 1;

Loading…
Cancel
Save