Issue #42; abstraction layer finished

This commit is dedicated to Schoumi, who is supporting me on Tipeee.
Many thanks :-)
This commit is contained in:
Luc Didry
2017-05-27 15:45:40 +02:00
parent 1a8d2ea171
commit 9a4a5a5799
5 changed files with 467 additions and 246 deletions

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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

View File

@@ -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;