diff --git a/Makefile b/Makefile index 23631ba..05f6844 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,10 @@ podcheck: test-sqlite: MOJO_CONFIG=t/sqlite.conf $(CARTON) $(REAL_LUTIM) test -test: podcheck test-sqlite +test-pg: + MOJO_CONFIG=t/postgresql.conf $(CARTON) $(REAL_LUTIM) test + +test: podcheck test-sqlite test-pg clean: rm -rf lutim.db files/ @@ -33,3 +36,18 @@ dev: devlog: multitail log/development.log + +create-pg-test-db: + sudo -u postgres psql -f t/create-pg-testdb.sql + +stats: + $(CARTON) $(LUTIM) cron stats -m production + +watch: + $(CARTON) $(LUTIM) cron watch -m production + +cleanfiles: + $(CARTON) $(LUTIM) cron cleanfiles -m production + +cleanbdd: + $(CARTON) $(LUTIM) cron cleanbdd -m production diff --git a/lib/Lutim/Command/cron/cleanbdd.pm b/lib/Lutim/Command/cron/cleanbdd.pm index c13b744..b65589b 100644 --- a/lib/Lutim/Command/cron/cleanbdd.pm +++ b/lib/Lutim/Command/cron/cleanbdd.pm @@ -1,8 +1,8 @@ # vim:set sw=4 ts=4 sts=4 ft=perl expandtab: package Lutim::Command::cron::cleanbdd; use Mojo::Base 'Mojolicious::Command'; -use Lutim::DB::Image; use Mojo::File; +use Lutim::DB::Image; use FindBin qw($Bin); use File::Spec qw(catfile); diff --git a/lib/Lutim/Command/cron/cleanfiles.pm b/lib/Lutim/Command/cron/cleanfiles.pm index 59a2def..1293213 100644 --- a/lib/Lutim/Command/cron/cleanfiles.pm +++ b/lib/Lutim/Command/cron/cleanfiles.pm @@ -1,10 +1,9 @@ # vim:set sw=4 ts=4 sts=4 ft=perl expandtab: package Lutim::Command::cron::cleanfiles; use Mojo::Base 'Mojolicious::Command'; -use Mojo::Util qw(slurp decode); +use Mojo::File; use Lutim::DB::Image; use Lutim; -use Mojo::File; use FindBin qw($Bin); use File::Spec qw(catfile); diff --git a/lib/Lutim/Command/cron/stats.pm b/lib/Lutim/Command/cron/stats.pm index 7c83920..f4848d4 100644 --- a/lib/Lutim/Command/cron/stats.pm +++ b/lib/Lutim/Command/cron/stats.pm @@ -1,10 +1,10 @@ # vim:set sw=4 ts=4 sts=4 ft=perl expandtab: package Lutim::Command::cron::stats; use Mojo::Base 'Mojolicious::Command'; -use Lutim::DB::Image; use Mojo::DOM; use Mojo::Util qw(encode); use Mojo::File; +use Lutim::DB::Image; use DateTime; use FindBin qw($Bin); use File::Spec qw(catfile); diff --git a/lib/Lutim/Command/cron/watch.pm b/lib/Lutim/Command/cron/watch.pm index 4eb2ba5..31eda39 100644 --- a/lib/Lutim/Command/cron/watch.pm +++ b/lib/Lutim/Command/cron/watch.pm @@ -1,7 +1,6 @@ # vim:set sw=4 ts=4 sts=4 ft=perl expandtab: package Lutim::Command::cron::watch; use Mojo::Base 'Mojolicious::Command'; -use Mojo::Util qw(slurp decode); use Filesys::DiskUsage qw/du/; use Lutim::DB::Image; use Lutim; diff --git a/lib/Lutim/DB/Image/Pg.pm b/lib/Lutim/DB/Image/Pg.pm index 23c70c9..8340f26 100644 --- a/lib/Lutim/DB/Image/Pg.pm +++ b/lib/Lutim/DB/Image/Pg.pm @@ -46,8 +46,7 @@ sub select_created_after { sub { my ($e, $num) = @_; my $i = Lutim::DB::Image->new(app => $c->app); - $i->record(1); - $i->_slurp; + $i->_slurp($e); push @images, $i; } @@ -61,8 +60,7 @@ sub select_empty { my $record = $c->app->pg->db->query('SELECT * FROM lutim WHERE path IS NULL LIMIT 1')->hashes->first; - $c->record(1); - $c = $c->_slurp; + $c = $c->_slurp($record); return $c; } @@ -84,7 +82,7 @@ sub count_short { my $c = shift; my $short = shift; - return $c->app->pg->db->query('SELECT count(short) FROM lutim WHERE short IS ?', $short)->hashes->first->{count}; + return $c->app->pg->db->query('SELECT count(short) FROM lutim WHERE short = ?', $short)->hashes->first->{count}; } sub count_empty { @@ -121,7 +119,7 @@ sub get_no_longer_viewed_files { my ($e, $num) = @_; my $i = Lutim::DB::Image->new(app => $c->app); $i->record(1); - $i->_slurp; + $i->_slurp($e); push @images, $i; } @@ -141,8 +139,7 @@ sub get_images_to_clean { sub { my ($e, $num) = @_; my $i = Lutim::DB::Image->new(app => $c->app); - $i->record(1); - $i->_slurp; + $i->_slurp($e); push @images, $i; } @@ -162,8 +159,7 @@ sub get_50_oldest { sub { my ($e, $num) = @_; my $i = Lutim::DB::Image->new(app => $c->app); - $i->record(1); - $i->_slurp; + $i->_slurp($e); push @images, $i; } @@ -183,12 +179,20 @@ sub disable { sub _slurp { my $c = shift; + my $r = shift; - my $images = $c->app->pg->db->query('SELECT * FROM lutim WHERE short = ?', $c->short)->hashes; + my $image; + if (defined $r) { + $image = $r; + } else { + my $images = $c->app->pg->db->query('SELECT * FROM lutim WHERE short = ?', $c->short)->hashes; - if ($images->size) { - my $image = $images->first; + if ($images->size) { + $image = $images->first; + } + } + if ($image) { $c->short($image->{short}); $c->path($image->{path}); $c->footprint($image->{footprint}); diff --git a/lib/Lutim/DB/Image/SQLite.pm b/lib/Lutim/DB/Image/SQLite.pm index 67c2205..65de29c 100644 --- a/lib/Lutim/DB/Image/SQLite.pm +++ b/lib/Lutim/DB/Image/SQLite.pm @@ -217,23 +217,25 @@ sub _slurp { } 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); + my $image = $images[0]; - $c->record($images[0]) unless $c->record; + $c->short($image->short); + $c->path($image->path); + $c->footprint($image->footprint); + $c->enabled($image->enabled); + $c->mediatype($image->mediatype); + $c->filename($image->filename); + $c->counter($image->counter); + $c->delete_at_first_view($image->delete_at_first_view); + $c->delete_at_day($image->delete_at_day); + $c->created_at($image->created_at); + $c->created_by($image->created_by); + $c->last_access_at($image->last_access_at); + $c->mod_token($image->mod_token); + $c->width($image->width); + $c->height($image->height); + + $c->record($image) unless $c->record; } return $c; diff --git a/lib/Mounter.pm b/lib/Mounter.pm index 19d21cb..58527d6 100644 --- a/lib/Mounter.pm +++ b/lib/Mounter.pm @@ -28,6 +28,8 @@ sub startup { } ); + $self->plugin('Lutim::Plugin::Helpers'); + $config->{prefix} = $config->{url_sub_dir} if (defined($config->{url_sub_dir}) && $config->{prefix} eq '/'); $self->app->log->warn('"url_sub_dir" configuration option is deprecated. Use "prefix" instead. "url_sub_dir" will be removed in the future') if (defined($config->{url_sub_dir})); diff --git a/t/create-pg-testdb.sql b/t/create-pg-testdb.sql new file mode 100644 index 0000000..d65625c --- /dev/null +++ b/t/create-pg-testdb.sql @@ -0,0 +1,2 @@ +CREATE USER lutim WITH PASSWORD 'lutim'; +CREATE DATABASE lutimtest OWNER lutim; diff --git a/t/postgresql.conf b/t/postgresql.conf new file mode 100644 index 0000000..c9205a1 --- /dev/null +++ b/t/postgresql.conf @@ -0,0 +1,169 @@ +# vim:set sw=4 ts=4 sts=4 ft=perl expandtab: +{ + #################### + # Hypnotoad settings + #################### + # see http://mojolicio.us/perldoc/Mojo/Server/Hypnotoad for a full list of settings + hypnotoad => { + # array of IP addresses and ports you want to listen to + listen => ['http://127.0.0.1:8080'], + # if you use Lutim behind a reverse proxy like Nginx, you want to set proxy to 1 + # if you use Lutim directly, let it commented + #proxy => 1, + }, + + ################ + # Lutim settings + ################ + + # put a way to contact you here and uncomment it + # mandatory + contact => 'John Doe, admin[at]example.com', + + # random string used to encrypt cookies + # mandatory + secrets => ['fdjsofjoihrei'], + + # choose a theme. See the available themes in `themes` directory + # optional, default is 'default' + #theme => 'default', + + # length of the images random URL + # optional, default is 8 + #length => 8, + + # length of the encryption key + # optional, default is 8 + #crypto_key_length => 8, + + # how many URLs will be provisioned in a batch ? + # optional, default is 5 + #provis_step => 5, + + # max number of URLs to be provisioned + # optional, default is 100 + #provisioning => 100, + + # anti-flood protection delay, in seconds + # users won't be able to ask Lutim to download images more than one per anti_flood_delay seconds + # optional, default is 5 + #anti_flood_delay => 5, + + # twitter account which will appear on twitter cards + # see https://dev.twitter.com/docs/cards/validation/validator to register your Lutim instance on twitter + # optional, default is @framasky + #tweet_card_via => '@framasky', + + # max image size, in octets + # you can write it 10*1024*1024 + # optional, default is 10485760 + max_file_size => 1048576, + + # if you want to have piwik statistics, provide a piwik image tracker + # only the image tracker is allowed, no javascript + # optional, no default + #piwik_img => 'https://piwik.example.org/piwik.php?idsite=1&rec=1', + + # if you want to include something in the right of the screen, put it here + # here's an example to put the logo of your hoster + # optional, no default + #hosted_by => 'My super hoster Hoster logo', + + # DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED + # Lutim now checks if the X-Forwarded-Proto header is present and equal to https. + # set to 1 if you use Lutim behind a secure web server + # optional, default is 0 + #https => 0, + + # broadcast_message which will displayed on all pages of Lutim (but no in json response) + # optional, no default + broadcast_message => 'test broadcast message', + + # array of authorized domains for API calls. + # if you want to authorize everyone to use the API: ['*'] + # optional, no domains allowed by default + #allowed_domains => ['http://1.example.com', 'http://2.example.com'], + + # default time limit for files + # valid values are 0, 1, 7, 30 and 365 + # optional, default is 0 (no limit) + default_delay => 30, + + # number of days after which the images will be deleted, even if they were uploaded with "no delay" (or value superior to max_delay) + # a warning message will be displayed on homepage + # optional, default is 0 (no limit) + max_delay => 200, + + # if set to 1, all the images will be encrypted and the encryption option will no be displayed + # optional, default is 0 + #always_encrypt => 0, + + # length of the image's delete token + # optional, default is 24 + #token_length => 24, + + # URL sub-directory in which you want Lutim to be accessible + # example: you want to have Lutim under https://example.org/lutim/ + # => set prefix to '/lutim' or to '/lutim/', it doesn't matter + # optional, defaut is / + #prefix => '/', + + # choose what database you want to use + # valid choices are sqlite and postgresql (all lowercase) + # optional, default is sqlite + dbtype => 'postgresql', + + # SQLite ONLY - only used if dbtype is set to sqlite + # define a path to the SQLite database + # you can define it relative to lutim directory or set an absolute path + # remember that it has to be in a directory writable by Lutim user + # optional, default is lutim.db + #db_path => 'lutim.db', + + # PostgreSQL ONLY - only used if dbtype is set to postgresql + # these are the credentials to access the PostgreSQL database + # mandatory if you choosed postgresql as dbtype + pgdb => { + database => 'lutimtest', + host => 'localhost', + user => 'lutim', + pwd => 'lutim' + }, + + # define the height of the thumbnails generated at users' will + # this is not the height of the thumbnails send after upload, + # we're talking about thumbnails generated when someone asked for + # https://example.org/lutim/tesrinp?thumb + # this works only if you have ImageMagick + # optional, default is 100 (pixels) + #thumbnail_size => 100, + + ########################## + # Lutim cron jobs settings + ########################## + + # number of days shown in /stats page (used with script/lutim cron stats) + # optional, default is 365 + #stats_day_num => 365, + + # number of days senders' IP addresses are kept in database + # after that delay, they will be deleted from database (used with script/lutim cron cleanbdd) + # optional, default is 365 + #keep_ip_during => 365, + + # max size of the files directory, in octets + # used by script/lutim cron watch to trigger an action + # optional, no default + #max_total_size => 10*1024*1024*1024, + + # default action when files directory is over max_total_size (used with script/lutim cron watch) + # valid values are 'warn', 'stop-upload' and 'delete' + # please, see readme + # optional, default is 'warn' + #policy_when_full => 'warn', + + # images which are not viewed since delete_no_longer_viewed_files days will be deleted by the cron cleanfiles task + # if delete_no_longer_viewed_files is not set, the no longer viewed files will NOT be deleted + # optional, no default + #delete_no_longer_viewed_files => 90 +}; diff --git a/utilities/migrations.sql b/utilities/migrations.sql index c35f272..7663d03 100644 --- a/utilities/migrations.sql +++ b/utilities/migrations.sql @@ -1,20 +1,20 @@ -- 1 up CREATE TABLE IF NOT EXISTS lutim ( short text PRIMARY KEY, - path text, - footprint text, + path text default null, + footprint text default null, enabled integer, - mediatype text, - filename text, + mediatype text default null, + filename text default null, counter integer default 0, - delete_at_first_view integer, - delete_at_day integer, - created_at integer, - created_by text, - last_access_at integer, - mod_token text, - width integer, - height integer)' + delete_at_first_view integer default null, + delete_at_day integer default null, + created_at integer default null, + created_by text default null, + last_access_at integer default null, + mod_token text default null, + width integer default null, + height integer default null ); -- 1 down DROP TABLE lutim;