diff --git a/lib/Lutim.pm b/lib/Lutim.pm
index 841462a..854e272 100644
--- a/lib/Lutim.pm
+++ b/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);
}
}
}
diff --git a/lib/Lutim/Command/cron/stats.pm b/lib/Lutim/Command/cron/stats.pm
index c82d6fa..08c79b5 100644
--- a/lib/Lutim/Command/cron/stats.pm
+++ b/lib/Lutim/Command/cron/stats.pm
@@ -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
| <%= \$raw[4] %> | ".$unlimited_enabled." | ".$unlimited_disabled." | ΓΈ |
\n");
$raw->append_content("| <%= \$raw[5] %> | ".$day_enabled." | ".$day_disabled." | ".$day_enabled." (100%) |
\n");
$raw->append_content("| <%= \$raw[6] %> | ".$week_enabled." | ".$week_disabled." | ".$week_enabled." (100%) |
\n");
$raw->append_content("| <%= \$raw[7] %> | ".$month_enabled." | ".$month_disabled." | ".$month_enabled." (100%) |
\n");
- $raw->append_content("| <%= \$raw[8] %> | ".$year_enabled." | ".$year_disabled." | ".$year_disabled_in_month." (".sprintf('%.2f', $year_disabled_in_month/$year_enabled)."%) |
\n");
+ $raw->append_content("| <%= \$raw[8] %> | ".$year_enabled." | ".$year_disabled." | ".$year_disabled_in_month.$year_disabled_in_month_pct." |
\n");
$raw_foot->append_content("\n| <%= \$raw[9] %> | ".($unlimited_enabled + $day_enabled + $week_enabled + $month_enabled + $year_enabled)." | ".($unlimited_disabled + $day_disabled + $week_disabled + $month_disabled + $year_disabled)." | ".($day_enabled + $week_enabled + $month_enabled + $year_disabled_in_month)." |
\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
diff --git a/lib/Lutim/Controller.pm b/lib/Lutim/Controller.pm
index d9229b8..1a94305 100644
--- a/lib/Lutim/Controller.pm
+++ b/lib/Lutim/Controller.pm
@@ -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();
diff --git a/lib/Lutim/DB/Image.pm b/lib/Lutim/DB/Image.pm
index a035dd4..0e936e0 100644
--- a/lib/Lutim/DB/Image.pm
+++ b/lib/Lutim/DB/Image.pm
@@ -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 : C<$c-Ecount_delete_at_day_endis($delete_at_day, $enabled[, $time])>
+
+=item B : 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 : 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 : integer
+
+=back
+
+=head2 count_created_before
+
+=over 1
+
+=item B : C<$c-Ecount_created_before($time)>
+
+=item B : an unix timestamp
+
+=item B : count how many images have been created before the given timestamp
+
+=item B : integer
+
+=back
+
+=head2 select_created_after
+
+=over 1
+
+=item B : C<$c-Eselect_created_after($time)>
+
+=item B : an unix timestamp
+
+=item B : select images created after the given timestamp
+
+=item B : a Mojo::Collection object containing the images created after the given timestamp
+
+=back
+
+=head2 select_empty
+
+=over 1
+
+=item B : C<$c-Eselect_empty>
+
+=item B : none
+
+=item B : select a ready-to-use empty record
+
+=item B : a db accessor object
+
+=back
+
+=head2 write
+
+=over 1
+
+=item B : C<$c-Ewrite>
+
+=item B : none
+
+=item B : create or update a record in the database, with the values of the object's attributes
+
+=item B : the db accessor object
+
+=back
+
+=head2 count_short
+
+=over 1
+
+=item B : C<$c-Ecount_short($short)>
+
+=item B : a random string, unique image identifier in the database
+
+=item B : checks that an identifier isn't already used
+
+=item B : integer, number of records having this identifier (should be 0 or 1)
+
+=back
+
+=head2 count_empty
+
+=over 1
+
+=item B : C<$c-Ecount_empty>
+
+=item B : none
+
+=item B : counts the number of record which path is null
+
+=item B : integer
+
+=back
+
+=head2 count_not_empty
+
+=over 1
+
+=item B : C<$c-Ecount_not_empty>
+
+=item B : none
+
+=item B : counts the number of record which path is not null
+
+=item B : integer
+
+=back
+
=head2 clean_ips_until
=over 1
diff --git a/lib/Lutim/DB/Image/SQLite.pm b/lib/Lutim/DB/Image/SQLite.pm
index a47f103..a165d37 100644
--- a/lib/Lutim/DB/Image/SQLite.pm
+++ b/lib/Lutim/DB/Image/SQLite.pm
@@ -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;