mirror of
https://framagit.org/fiat-tux/hat-softwares/lutim.git
synced 2026-05-06 21:42:42 +02:00
Issue #42; abstraction layer finished
This commit is dedicated to Schoumi, who is supporting me on Tipeee. Many thanks :-)
This commit is contained in:
31
lib/Lutim.pm
31
lib/Lutim.pm
@@ -144,24 +144,23 @@ sub startup {
|
||||
my $c = shift;
|
||||
|
||||
# Create some short patterns for provisioning
|
||||
if (LutimModel::Lutim->count('WHERE path IS NULL') < $c->config->{provisioning}) {
|
||||
my $img = Lutim::DB::Image->new(app => $c->app);
|
||||
if ($img->count_empty < $c->config->{provisioning}) {
|
||||
for (my $i = 0; $i < $c->config->{provis_step}; $i++) {
|
||||
if (LutimModel->begin) {
|
||||
my $short;
|
||||
do {
|
||||
$short= $c->shortener($c->config->{length});
|
||||
} while (LutimModel::Lutim->count('WHERE short = ?', $short) || $short eq 'about' || $short eq 'stats' || $short eq 'd' || $short eq 'm' || $short eq 'gallery' || $short eq 'zip' || $short eq 'infos');
|
||||
my $short;
|
||||
do {
|
||||
$short = $c->shortener($c->config->{length});
|
||||
} while ($img->count_short($short) || $short eq 'about' || $short eq 'stats' || $short eq 'd' || $short eq 'm' || $short eq 'gallery' || $short eq 'zip' || $short eq 'infos');
|
||||
|
||||
LutimModel::Lutim->create(
|
||||
short => $short,
|
||||
counter => 0,
|
||||
enabled => 1,
|
||||
delete_at_first_view => 0,
|
||||
delete_at_day => 0,
|
||||
mod_token => $c->shortener($c->config->{token_length})
|
||||
);
|
||||
LutimModel->commit;
|
||||
}
|
||||
$img->short($short)
|
||||
->counter(0)
|
||||
->enabled(1)
|
||||
->delete_at_first_view(0)
|
||||
->delete_at_day(0)
|
||||
->mod_token($c->shortener($c->config->{token_length}))
|
||||
->write;
|
||||
|
||||
$img = Lutim::DB::Image->new(app => $c->app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package Lutim::Command::cron::stats;
|
||||
use Mojo::Base 'Mojolicious::Command';
|
||||
use LutimModel;
|
||||
use Lutim::DB::Image;
|
||||
use Mojo::DOM;
|
||||
use Mojo::Util qw(slurp spurt encode);
|
||||
use Mojo::Util qw(encode);
|
||||
use Mojo::File;
|
||||
use DateTime;
|
||||
use FindBin qw($Bin);
|
||||
use File::Spec qw(catfile);
|
||||
@@ -17,7 +18,8 @@ sub run {
|
||||
file => File::Spec->catfile($Bin, '..' ,'lutim.conf'),
|
||||
theme => 'default',
|
||||
default => {
|
||||
stats_day_num => 365
|
||||
stats_day_num => 365,
|
||||
dbtype => 'sqlite'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -26,7 +28,7 @@ sub run {
|
||||
$config->{theme} = 'default';
|
||||
$template = 'themes/'.$config->{theme}.'/templates/data.html.ep.template';
|
||||
}
|
||||
my $text = slurp($template);
|
||||
my $text = Mojo::File->new($template)->slurp;
|
||||
my $dom = Mojo::DOM->new($text);
|
||||
my $thead_tr = $dom->at('table thead tr');
|
||||
my $tbody_tr = $dom->at('table tbody tr');
|
||||
@@ -35,18 +37,22 @@ sub run {
|
||||
my $separation = time() - $config->{stats_day_num} * 86400;
|
||||
|
||||
my %data;
|
||||
for my $img (LutimModel::Lutim->select('WHERE path IS NOT NULL AND created_at >= ?', $separation)) {
|
||||
my $time = DateTime->from_epoch(epoch => $img->created_at);
|
||||
my ($year, $month, $day) = ($time->year(), $time->month(), $time->day());
|
||||
my $img = Lutim::DB::Image->new(app => $c->app);
|
||||
$img->select_created_after($separation)->each(
|
||||
sub {
|
||||
my ($e, $num) = @_;
|
||||
my $time = DateTime->from_epoch(epoch => $e->created_at);
|
||||
my ($year, $month, $day) = ($time->year(), $time->month(), $time->day());
|
||||
|
||||
if (defined($data{$year}->{$month}->{$day})) {
|
||||
$data{$year}->{$month}->{$day} += 1;
|
||||
} else {
|
||||
$data{$year}->{$month}->{$day} = 1;
|
||||
if (defined($data{$year}->{$month}->{$day})) {
|
||||
$data{$year}->{$month}->{$day} += 1;
|
||||
} else {
|
||||
$data{$year}->{$month}->{$day} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
my $total = LutimModel::Lutim->count('WHERE path IS NOT NULL AND created_at < ?', $separation);
|
||||
my $total = $img->count_created_before($separation);
|
||||
for my $year (sort {$a <=> $b} keys %data) {
|
||||
for my $month (sort {$a <=> $b} keys %{$data{$year}}) {
|
||||
for my $day (sort {$a <=> $b} keys %{$data{$year}->{$month}}) {
|
||||
@@ -64,27 +70,29 @@ sub run {
|
||||
$config->{theme} = 'default';
|
||||
$template = 'themes/'.$config->{theme}.'/templates/raw.html.ep.template';
|
||||
}
|
||||
my $text2 = slurp($template2);
|
||||
my $text2 = Mojo::File->new($template2)->slurp;
|
||||
my $dom2 = Mojo::DOM->new($text2);
|
||||
my $raw = $dom2->at('table tbody');
|
||||
my $raw_foot = $dom2->at('table tfoot');
|
||||
my $unlimited_enabled = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 0 AND enabled = 1');
|
||||
my $unlimited_disabled = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 0 AND enabled = 0');
|
||||
my $day_enabled = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 1 AND enabled = 1');
|
||||
my $day_disabled = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 1 AND enabled = 0');
|
||||
my $week_enabled = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 7 AND enabled = 1');
|
||||
my $week_disabled = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 7 AND enabled = 0');
|
||||
my $month_enabled = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 30 AND enabled = 1');
|
||||
my $month_disabled = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 30 AND enabled = 0');
|
||||
my $year_enabled = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 365 AND enabled = 1');
|
||||
my $year_disabled = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 365 AND enabled = 0');
|
||||
my $year_disabled_in_month = LutimModel::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = 365 AND enabled = 0 AND created_at < ?', time - 30 * 86400);
|
||||
my $unlimited_enabled = $img->count_delete_at_day_endis(0, 1);
|
||||
my $unlimited_disabled = $img->count_delete_at_day_endis(0, 0);
|
||||
my $day_enabled = $img->count_delete_at_day_endis(1, 1);
|
||||
my $day_disabled = $img->count_delete_at_day_endis(1, 0);
|
||||
my $week_enabled = $img->count_delete_at_day_endis(7, 1);
|
||||
my $week_disabled = $img->count_delete_at_day_endis(7, 0);
|
||||
my $month_enabled = $img->count_delete_at_day_endis(30, 1);
|
||||
my $month_disabled = $img->count_delete_at_day_endis(30, 0);
|
||||
my $year_enabled = $img->count_delete_at_day_endis(365, 1);
|
||||
my $year_disabled = $img->count_delete_at_day_endis(365, 0);
|
||||
my $year_disabled_in_month = $img->count_delete_at_day_endis(365, 1, time - 335 * 86400);
|
||||
|
||||
my $year_disabled_in_month_pct = ($year_enabled != 0) ? " (".sprintf('%.2f', $year_disabled_in_month/$year_enabled)."%)" : '';
|
||||
|
||||
$raw->append_content("\n<tr><td><%= \$raw[4] %></td><td>".$unlimited_enabled."</td><td>".$unlimited_disabled."</td><td>ø</td></tr>\n");
|
||||
$raw->append_content("<tr><td><%= \$raw[5] %></td><td>".$day_enabled."</td><td>".$day_disabled."</td><td>".$day_enabled." (100%)</td></tr>\n");
|
||||
$raw->append_content("<tr><td><%= \$raw[6] %></td><td>".$week_enabled."</td><td>".$week_disabled."</td><td>".$week_enabled." (100%)</td></tr>\n");
|
||||
$raw->append_content("<tr><td><%= \$raw[7] %></td><td>".$month_enabled."</td><td>".$month_disabled."</td><td>".$month_enabled." (100%)</td></tr>\n");
|
||||
$raw->append_content("<tr><td><%= \$raw[8] %></td><td>".$year_enabled."</td><td>".$year_disabled."</td><td>".$year_disabled_in_month." (".sprintf('%.2f', $year_disabled_in_month/$year_enabled)."%)</td></tr>\n");
|
||||
$raw->append_content("<tr><td><%= \$raw[8] %></td><td>".$year_enabled."</td><td>".$year_disabled."</td><td>".$year_disabled_in_month.$year_disabled_in_month_pct."</td></tr>\n");
|
||||
|
||||
$raw_foot->append_content("\n<tr><td><%= \$raw[9] %></td><td>".($unlimited_enabled + $day_enabled + $week_enabled + $month_enabled + $year_enabled)."</td><td>".($unlimited_disabled + $day_disabled + $week_disabled + $month_disabled + $year_disabled)."</td><td>".($day_enabled + $week_enabled + $month_enabled + $year_disabled_in_month)."</td></tr>\n");
|
||||
|
||||
@@ -140,8 +148,8 @@ Morris.Donut({
|
||||
$dom2
|
||||
EOF
|
||||
|
||||
spurt $dom, 'themes/'.$config->{theme}.'/templates/data.html.ep';
|
||||
spurt encode('UTF-8', $dom2), 'themes/'.$config->{theme}.'/templates/raw.html.ep';
|
||||
Mojo::File->new('themes/'.$config->{theme}.'/templates/data.html.ep')->spurt($dom);
|
||||
Mojo::File->new('themes/'.$config->{theme}.'/templates/raw.html.ep')->spurt(encode('UTF-8', $dom2));
|
||||
}
|
||||
|
||||
=encoding utf8
|
||||
|
||||
@@ -4,6 +4,7 @@ use Mojo::Base 'Mojolicious::Controller';
|
||||
use Mojo::Util qw(url_unescape b64_encode);
|
||||
use Mojo::Asset::Memory;
|
||||
use Mojo::JSON qw(true false);
|
||||
use Lutim::DB::Image;
|
||||
use DateTime;
|
||||
use Digest::file qw(digest_file_hex);
|
||||
use Text::Unidecode;
|
||||
@@ -45,9 +46,12 @@ sub about {
|
||||
}
|
||||
|
||||
sub stats {
|
||||
shift->render(
|
||||
my $c = shift;
|
||||
|
||||
my $img = Lutim::DB::Image->new(app => $c);
|
||||
$c->render(
|
||||
template => 'stats',
|
||||
total => LutimModel::Lutim->count('WHERE path IS NOT NULL')
|
||||
total => $img->count_not_empty
|
||||
);
|
||||
}
|
||||
|
||||
@@ -85,13 +89,13 @@ sub get_counter {
|
||||
my $short = $c->param('short');
|
||||
my $token = $c->param('token');
|
||||
|
||||
my @images = LutimModel::Lutim->select('WHERE short = ? AND path IS NOT NULL AND mod_token = ?', ($short, $token));
|
||||
if (scalar(@images)) {
|
||||
my $img = Lutim::DB::Image->new(app => $c->app, short => $short);
|
||||
if (defined($img->mod_token) && $img->mod_token eq $token) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => true,
|
||||
counter => $images[0]->counter,
|
||||
enabled => ($images[0]->enabled) ? true : false
|
||||
counter => $img->counter,
|
||||
enabled => ($img->enabled) ? true : false
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -109,11 +113,10 @@ sub modify {
|
||||
my $token = $c->param('token');
|
||||
my $url = $c->param('url');
|
||||
|
||||
my @images = LutimModel::Lutim->select('WHERE short = ? AND path IS NOT NULL', $short);
|
||||
if (scalar(@images)) {
|
||||
my $image = $images[0];
|
||||
my $image = Lutim::DB::Image->new(app => $c->app, short => $short);
|
||||
if ($image->path) {
|
||||
my $msg;
|
||||
if ($image->mod_token() ne $token || $token eq '') {
|
||||
if ($image->mod_token ne $token || $token eq '') {
|
||||
$msg = $c->l('The delete token is invalid.');
|
||||
} else {
|
||||
$c->app->log->info('[MODIFICATION] someone modify '.$image->filename.' with token method (path: '.$image->path.')');
|
||||
@@ -178,11 +181,10 @@ sub delete {
|
||||
my $short = $c->param('short');
|
||||
my $token = $c->param('token');
|
||||
|
||||
my @images = LutimModel::Lutim->select('WHERE short = ? AND path IS NOT NULL', $short);
|
||||
if (scalar(@images)) {
|
||||
my $image = $images[0];
|
||||
my $image = Lutim::DB::Image->new(app => $c->app, short => $short);
|
||||
if ($image->path) {
|
||||
my $msg;
|
||||
if ($image->mod_token() ne $token || $token eq '') {
|
||||
if ($image->mod_token ne $token || $token eq '') {
|
||||
$msg = $c->l('The delete token is invalid.');
|
||||
} elsif ($image->enabled() == 0) {
|
||||
$msg = $c->l('The image %1 has already been deleted.', $image->filename);
|
||||
@@ -349,102 +351,96 @@ sub add {
|
||||
return $c->redirect_to('/');
|
||||
}
|
||||
}
|
||||
if(LutimModel->begin) {
|
||||
my @records = LutimModel::Lutim->select('WHERE path IS NULL LIMIT 1');
|
||||
if (scalar(@records)) {
|
||||
# Save file and create record
|
||||
my $filename = unidecode($upload->filename);
|
||||
my $ext = ($filename =~ m/([^.]+)$/)[0];
|
||||
my $path = 'files/'.$records[0]->short.'.'.$ext;
|
||||
my $record = Lutim::DB::Image->new(app => $c->app)->select_empty;
|
||||
if ($record->short) {
|
||||
# Save file and create record
|
||||
my $filename = unidecode($upload->filename);
|
||||
my $ext = ($filename =~ m/([^.]+)$/)[0];
|
||||
my $path = 'files/'.$record->short.'.'.$ext;
|
||||
|
||||
my ($width, $height);
|
||||
if ($im_loaded && $mediatype ne 'image/svg+xml' && $mediatype !~ m#image/(x-)?xcf# && $mediatype ne 'image/webp') { # ImageMagick don't work in Debian with svg (for now?)
|
||||
my $im = Image::Magick->new;
|
||||
$im->BlobToImage($upload->slurp);
|
||||
my ($width, $height);
|
||||
if ($im_loaded && $mediatype ne 'image/svg+xml' && $mediatype !~ m#image/(x-)?xcf# && $mediatype ne 'image/webp') { # ImageMagick don't work in Debian with svg (for now?)
|
||||
my $im = Image::Magick->new;
|
||||
$im->BlobToImage($upload->slurp);
|
||||
|
||||
# Automatic rotation from EXIF tag
|
||||
$im->AutoOrient();
|
||||
# Automatic rotation from EXIF tag
|
||||
$im->AutoOrient();
|
||||
|
||||
# Update the uploaded file with it's auto-rotated clone
|
||||
my $asset = Mojo::Asset::Memory->new->add_chunk($im->ImageToBlob());
|
||||
$upload->asset($asset);
|
||||
# Update the uploaded file with it's auto-rotated clone
|
||||
my $asset = Mojo::Asset::Memory->new->add_chunk($im->ImageToBlob());
|
||||
$upload->asset($asset);
|
||||
|
||||
# Create the thumbnail
|
||||
$width = $im->Get('width');
|
||||
$height = $im->Get('height');
|
||||
$im->Resize(geometry=>'x85');
|
||||
|
||||
$thumb = 'data:'.$mediatype.';base64,';
|
||||
if ($mediatype eq 'image/gif') {
|
||||
$thumb .= b64_encode $im->[0]->ImageToBlob();
|
||||
} else {
|
||||
$thumb .= b64_encode $im->ImageToBlob();
|
||||
}
|
||||
# Create the thumbnail
|
||||
$width = $im->Get('width');
|
||||
$height = $im->Get('height');
|
||||
$im->Resize(geometry=>'x85');
|
||||
|
||||
$thumb = 'data:'.$mediatype.';base64,';
|
||||
if ($mediatype eq 'image/gif') {
|
||||
$thumb .= b64_encode $im->[0]->ImageToBlob();
|
||||
} else {
|
||||
$thumb .= b64_encode $im->ImageToBlob();
|
||||
}
|
||||
|
||||
unless ((defined($keep_exif) && $keep_exif) || $mediatype eq 'image/svg+xml' || $mediatype !~ m#image/(x-)?xcf# || $mediatype ne 'image/webp') {
|
||||
# Remove the EXIF tags
|
||||
my $data = new IO::Scalar \$upload->slurp();
|
||||
my $et = new Image::ExifTool;
|
||||
|
||||
# Use $data in Image::ExifTool object
|
||||
$et->ExtractInfo($data);
|
||||
# Remove all metadata
|
||||
$et->SetNewValue('*', undef);
|
||||
|
||||
# Create a temporary IO::Scalar to write into
|
||||
my $temp;
|
||||
my $a = new IO::Scalar \$temp;
|
||||
$et->WriteInfo($data, $a);
|
||||
|
||||
# Update the uploaded file with it's no-tags clone
|
||||
$data = Mojo::Asset::Memory->new->add_chunk($temp);
|
||||
$upload->asset($data);
|
||||
}
|
||||
|
||||
my $key;
|
||||
if ($c->param('crypt') || $c->config->{always_encrypt}) {
|
||||
($upload, $key) = $c->crypt($upload, $filename);
|
||||
}
|
||||
$upload->move_to($path);
|
||||
|
||||
$records[0]->update(
|
||||
path => $path,
|
||||
filename => $filename,
|
||||
mediatype => $mediatype,
|
||||
footprint => digest_file_hex($path, 'SHA-512'),
|
||||
enabled => 1,
|
||||
delete_at_day => ($c->param('delete-day') && ($c->param('delete-day') <= $c->max_delay || $c->max_delay == 0)) ? $c->param('delete-day') : $c->max_delay,
|
||||
delete_at_first_view => ($c->param('first-view')) ? 1 : 0,
|
||||
created_at => time(),
|
||||
created_by => $ip,
|
||||
width => $width,
|
||||
height => $height
|
||||
);
|
||||
|
||||
# Log image creation
|
||||
$c->app->log->info('[CREATION] '.$ip.' pushed '.$filename.' (path: '.$path.')');
|
||||
|
||||
# Give url to user
|
||||
$short = $records[0]->short;
|
||||
$real_short = $short;
|
||||
if (!defined($records[0]->mod_token)) {
|
||||
$records[0]->update(
|
||||
mod_token => $c->shortener($c->config->{token_length})
|
||||
);
|
||||
}
|
||||
$token = $records[0]->mod_token;
|
||||
$short .= '/'.$key if (defined($key));
|
||||
|
||||
$limit = $records[0]->delete_at_day;
|
||||
$created = $records[0]->created_at;
|
||||
} else {
|
||||
# Houston, we have a problem
|
||||
$msg = $c->l('There is no more available URL. Retry or contact the administrator. %1', $c->config->{contact});
|
||||
}
|
||||
|
||||
unless ((defined($keep_exif) && $keep_exif) || $mediatype eq 'image/svg+xml' || $mediatype !~ m#image/(x-)?xcf# || $mediatype ne 'image/webp') {
|
||||
# Remove the EXIF tags
|
||||
my $data = new IO::Scalar \$upload->slurp();
|
||||
my $et = new Image::ExifTool;
|
||||
|
||||
# Use $data in Image::ExifTool object
|
||||
$et->ExtractInfo($data);
|
||||
# Remove all metadata
|
||||
$et->SetNewValue('*', undef);
|
||||
|
||||
# Create a temporary IO::Scalar to write into
|
||||
my $temp;
|
||||
my $a = new IO::Scalar \$temp;
|
||||
$et->WriteInfo($data, $a);
|
||||
|
||||
# Update the uploaded file with it's no-tags clone
|
||||
$data = Mojo::Asset::Memory->new->add_chunk($temp);
|
||||
$upload->asset($data);
|
||||
}
|
||||
|
||||
my $key;
|
||||
if ($c->param('crypt') || $c->config->{always_encrypt}) {
|
||||
($upload, $key) = $c->crypt($upload, $filename);
|
||||
}
|
||||
$upload->move_to($path);
|
||||
|
||||
$record->path($path)
|
||||
->filename($filename)
|
||||
->mediatype($mediatype)
|
||||
->footprint(digest_file_hex($path, 'SHA-512'))
|
||||
->enabled(1)
|
||||
->delete_at_day(($c->param('delete-day') && ($c->param('delete-day') <= $c->max_delay || $c->max_delay == 0)) ? $c->param('delete-day') : $c->max_delay)
|
||||
->delete_at_first_view(($c->param('first-view'))? 1 : 0)
|
||||
->created_at(time())
|
||||
->created_by($ip)
|
||||
->width($width)
|
||||
->height($height)
|
||||
->write;
|
||||
|
||||
# Log image creation
|
||||
$c->app->log->info('[CREATION] '.$ip.' pushed '.$filename.' (path: '.$path.')');
|
||||
|
||||
# Give url to user
|
||||
$short = $record->short;
|
||||
$real_short = $short;
|
||||
if (!defined($record->mod_token)) {
|
||||
$record->mod_token($c->shortener($c->config->{token_length}))->write;
|
||||
}
|
||||
$token = $record->mod_token;
|
||||
$short .= '/'.$key if (defined($key));
|
||||
|
||||
$limit = $record->delete_at_day;
|
||||
$created = $record->created_at;
|
||||
} else {
|
||||
# Houston, we have a problem
|
||||
$msg = $c->l('There is no more available URL. Retry or contact the administrator. %1', $c->config->{contact});
|
||||
}
|
||||
LutimModel->commit;
|
||||
} else {
|
||||
$msg = $c->l('The file %1 is not an image.', $upload->filename);
|
||||
}
|
||||
@@ -519,15 +515,14 @@ sub short {
|
||||
my $thumb = $c->param('thumb');
|
||||
my $dl = (defined($c->param('dl'))) ? 'attachment' : 'inline';
|
||||
|
||||
my @images = LutimModel::Lutim->select('WHERE short = ? AND ENABLED = 1 AND path IS NOT NULL', $short);
|
||||
|
||||
if (scalar(@images)) {
|
||||
if($images[0]->delete_at_day && $images[0]->created_at + $images[0]->delete_at_day * 86400 <= time()) {
|
||||
my $image = Lutim::DB::Image->new(app => $c->app, short => $short);
|
||||
if ($image->enabled && $image->path) {
|
||||
if($image->delete_at_day && $image->created_at + $image->delete_at_day * 86400 <= time()) {
|
||||
# Log deletion
|
||||
$c->app->log->info('[DELETION] someone tried to view '.$images[0]->filename.' but it has been removed by expiration (path: '.$images[0]->path.')');
|
||||
$c->app->log->info('[DELETION] someone tried to view '.$image->filename.' but it has been removed by expiration (path: '.$image->path.')');
|
||||
|
||||
# Delete image
|
||||
$c->delete_image($images[0]);
|
||||
$c->delete_image($image);
|
||||
|
||||
# Warn user
|
||||
$c->flash(
|
||||
@@ -539,54 +534,53 @@ sub short {
|
||||
my $test;
|
||||
if (defined($touit)) {
|
||||
$test = 1;
|
||||
my $short = $images[0]->short;
|
||||
my $short = $image->short;
|
||||
$short .= '/'.$key if (defined($key));
|
||||
my ($width, $height) = (340,340);
|
||||
if ($images[0]->mediatype eq 'image/gif') {
|
||||
if (defined($images[0]->width) && defined($images[0]->height)) {
|
||||
($width, $height) = ($images[0]->width, $images[0]->height);
|
||||
if ($image->mediatype eq 'image/gif') {
|
||||
if (defined($image->width) && defined($image->height)) {
|
||||
($width, $height) = ($image->width, $image->height);
|
||||
} elsif ($im_loaded) {
|
||||
my $upload = $c->decrypt($key, $images[0]->path);
|
||||
my $upload = $c->decrypt($key, $image->path);
|
||||
my $im = Image::Magick->new;
|
||||
$im->BlobToImage($upload->slurp);
|
||||
$width = $im->Get('width');
|
||||
$height = $im->Get('height');
|
||||
|
||||
$images[0]->update(
|
||||
width => $width,
|
||||
height => $height
|
||||
);
|
||||
$image->width($width)
|
||||
->height($height)
|
||||
->write;
|
||||
}
|
||||
}
|
||||
return $c->render(
|
||||
template => 'twitter',
|
||||
layout => undef,
|
||||
short => $short,
|
||||
filename => $images[0]->filename,
|
||||
mimetype => ($c->req->url->to_abs()->scheme eq 'https') ? $images[0]->mediatype : '',
|
||||
filename => $image->filename,
|
||||
mimetype => ($c->req->url->to_abs()->scheme eq 'https') ? $image->mediatype : '',
|
||||
width => $width,
|
||||
height => $height
|
||||
);
|
||||
} else {
|
||||
# Delete image if needed
|
||||
if ($images[0]->delete_at_first_view && $images[0]->counter >= 1) {
|
||||
if ($image->delete_at_first_view && $image->counter >= 1) {
|
||||
# Log deletion
|
||||
$c->app->log->info('[DELETION] someone made '.$images[0]->filename.' removed (path: '.$images[0]->path.')');
|
||||
$c->app->log->info('[DELETION] someone made '.$image->filename.' removed (path: '.$image->path.')');
|
||||
|
||||
# Delete image
|
||||
$c->delete_image($images[0]);
|
||||
$c->delete_image($image);
|
||||
|
||||
$c->flash(
|
||||
msg => $c->l('Unable to find the image: it has been deleted.')
|
||||
);
|
||||
return $c->redirect_to('/');
|
||||
} else {
|
||||
my $expires = ($images[0]->delete_at_day) ? $images[0]->delete_at_day : 360;
|
||||
my $dt = DateTime->from_epoch( epoch => $expires * 86400 + $images[0]->created_at);
|
||||
my $expires = ($image->delete_at_day) ? $image->delete_at_day : 360;
|
||||
my $dt = DateTime->from_epoch( epoch => $expires * 86400 + $image->created_at);
|
||||
$dt->set_time_zone('GMT');
|
||||
$expires = $dt->strftime("%a, %d %b %Y %H:%M:%S GMT");
|
||||
|
||||
$test = $c->render_file($images[0]->filename, $images[0]->path, $images[0]->mediatype, $dl, $expires, $images[0]->delete_at_first_view, $key, $thumb);
|
||||
$test = $c->render_file($image->filename, $image->path, $image->mediatype, $dl, $expires, $image->delete_at_first_view, $key, $thumb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,40 +588,36 @@ sub short {
|
||||
# Update counter
|
||||
$c->on(finish => sub {
|
||||
# Log access
|
||||
$c->app->log->info('[VIEW] someone viewed '.$images[0]->filename.' (path: '.$images[0]->path.')');
|
||||
$c->app->log->info('[VIEW] someone viewed '.$image->filename.' (path: '.$image->path.')');
|
||||
|
||||
# Update record
|
||||
my $counter = $images[0]->counter + 1;
|
||||
$images[0]->update(counter => $counter);
|
||||
|
||||
$images[0]->update(last_access_at => time());
|
||||
my $counter = $image->counter + 1;
|
||||
$image->counter($counter)
|
||||
->last_access_at(time)
|
||||
->write;
|
||||
|
||||
# Delete image if needed
|
||||
if ($images[0]->delete_at_first_view) {
|
||||
if ($image->delete_at_first_view) {
|
||||
# Log deletion
|
||||
$c->app->log->info('[DELETION] someone made '.$images[0]->filename.' removed (path: '.$images[0]->path.')');
|
||||
$c->app->log->info('[DELETION] someone made '.$image->filename.' removed (path: '.$image->path.')');
|
||||
|
||||
# Delete image
|
||||
$c->delete_image($images[0]);
|
||||
$c->delete_image($image);
|
||||
}
|
||||
});
|
||||
}
|
||||
} elsif ($image->path && !$image->enabled) {
|
||||
# Log access try
|
||||
$c->app->log->info('[NOT FOUND] someone tried to view '.$short.' but it does\'nt exist anymore.');
|
||||
|
||||
# Warn user
|
||||
$c->flash(
|
||||
msg => $c->l('Unable to find the image: it has been deleted.')
|
||||
);
|
||||
return $c->redirect_to('/');
|
||||
} else {
|
||||
@images = LutimModel::Lutim->select('WHERE short = ? AND ENABLED = 0 AND path IS NOT NULL', $short);
|
||||
|
||||
if (scalar(@images)) {
|
||||
# Log access try
|
||||
$c->app->log->info('[NOT FOUND] someone tried to view '.$short.' but it does\'nt exist anymore.');
|
||||
|
||||
# Warn user
|
||||
$c->flash(
|
||||
msg => $c->l('Unable to find the image: it has been deleted.')
|
||||
);
|
||||
return $c->redirect_to('/');
|
||||
} else {
|
||||
# Image never existed
|
||||
$c->render_not_found;
|
||||
}
|
||||
# Image never existed
|
||||
$c->render_not_found;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,16 +639,16 @@ sub zip {
|
||||
} else {
|
||||
$short =~ s/\.[^.]*//;
|
||||
}
|
||||
my @images = LutimModel::Lutim->select('WHERE short = ? AND ENABLED = 1 AND path IS NOT NULL', $short);
|
||||
my $image = Lutim::DB::Image->new(app => $c->app, short => $short);
|
||||
|
||||
if (scalar(@images)) {
|
||||
my $filename = $images[0]->filename;
|
||||
if($images[0]->delete_at_day && $images[0]->created_at + $images[0]->delete_at_day * 86400 <= time()) {
|
||||
if ($image->enabled && $image->path) {
|
||||
my $filename = $image->filename;
|
||||
if($image->delete_at_day && $image->created_at + $image->delete_at_day * 86400 <= time()) {
|
||||
# Log deletion
|
||||
$c->app->log->info('[DELETION] someone tried to view '.$images[0]->filename.' but it has been removed by expiration (path: '.$images[0]->path.')');
|
||||
$c->app->log->info('[DELETION] someone tried to view '.$image->filename.' but it has been removed by expiration (path: '.$image->path.')');
|
||||
|
||||
# Delete image
|
||||
$c->delete_image($images[0]);
|
||||
$c->delete_image($image);
|
||||
|
||||
# Warn user
|
||||
$zip->addString($c->l('Unable to find the image: it has been deleted.'), 'images/'.$filename.'.txt');
|
||||
@@ -666,22 +656,22 @@ sub zip {
|
||||
}
|
||||
|
||||
# Delete image if needed
|
||||
if ($images[0]->delete_at_first_view && $images[0]->counter >= 1) {
|
||||
if ($image->delete_at_first_view && $image->counter >= 1) {
|
||||
# Log deletion
|
||||
$c->app->log->info('[DELETION] someone made '.$images[0]->filename.' removed (path: '.$images[0]->path.')');
|
||||
$c->app->log->info('[DELETION] someone made '.$image->filename.' removed (path: '.$image->path.')');
|
||||
|
||||
# Delete image
|
||||
$c->delete_image($images[0]);
|
||||
$c->delete_image($image);
|
||||
|
||||
$zip->addString($c->l('Unable to find the image: it has been deleted.'), 'images/'.$filename.'.txt');
|
||||
next;
|
||||
} else {
|
||||
my $expires = ($images[0]->delete_at_day) ? $images[0]->delete_at_day : 360;
|
||||
my $dt = DateTime->from_epoch( epoch => $expires * 86400 + $images[0]->created_at);
|
||||
my $expires = ($image->delete_at_day) ? $image->delete_at_day : 360;
|
||||
my $dt = DateTime->from_epoch( epoch => $expires * 86400 + $image->created_at);
|
||||
$dt->set_time_zone('GMT');
|
||||
$expires = $dt->strftime("%a, %d %b %Y %H:%M:%S GMT");
|
||||
|
||||
my $path = $images[0]->path;
|
||||
my $path = $image->path;
|
||||
unless ( -f $path && -r $path ) {
|
||||
$c->app->log->error("Cannot read file [$path]. error [$!]");
|
||||
$zip->addString($c->l('Unable to find the image: it has been deleted.'), 'images/'.$filename.'.txt');
|
||||
@@ -695,26 +685,22 @@ sub zip {
|
||||
}
|
||||
|
||||
# Log access
|
||||
$c->app->log->info('[VIEW] someone viewed '.$images[0]->filename.' (path: '.$images[0]->path.')');
|
||||
# Update counter
|
||||
$images[0]->update(counter => $images[0]->counter + 1);
|
||||
# Update record
|
||||
$images[0]->update(last_access_at => time());
|
||||
$c->app->log->info('[VIEW] someone viewed '.$image->filename.' (path: '.$image->path.')');
|
||||
# Update counter and record
|
||||
$image->counter($image->counter + 1)
|
||||
->last_access_at(time)
|
||||
->write;
|
||||
}
|
||||
} elsif ($image->path && !$image->enabled) {
|
||||
# Log access try
|
||||
$c->app->log->info('[NOT FOUND] someone tried to view '.$short.' but it does\'nt exist anymore.');
|
||||
|
||||
# Warn user
|
||||
$zip->addString($c->l('Unable to find the image: it has been deleted.'), 'images/'.$image->filename.'.txt');
|
||||
next;
|
||||
} else {
|
||||
@images = LutimModel::Lutim->select('WHERE short = ? AND ENABLED = 0 AND path IS NOT NULL', $short);
|
||||
|
||||
if (scalar(@images)) {
|
||||
# Log access try
|
||||
$c->app->log->info('[NOT FOUND] someone tried to view '.$short.' but it does\'nt exist anymore.');
|
||||
|
||||
# Warn user
|
||||
$zip->addString($c->l('Unable to find the image: it has been deleted.'), 'images/'.$images[0]->filename.'.txt');
|
||||
next;
|
||||
} else {
|
||||
$zip->addString($c->l('Image not found.'), 'images/'.$short.'.txt');
|
||||
next;
|
||||
}
|
||||
$zip->addString($c->l('Image not found.'), 'images/'.$short.'.txt');
|
||||
next;
|
||||
}
|
||||
}
|
||||
my ($fh, $zipfile) = Archive::Zip::tempFile();
|
||||
|
||||
@@ -98,9 +98,9 @@ sub new {
|
||||
if ($dbtype eq 'sqlite') {
|
||||
use Lutim::DB::Image::SQLite;
|
||||
$c = Lutim::DB::Image::SQLite->new(@_);
|
||||
} elsif ($dbtype eq 'postgresql') {
|
||||
use Lutim::DB::Image::Pg;
|
||||
$c = Lutim::DB::Image::Pg->new(@_);
|
||||
#} elsif ($dbtype eq 'postgresql') {
|
||||
# use Lutim::DB::Image::Pg;
|
||||
# $c = Lutim::DB::Image::Pg->new(@_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +129,120 @@ sub to_hash {
|
||||
};
|
||||
}
|
||||
|
||||
=head2 count_delete_at_day_endis
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>count_delete_at_day_endis($delete_at_day, $enabled[, $time])>
|
||||
|
||||
=item B<Arguments> : two mandatory parameters: one integer, the delete_at_day attribute, a boolean (0 or 1), the enabled attribute
|
||||
an optional parameter: an unix timestamp
|
||||
|
||||
=item B<Purpose> : count how many images there is with the given delete_at_day attribute, and enabled or disabled, depending on the given enabled attribute
|
||||
if the optional parameter is given, count only images according to the given mandatory parameters that were created before the timestamp
|
||||
|
||||
=item B<Returns> : integer
|
||||
|
||||
=back
|
||||
|
||||
=head2 count_created_before
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>count_created_before($time)>
|
||||
|
||||
=item B<Arguments> : an unix timestamp
|
||||
|
||||
=item B<Purpose> : count how many images have been created before the given timestamp
|
||||
|
||||
=item B<Returns> : integer
|
||||
|
||||
=back
|
||||
|
||||
=head2 select_created_after
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>select_created_after($time)>
|
||||
|
||||
=item B<Arguments> : an unix timestamp
|
||||
|
||||
=item B<Purpose> : select images created after the given timestamp
|
||||
|
||||
=item B<Returns> : a Mojo::Collection object containing the images created after the given timestamp
|
||||
|
||||
=back
|
||||
|
||||
=head2 select_empty
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>select_empty>
|
||||
|
||||
=item B<Arguments> : none
|
||||
|
||||
=item B<Purpose> : select a ready-to-use empty record
|
||||
|
||||
=item B<Returns> : a db accessor object
|
||||
|
||||
=back
|
||||
|
||||
=head2 write
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>write>
|
||||
|
||||
=item B<Arguments> : none
|
||||
|
||||
=item B<Purpose> : create or update a record in the database, with the values of the object's attributes
|
||||
|
||||
=item B<Returns> : the db accessor object
|
||||
|
||||
=back
|
||||
|
||||
=head2 count_short
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>count_short($short)>
|
||||
|
||||
=item B<Arguments> : a random string, unique image identifier in the database
|
||||
|
||||
=item B<Purpose> : checks that an identifier isn't already used
|
||||
|
||||
=item B<Returns> : integer, number of records having this identifier (should be 0 or 1)
|
||||
|
||||
=back
|
||||
|
||||
=head2 count_empty
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>count_empty>
|
||||
|
||||
=item B<Arguments> : none
|
||||
|
||||
=item B<Purpose> : counts the number of record which path is null
|
||||
|
||||
=item B<Returns> : integer
|
||||
|
||||
=back
|
||||
|
||||
=head2 count_not_empty
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>count_not_empty>
|
||||
|
||||
=item B<Arguments> : none
|
||||
|
||||
=item B<Purpose> : counts the number of record which path is not null
|
||||
|
||||
=item B<Returns> : integer
|
||||
|
||||
=back
|
||||
|
||||
=head2 clean_ips_until
|
||||
|
||||
=over 1
|
||||
|
||||
@@ -13,6 +13,120 @@ sub new {
|
||||
return $c;
|
||||
}
|
||||
|
||||
sub count_delete_at_day_endis {
|
||||
my $c = shift;
|
||||
my $day = shift;
|
||||
my $enabled = shift;
|
||||
my $created = shift;
|
||||
|
||||
if (defined $created) {
|
||||
return Lutim::DB::SQLite::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = ? AND enabled = ? AND created_at < ?', $day, $enabled, $created);
|
||||
} else {
|
||||
return Lutim::DB::SQLite::Lutim->count('WHERE path IS NOT NULL AND delete_at_day = ? AND enabled = ?', $day, $enabled);
|
||||
}
|
||||
}
|
||||
|
||||
sub count_created_before {
|
||||
my $c = shift;
|
||||
my $time = shift;
|
||||
|
||||
return Lutim::DB::SQLite::Lutim->count('WHERE path IS NOT NULL AND created_at < ?', $time);
|
||||
}
|
||||
|
||||
sub select_created_after {
|
||||
my $c = shift;
|
||||
my $time = shift;
|
||||
|
||||
my @images;
|
||||
|
||||
my @records = Lutim::DB::SQLite::Lutim->select('WHERE path IS NOT NULL AND created_at >= ?', $time);
|
||||
|
||||
for my $e (@records) {
|
||||
my $i = Lutim::DB::Image->new(app => $c->app);
|
||||
$i->record($e);
|
||||
$i->_slurp;
|
||||
|
||||
push @images, $i;
|
||||
}
|
||||
|
||||
return c(@images);
|
||||
}
|
||||
|
||||
sub select_empty {
|
||||
my $c = shift;
|
||||
|
||||
my @records = Lutim::DB::SQLite::Lutim->select('WHERE path IS NULL LIMIT 1');
|
||||
|
||||
$c->record($records[0]);
|
||||
$c = $c->_slurp;
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
sub write {
|
||||
my $c = shift;
|
||||
|
||||
if ($c->record) {
|
||||
$c->record->update(
|
||||
counter => $c->counter,
|
||||
created_at => $c->created_at,
|
||||
created_by => $c->created_by,
|
||||
delete_at_day => $c->delete_at_day,
|
||||
delete_at_first_view => $c->delete_at_first_view,
|
||||
enabled => $c->enabled,
|
||||
filename => $c->filename,
|
||||
footprint => $c->footprint,
|
||||
height => $c->height,
|
||||
last_access_at => $c->last_access_at,
|
||||
mediatype => $c->mediatype,
|
||||
mod_token => $c->mod_token,
|
||||
path => $c->path,
|
||||
short => $c->short,
|
||||
width => $c->width
|
||||
);
|
||||
} else {
|
||||
my $record = Lutim::DB::SQLite::Lutim->create(
|
||||
counter => $c->counter,
|
||||
created_at => $c->created_at,
|
||||
created_by => $c->created_by,
|
||||
delete_at_day => $c->delete_at_day,
|
||||
delete_at_first_view => $c->delete_at_first_view,
|
||||
enabled => $c->enabled,
|
||||
filename => $c->filename,
|
||||
footprint => $c->footprint,
|
||||
height => $c->height,
|
||||
last_access_at => $c->last_access_at,
|
||||
mediatype => $c->mediatype,
|
||||
mod_token => $c->mod_token,
|
||||
path => $c->path,
|
||||
short => $c->short,
|
||||
width => $c->width
|
||||
);
|
||||
$c->record($record);
|
||||
}
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
sub count_short {
|
||||
my $c = shift;
|
||||
my $short = shift;
|
||||
|
||||
return Lutim::DB::SQLite::Lutim->count('WHERE short IS ?', $short);
|
||||
}
|
||||
|
||||
sub count_empty {
|
||||
my $c = shift;
|
||||
|
||||
return Lutim::DB::SQLite::Lutim->count('WHERE path IS NULL');
|
||||
}
|
||||
|
||||
sub count_not_empty {
|
||||
my $c = shift;
|
||||
|
||||
return Lutim::DB::SQLite::Lutim->count('WHERE path IS NOT NULL');
|
||||
}
|
||||
|
||||
sub clean_ips_until {
|
||||
my $c = shift;
|
||||
my $time = shift;
|
||||
@@ -50,7 +164,7 @@ sub get_images_to_clean {
|
||||
|
||||
my @images;
|
||||
|
||||
my @records = c(Lutim::DB::SQLite::Lutim->select('WHERE enabled = 1 AND (delete_at_day * 86400) < (? - created_at) AND delete_at_day != 0', time()));
|
||||
my @records = Lutim::DB::SQLite::Lutim->select('WHERE enabled = 1 AND (delete_at_day * 86400) < (? - created_at) AND delete_at_day != 0', time());
|
||||
|
||||
for my $e (@records) {
|
||||
my $i = Lutim::DB::Image->new(app => $c->app);
|
||||
@@ -68,7 +182,7 @@ sub get_50_oldest {
|
||||
|
||||
my @images;
|
||||
|
||||
my @records = c(Lutim::DB::SQLite::Lutim->select('WHERE path IS NOT NULL AND enabled = 1 ORDER BY created_at ASC LIMIT 50'));
|
||||
my @records = Lutim::DB::SQLite::Lutim->select('WHERE path IS NOT NULL AND enabled = 1 ORDER BY created_at ASC LIMIT 50');
|
||||
|
||||
for my $e (@records) {
|
||||
my $i = Lutim::DB::Image->new(app => $c->app);
|
||||
@@ -93,31 +207,31 @@ sub disable {
|
||||
sub _slurp {
|
||||
my $c = shift;
|
||||
|
||||
my @urls;
|
||||
my @images;
|
||||
if ($c->record) {
|
||||
@urls = ($c->record);
|
||||
@images = ($c->record);
|
||||
} elsif ($c->short) {
|
||||
@urls = Lutim::DB::SQLite::Lutim->select('WHERE short = ?', $c->short);
|
||||
@images = Lutim::DB::SQLite::Lutim->select('WHERE short = ?', $c->short);
|
||||
}
|
||||
|
||||
if (scalar @urls) {
|
||||
$c->short($urls[0]->short);
|
||||
$c->path($urls[0]->path);
|
||||
$c->footprint($urls[0]->footprint);
|
||||
$c->enabled($urls[0]->enabled);
|
||||
$c->mediatype($urls[0]->mediatype);
|
||||
$c->filename($urls[0]->filename);
|
||||
$c->counter($urls[0]->counter);
|
||||
$c->delete_at_first_view($urls[0]->delete_at_first_view);
|
||||
$c->delete_at_day($urls[0]->delete_at_day);
|
||||
$c->created_at($urls[0]->created_at);
|
||||
$c->created_by($urls[0]->created_by);
|
||||
$c->last_access_at($urls[0]->last_access_at);
|
||||
$c->mod_token($urls[0]->mod_token);
|
||||
$c->width($urls[0]->width);
|
||||
$c->height($urls[0]->height);
|
||||
if (scalar @images) {
|
||||
$c->short($images[0]->short);
|
||||
$c->path($images[0]->path);
|
||||
$c->footprint($images[0]->footprint);
|
||||
$c->enabled($images[0]->enabled);
|
||||
$c->mediatype($images[0]->mediatype);
|
||||
$c->filename($images[0]->filename);
|
||||
$c->counter($images[0]->counter);
|
||||
$c->delete_at_first_view($images[0]->delete_at_first_view);
|
||||
$c->delete_at_day($images[0]->delete_at_day);
|
||||
$c->created_at($images[0]->created_at);
|
||||
$c->created_by($images[0]->created_by);
|
||||
$c->last_access_at($images[0]->last_access_at);
|
||||
$c->mod_token($images[0]->mod_token);
|
||||
$c->width($images[0]->width);
|
||||
$c->height($images[0]->height);
|
||||
|
||||
$c->record($urls[0]) unless $c->record;
|
||||
$c->record($images[0]) unless $c->record;
|
||||
}
|
||||
|
||||
return $c;
|
||||
|
||||
Reference in New Issue
Block a user