Commit 3f21ddb3 authored by Luc Didry's avatar Luc Didry
Browse files

Merge branch 'issue-42' into 'development'

Issue 42

See merge request !13
parents d2cd4b83 a8d38f6e
*.swp
lutim.conf
lutim.db
*.db
*.db-shm
*.db-wal
script/hypnotoad.pid
......
image: hatsoftwares/test-ci:latest
stages:
- sqlite
before_script:
- carton install
- rm -f *db
sqlite:
stage: sqlite
cache:
key: "$CI_BUILD_REF_NAME"
untracked: true
paths:
- local
script:
- MOJO_CONFIG=t/sqlite.conf make test
tags:
- Debian
- Jessie
......@@ -2,6 +2,12 @@ Revision history for Lutim
0.8 2017-?
- Improve statistics page
- Add database abstraction layer (#42)
- Add PostgreSQL support (#42)
- Asks for Mojolicious 7.31 minimum (to install it: `carton update`)
- Add Liberapay and Tipeee buttons
- Remove Flattr button
- Handle MOJO_CONFIG env variable (#44)
0.7.1 2016-06-21
- Fix dependency bug
......
EXTRACTFILES=utilities/locales_files.txt
EXTRACTDIR=-D lib -D themes/default/templates
EN=themes/default/lib/Lutim/I18N/en.po
FR=themes/default/lib/Lutim/I18N/fr.po
DE=themes/default/lib/Lutim/I18N/de.po
......@@ -7,19 +7,47 @@ OC=themes/default/lib/Lutim/I18N/oc.po
XGETTEXT=carton exec local/bin/xgettext.pl
CARTON=carton exec
LUTIM=script/lutim
REAL_LUTIM=script/application
locales:
$(XGETTEXT) -W -f $(EXTRACTFILES) -o $(EN) 2>/dev/null
$(XGETTEXT) -W -f $(EXTRACTFILES) -o $(FR) 2>/dev/null
$(XGETTEXT) -W -f $(EXTRACTFILES) -o $(DE) 2>/dev/null
$(XGETTEXT) -W -f $(EXTRACTFILES) -o $(ES) 2>/dev/null
$(XGETTEXT) -W -f $(EXTRACTFILES) -o $(OC) 2>/dev/null
$(XGETTEXT) $(EXTRACTDIR) -o $(EN) 2>/dev/null
$(XGETTEXT) $(EXTRACTDIR) -o $(FR) 2>/dev/null
$(XGETTEXT) $(EXTRACTDIR) -o $(DE) 2>/dev/null
$(XGETTEXT) $(EXTRACTDIR) -o $(ES) 2>/dev/null
$(XGETTEXT) $(EXTRACTDIR) -o $(OC) 2>/dev/null
podcheck:
podchecker lib/Lutim/DB/Image.pm
test-sqlite:
MOJO_CONFIG=t/sqlite.conf $(CARTON) $(REAL_LUTIM) test
test-pg:
MOJO_CONFIG=t/postgresql.conf $(CARTON) $(REAL_LUTIM) test
test: podcheck test-sqlite test-pg
clean:
rm -rf lutim.db files/
dev:
rm -rf themes/default/public/packed/*
$(CARTON) morbo $(LUTIM) --listen http://0.0.0.0:3000 --watch lib/ --watch script/ --watch themes/ --watch lutim.conf
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
......@@ -3,6 +3,7 @@ requires 'EV';
requires 'IO::Socket::SSL';
requires 'Data::Validate::URI';
requires 'Net::Domain::TLD', '>= 1.73'; # Must have the last version to handle (at least) .xyz and .link
requires 'Mojo::Pg';
requires 'Mojolicious::Plugin::I18N';
requires 'Mojolicious::Plugin::AssetPack';
requires 'CSS::Minifier::XS';
......
......@@ -72,12 +72,32 @@ DISTRIBUTIONS
ExtUtils::MakeMaker 0
File::Spec 0.80
perl 5.006
Class-Method-Modifiers-2.12
pathname: E/ET/ETHER/Class-Method-Modifiers-2.12.tar.gz
provides:
Class::Method::Modifiers 2.12
requirements:
B 0
Carp 0
Exporter 0
ExtUtils::MakeMaker 0
base 0
perl 5.006
strict 0
warnings 0
Class-Singleton-1.4
pathname: A/AB/ABW/Class-Singleton-1.4.tar.gz
provides:
Class::Singleton 1.4
requirements:
ExtUtils::MakeMaker 0
Clone-0.39
pathname: G/GA/GARU/Clone-0.39.tar.gz
provides:
Clone 0.39
requirements:
ExtUtils::MakeMaker 0
Test::More 0
Crypt-Blowfish-2.14
pathname: D/DP/DPARIS/Crypt-Blowfish-2.14.tar.gz
provides:
......@@ -98,6 +118,17 @@ DISTRIBUTIONS
requirements:
ExtUtils::MakeMaker 0
perl 5.006
DBD-Pg-3.6.2
pathname: T/TU/TURNSTEP/DBD-Pg-3.6.2.tar.gz
provides:
Bundle::DBD::Pg v3.6.2
DBD::Pg v3.6.2
requirements:
DBI 1.614
ExtUtils::MakeMaker 6.11
Test::More 0.88
Time::HiRes 0
version 0
DBD-SQLite-1.40
pathname: I/IS/ISHIGAKI/DBD-SQLite-1.40.tar.gz
provides:
......@@ -278,19 +309,19 @@ DISTRIBUTIONS
Data::Validate::Domain 0
Data::Validate::IP 0
ExtUtils::MakeMaker 0
DateTime-1.42
pathname: D/DR/DROLSKY/DateTime-1.42.tar.gz
provides:
DateTime 1.42
DateTime::Duration 1.42
DateTime::Helpers 1.42
DateTime::Infinite 1.42
DateTime::Infinite::Future 1.42
DateTime::Infinite::Past 1.42
DateTime::LeapSecond 1.42
DateTime::PP 1.42
DateTime::PPExtra 1.42
DateTime::Types 1.42
DateTime-1.43
pathname: D/DR/DROLSKY/DateTime-1.43.tar.gz
provides:
DateTime 1.43
DateTime::Duration 1.43
DateTime::Helpers 1.43
DateTime::Infinite 1.43
DateTime::Infinite::Future 1.43
DateTime::Infinite::Past 1.43
DateTime::LeapSecond 1.43
DateTime::PP 1.43
DateTime::PPExtra 1.43
DateTime::Types 1.43
requirements:
Carp 0
DateTime::Locale 1.06
......@@ -734,6 +765,14 @@ DISTRIBUTIONS
perl 5.008004
strict 0
warnings 0
Devel-GlobalDestruction-0.14
pathname: H/HA/HAARG/Devel-GlobalDestruction-0.14.tar.gz
provides:
Devel::GlobalDestruction 0.14
requirements:
ExtUtils::MakeMaker 0
Sub::Exporter::Progressive 0.001011
perl 5.006
Devel-StackTrace-2.02
pathname: D/DR/DROLSKY/Devel-StackTrace-2.02.tar.gz
provides:
......@@ -950,6 +989,14 @@ DISTRIBUTIONS
perl 5.005
strict 0
warnings 0
Hash-Merge-0.200
pathname: R/RE/REHSACK/Hash-Merge-0.200.tar.gz
provides:
Hash::Merge 0.200
requirements:
Clone 0
ExtUtils::MakeMaker 0
perl 5.008001
IO-Socket-IP-0.37
pathname: P/PE/PEVANS/IO-Socket-IP-0.37.tar.gz
provides:
......@@ -1341,8 +1388,22 @@ DISTRIBUTIONS
perl 5.006
strict 0
warnings 0
Mojolicious-7.31
pathname: S/SR/SRI/Mojolicious-7.31.tar.gz
Mojo-Pg-3.06
pathname: S/SR/SRI/Mojo-Pg-3.06.tar.gz
provides:
Mojo::Pg 3.06
Mojo::Pg::Database undef
Mojo::Pg::Migrations undef
Mojo::Pg::PubSub undef
Mojo::Pg::Results undef
Mojo::Pg::Transaction undef
requirements:
DBD::Pg 3.005001
ExtUtils::MakeMaker 0
Mojolicious 7.32
SQL::Abstract 1.81
Mojolicious-7.32
pathname: S/SR/SRI/Mojolicious-7.32.tar.gz
provides:
Mojo undef
Mojo::Asset undef
......@@ -1410,7 +1471,7 @@ DISTRIBUTIONS
Mojo::UserAgent::Transactor undef
Mojo::Util undef
Mojo::WebSocket undef
Mojolicious 7.31
Mojolicious 7.32
Mojolicious::Command undef
Mojolicious::Command::cgi undef
Mojolicious::Command::cpanify undef
......@@ -1508,6 +1569,36 @@ DISTRIBUTIONS
Mojolicious 5
Test::More 0
perl 5.010001
Moo-2.003002
pathname: H/HA/HAARG/Moo-2.003002.tar.gz
provides:
Method::Generate::Accessor undef
Method::Generate::BuildAll undef
Method::Generate::Constructor undef
Method::Generate::DemolishAll undef
Moo 2.003002
Moo::HandleMoose undef
Moo::HandleMoose::FakeConstructor undef
Moo::HandleMoose::FakeMetaClass undef
Moo::HandleMoose::_TypeMap undef
Moo::Object undef
Moo::Role 2.003002
Moo::_Utils undef
Moo::_mro undef
Moo::_strictures undef
Moo::sification undef
oo undef
requirements:
Class::Method::Modifiers 1.1
Devel::GlobalDestruction 0.11
Exporter 5.57
ExtUtils::MakeMaker 0
Module::Runtime 0.014
Role::Tiny 2.000004
Scalar::Util 0
Sub::Defer 2.003001
Sub::Quote 2.003001
perl 5.006
Net-Domain-TLD-1.75
pathname: A/AL/ALEXP/Net-Domain-TLD-1.75.tar.gz
provides:
......@@ -1667,6 +1758,22 @@ DISTRIBUTIONS
requirements:
Exporter 5.57
perl 5.006
SQL-Abstract-1.84
pathname: I/IL/ILMARI/SQL-Abstract-1.84.tar.gz
provides:
SQL::Abstract 1.84
SQL::Abstract::Test undef
SQL::Abstract::Tree undef
requirements:
Exporter 5.57
ExtUtils::MakeMaker 0
Hash::Merge 0.12
List::Util 0
MRO::Compat 0.12
Moo 2.000001
Scalar::Util 0
Sub::Quote 2.000001
Text::Balanced 2.00
SUPER-1.20141117
pathname: C/CH/CHROMATIC/SUPER-1.20141117.tar.gz
provides:
......@@ -1767,6 +1874,15 @@ DISTRIBUTIONS
requirements:
ExtUtils::MakeMaker 0
Test::More 0
Sub-Quote-2.003001
pathname: H/HA/HAARG/Sub-Quote-2.003001.tar.gz
provides:
Sub::Defer 2.003001
Sub::Quote 2.003001
requirements:
ExtUtils::MakeMaker 0
Scalar::Util 0
perl 5.006
Sub-Uplevel-0.24
pathname: D/DA/DAGOLDEN/Sub-Uplevel-0.24.tar.gz
provides:
......
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim;
use Mojo::Base 'Mojolicious';
use Mojo::Util qw(quote);
use Lutim::DB::Image;
use Crypt::CBC;
use Data::Entropy qw(entropy_source);
use vars qw($im_loaded);
BEGIN {
......@@ -71,227 +69,9 @@ sub startup {
$self->plugin('AssetPack' => { pipes => [qw(Combine)] });
# Helpers
$self->helper(
render_file => sub {
my $c = shift;
my ($filename, $path, $mediatype, $dl, $expires, $nocache, $key, $thumb) = @_;
$dl = 'attachment' if ($mediatype =~ m/svg/);
$filename = quote($filename);
my $asset;
unless (-f $path && -r $path) {
$c->app->log->error("Cannot read file [$path]. error [$!]");
$c->flash(
msg => $c->l('Unable to find the image: it has been deleted.')
);
return 500;
}
$mediatype =~ s/x-//;
my $headers = Mojo::Headers->new();
if ($nocache) {
$headers->add('Cache-Control' => 'no-cache, no-store, max-age=0, must-revalidate');
} else {
$headers->add('Expires' => $expires);
}
$headers->add('Content-Type' => $mediatype.';name='.$filename);
$headers->add('Content-Disposition' => $dl.';filename='.$filename);
$c->res->content->headers($headers);
if ($key) {
$asset = $c->decrypt($key, $path);
} else {
$asset = Mojo::Asset::File->new(path => $path);
}
if (defined $thumb && $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($asset->slurp);
# Create the thumbnail
$im->Resize(geometry=>'x'.$c->config('thumbnail_size'));
# Replace the asset with the thumbnail
$asset = Mojo::Asset::Memory->new->add_chunk($im->ImageToBlob());
}
$c->res->content->asset($asset);
$headers->add('Content-Length' => $asset->size);
return $c->rendered(200);
}
);
$self->helper(
ip => sub {
my $c = shift;
my $ip_only = shift || 0;
my $proxy = $c->req->headers->header('X-Forwarded-For');
my $ip = ($proxy) ? $proxy : $c->tx->remote_address;
my $remote_port = (defined($c->req->headers->header('X-Remote-Port'))) ? $c->req->headers->header('X-Remote-Port') : $c->tx->remote_port;
return ($ip_only) ? $ip : "$ip remote port:$remote_port";
}
);
$self->helper(
provisioning => sub {
my $c = shift;
# Create some short patterns for 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++) {
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');
$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);
}
}
}
);
$self->helper(
shortener => sub {
my $c = shift;
my $length = shift;
my @chars = ('a'..'z','A'..'Z','0'..'9');
my $result = '';
foreach (1..$length) {
$result .= $chars[entropy_source->get_int(scalar(@chars))];
}
return $result;
}
);
$self->helper(
stop_upload => sub {
my $c = shift;
if (-f 'stop-upload' || -f 'stop-upload.manual') {
$c->stash(
stop_upload => $c->l('Uploading is currently disabled, please try later or contact the administrator (%1).', $config->{contact})
);
return 1;
}
return 0;
}
);
$self->helper(
max_delay => sub {
my $c = shift;
return $c->config->{max_delay} if ($c->config->{max_delay} >= 0);
warn "max_delay set to a negative value. Default to 0.";
return 0;
}
);
$self->helper(
default_delay => sub {
my $c = shift;
return $c->config->{default_delay} if ($c->config->{default_delay} >= 0);
warn "default_delay set to a negative value. Default to 0.";
return 0;
}
);
$self->helper(
is_selected => sub {
my $c = shift;
my $num = shift;
return ($num == $c->default_delay) ? 'selected="selected"' : '';
}
);
$self->helper(
crypt => sub {
my $c = shift;
my $upload = shift;
my $filename = shift;
my $key = $c->shortener($c->config('crypto_key_length'));
my $cipher = Crypt::CBC->new(
-key => $key,
-cipher => 'Blowfish',
-header => 'none',
-iv => 'dupajasi'
);
$cipher->start('encrypting');
my $crypt_asset = Mojo::Asset::File->new;
$crypt_asset->add_chunk($cipher->crypt($upload->slurp));
$crypt_asset->add_chunk($cipher->finish);
my $crypt_upload = Mojo::Upload->new;
$crypt_upload->filename($filename);
$crypt_upload->asset($crypt_asset);
return ($crypt_upload, $key);
}
);
$self->helper(
decrypt => sub {
my $c = shift;
my $key = shift;
my $file = shift;
my $cipher = Crypt::CBC->new(
-key => $key,
-cipher => 'Blowfish',
-header => 'none',
-iv => 'dupajasi'
);
$cipher->start('decrypting');
my $decrypt_asset = Mojo::Asset::File->new;
open(my $f, "<",$file) or die "Unable to read encrypted file: $!";
binmode $f;
while (read($f, my $buffer,1024)) {
$decrypt_asset->add_chunk($cipher->crypt($buffer));
}
$decrypt_asset->add_chunk($cipher->finish) ;
return $decrypt_asset;
}
);
$self->helper(
delete_image => sub {
my $c = shift;
my $img = shift;
unlink $img->path or warn "Could not unlink ".$img->path.": $!";
$img->disable();
}
);
$self->plugin('Lutim::Plugin::Helpers');
# Hooks
$self->hook(
before_dispatch => sub {
my $c = shift;
......
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Command::cron;
use Mojo::Base 'Mojolicious::Commands';
......
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lutim::Command::cron::cleanbdd;
use Mojo::Base 'Mojolicious::Command';
use Mojo::File;
use Lutim::DB::Image;
use FindBin qw($Bin);
use File::Spec qw(catfile);
......@@ -10,8 +12,15 @@ has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
my $cfile = Mojo::File->new($Bin, '..' , 'lutim.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => File::Spec->catfile($Bin, '..' ,'lutim.conf'),
file => $cfile,
default => {
keep_ip_during => 365,
dbtype => 'sqlite',
......
# 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 FindBin qw($Bin);
......@@ -12,8 +13,15 @@ has usage => sub { shift->extract_usage };
sub run {
my $c = shift;
my $cfile = Mojo::File->new($Bin, '..' , 'lutim.conf');
if (defined $ENV{MOJO_CONFIG}) {
$cfile = Mojo::File->new($ENV{MOJO_CONFIG});
unless (-e $cfile->to_abs) {
$cfile = Mojo::File->new($Bin, '..', $ENV{MOJO_CONFIG});
}
}
my $config = $c->app->plugin('Config', {
file => File::Spec->catfile($Bin, '..' ,'lutim.conf'),
file => $cfile,
default => {
dbtype => 'sqlite',
}
......
# 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;