Add DB abstraction layer
This commit is contained in:
parent
5684cbe17f
commit
d909b8ad70
|
@ -0,0 +1,14 @@
|
|||
Revision history for Lufi
|
||||
|
||||
0.02 2017-?
|
||||
- Database abstraction layer
|
||||
- IE 11 and Edge support
|
||||
- Fix encoding error (#83)
|
||||
- Htpassword authentication support
|
||||
- Ability to add a password to a file
|
||||
|
||||
0.01 2017-01-09
|
||||
- Upload files
|
||||
- Download files
|
||||
- Preview files in browser depending on mimetype (images and videos)
|
||||
- LDAP authentication support
|
3
Makefile
3
Makefile
|
@ -20,6 +20,9 @@ locales:
|
|||
$(XGETTEXT) $(EXTRACTDIR) -o $(PT) 2>/dev/null
|
||||
$(XGETTEXT) $(EXTRACTDIR) -o $(NL) 2>/dev/null
|
||||
|
||||
podcheck:
|
||||
podchecker lib/Lufi/DB/File.pm lib/Lufi/DB/Slice.pm
|
||||
|
||||
test:
|
||||
$(CARTON) $(REAL_LUFI) test
|
||||
|
||||
|
|
2
cpanfile
2
cpanfile
|
@ -1,9 +1,11 @@
|
|||
requires 'Mojolicious', '>= 7.31';
|
||||
requires 'ORLite';
|
||||
requires 'Mojolicious::Plugin::DebugDumperHelper';
|
||||
requires 'Mojolicious::Plugin::PgURLHelper';
|
||||
requires 'Mojolicious::Plugin::I18N';
|
||||
requires 'Mojolicious::Plugin::Mail';
|
||||
requires 'Mojolicious::Plugin::Authentication';
|
||||
requires 'Mojo::Pg';
|
||||
requires 'EV';
|
||||
requires 'Filesys::DiskUsage';
|
||||
requires 'Switch';
|
||||
|
|
|
@ -51,6 +51,26 @@ DISTRIBUTIONS
|
|||
perl 5.006
|
||||
strict 0
|
||||
warnings 0
|
||||
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
|
||||
Clone-0.39
|
||||
pathname: G/GA/GARU/Clone-0.39.tar.gz
|
||||
provides:
|
||||
Clone 0.39
|
||||
requirements:
|
||||
ExtUtils::MakeMaker 0
|
||||
Test::More 0
|
||||
Convert-ASN1-0.27
|
||||
pathname: G/GB/GBARR/Convert-ASN1-0.27.tar.gz
|
||||
provides:
|
||||
|
@ -85,6 +105,17 @@ DISTRIBUTIONS
|
|||
ExtUtils::MakeMaker 6.30
|
||||
Test::Fatal 0
|
||||
Test::More 0
|
||||
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.54
|
||||
pathname: I/IS/ISHIGAKI/DBD-SQLite-1.54.tar.gz
|
||||
provides:
|
||||
|
@ -241,6 +272,14 @@ DISTRIBUTIONS
|
|||
perl 5.006
|
||||
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
|
||||
Digest-HMAC-1.03
|
||||
pathname: G/GA/GAAS/Digest-HMAC-1.03.tar.gz
|
||||
provides:
|
||||
|
@ -454,6 +493,14 @@ DISTRIBUTIONS
|
|||
ExtUtils::MakeMaker 0
|
||||
HTTP::Headers 6
|
||||
perl 5.008001
|
||||
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-HTML-1.001
|
||||
pathname: C/CJ/CJM/IO-HTML-1.001.tar.gz
|
||||
provides:
|
||||
|
@ -571,6 +618,13 @@ DISTRIBUTIONS
|
|||
File::Spec 0
|
||||
List::Util 0
|
||||
Test::More 0.47
|
||||
MRO-Compat-0.13
|
||||
pathname: H/HA/HAARG/MRO-Compat-0.13.tar.gz
|
||||
provides:
|
||||
MRO::Compat 0.13
|
||||
requirements:
|
||||
ExtUtils::MakeMaker 0
|
||||
perl 5.006
|
||||
MailTools-2.18
|
||||
pathname: M/MA/MARKOV/MailTools-2.18.tar.gz
|
||||
provides:
|
||||
|
@ -654,6 +708,31 @@ DISTRIBUTIONS
|
|||
Text::ParseWords 0
|
||||
perl 5.006001
|
||||
version 0.87
|
||||
Module-Runtime-0.015
|
||||
pathname: Z/ZE/ZEFRAM/Module-Runtime-0.015.tar.gz
|
||||
provides:
|
||||
Module::Runtime 0.015
|
||||
requirements:
|
||||
Module::Build 0
|
||||
Test::More 0.41
|
||||
perl 5.006
|
||||
strict 0
|
||||
warnings 0
|
||||
Mojo-Pg-4.0
|
||||
pathname: S/SR/SRI/Mojo-Pg-4.0.tar.gz
|
||||
provides:
|
||||
Mojo::Pg 4.0
|
||||
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
|
||||
perl 5.010001
|
||||
Mojolicious-7.36
|
||||
pathname: S/SR/SRI/Mojolicious-7.36.tar.gz
|
||||
provides:
|
||||
|
@ -813,6 +892,43 @@ DISTRIBUTIONS
|
|||
Mojolicious 5
|
||||
Test::More 0
|
||||
perl 5.001001
|
||||
Mojolicious-Plugin-PgURLHelper-0.03
|
||||
pathname: L/LD/LDIDRY/Mojolicious-Plugin-PgURLHelper-0.03.tar.gz
|
||||
provides:
|
||||
Mojolicious::Plugin::PgURLHelper 0.03
|
||||
requirements:
|
||||
ExtUtils::MakeMaker 0
|
||||
Mojolicious 7.23
|
||||
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
|
||||
Mozilla-CA-20160104
|
||||
pathname: A/AB/ABH/Mozilla-CA-20160104.tar.gz
|
||||
provides:
|
||||
|
@ -909,6 +1025,45 @@ DISTRIBUTIONS
|
|||
ExtUtils::MakeMaker 6.30
|
||||
File::Spec 0
|
||||
strict 0
|
||||
Role-Tiny-2.000005
|
||||
pathname: H/HA/HAARG/Role-Tiny-2.000005.tar.gz
|
||||
provides:
|
||||
Role::Tiny 2.000005
|
||||
Role::Tiny::With 2.000005
|
||||
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
|
||||
Sub-Exporter-Progressive-0.001013
|
||||
pathname: F/FR/FREW/Sub-Exporter-Progressive-0.001013.tar.gz
|
||||
provides:
|
||||
Sub::Exporter::Progressive 0.001013
|
||||
requirements:
|
||||
ExtUtils::MakeMaker 0
|
||||
Sub-Quote-2.004000
|
||||
pathname: H/HA/HAARG/Sub-Quote-2.004000.tar.gz
|
||||
provides:
|
||||
Sub::Defer 2.004000
|
||||
Sub::Quote 2.004000
|
||||
requirements:
|
||||
ExtUtils::MakeMaker 0
|
||||
Scalar::Util 0
|
||||
perl 5.006
|
||||
Sub-Uplevel-0.2800
|
||||
pathname: D/DA/DAGOLDEN/Sub-Uplevel-0.2800.tar.gz
|
||||
provides:
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package Lufi;
|
||||
use Mojo::Base 'Mojolicious';
|
||||
use LufiDB;
|
||||
use Net::LDAP;
|
||||
use Apache::Htpasswd;
|
||||
|
||||
|
@ -29,6 +28,7 @@ sub startup {
|
|||
upload_dir => 'files',
|
||||
session_duration => 3600,
|
||||
allow_pwd_on_files => 0,
|
||||
dbtype => 'sqlite',
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package Lufi::Command::cron::cleanbdd;
|
||||
use Mojo::Base 'Mojolicious::Command';
|
||||
use LufiDB;
|
||||
use Lufi::DB::File;
|
||||
use FindBin qw($Bin);
|
||||
use File::Spec qw(catfile);
|
||||
|
||||
has description => 'Delete IP addresses from database after configured delay.';
|
||||
has usage => sub { shift->extract_usage };
|
||||
|
@ -11,20 +10,24 @@ has usage => sub { shift->extract_usage };
|
|||
sub run {
|
||||
my $c = shift;
|
||||
|
||||
my $cfile = Mojo::File->new($Bin, '..' , 'lufi.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, '..' ,'lufi.conf'),
|
||||
file => $cfile,
|
||||
default => {
|
||||
dbtype => 'sqlite',
|
||||
keep_ip_during => 365,
|
||||
}
|
||||
});
|
||||
|
||||
my $separation = time() - $config->{keep_ip_during} * 86400;
|
||||
|
||||
LufiDB->do(
|
||||
'UPDATE files SET created_by = NULL WHERE created_by IS NOT NULL AND created_at < ?',
|
||||
{},
|
||||
$separation
|
||||
);
|
||||
Lufi::DB::File->new(app => $c->app)->delete_creator_before($separation);
|
||||
}
|
||||
|
||||
=encoding utf8
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package Lufi::Command::cron::cleanfiles;
|
||||
use Mojo::Base 'Mojolicious::Command';
|
||||
use LufiDB;
|
||||
use Lufi::File;
|
||||
use Lufi::DB::File;
|
||||
use FindBin qw($Bin);
|
||||
use File::Spec qw(catfile);
|
||||
|
||||
has description => 'Delete expired files.';
|
||||
has usage => sub { shift->extract_usage };
|
||||
|
@ -12,28 +10,39 @@ has usage => sub { shift->extract_usage };
|
|||
sub run {
|
||||
my $c = shift;
|
||||
|
||||
my $cfile = Mojo::File->new($Bin, '..' , 'lufi.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 => $cfile,
|
||||
default => {
|
||||
dbtype => 'sqlite',
|
||||
}
|
||||
});
|
||||
|
||||
my $time = time();
|
||||
|
||||
## Select only files expired since two days, to be sure that nobody is still downloading it
|
||||
my @files = LufiDB::Files->select('WHERE deleted = 0 AND ((delete_at_day + 2) * 86400) < (? - created_at) AND delete_at_day != 0', $time);
|
||||
|
||||
for my $file (@files) {
|
||||
my $f = Lufi::File->new(record => $file);
|
||||
$file->delete;
|
||||
}
|
||||
|
||||
my $config = $c->app->plugin('Config', {
|
||||
file => File::Spec->catfile($Bin, '..' ,'lufi.conf'),
|
||||
});
|
||||
my $ldfile = Lufi::DB::File->new(app => $c->app);
|
||||
$ldfile->get_expired($time)->each(
|
||||
sub {
|
||||
my ($f, $num) = @_;
|
||||
$f->delete;
|
||||
}
|
||||
);
|
||||
|
||||
if (defined($config->{delete_no_longer_viewed_files}) && $config->{delete_no_longer_viewed_files} > 0) {
|
||||
$time = time() - $config->{delete_no_longer_viewed_files} * 86400;
|
||||
@files = LufiDB::Files->select('WHERE deleted = 0 AND last_access_at < ?', $time);
|
||||
|
||||
for my $file (@files) {
|
||||
my $f = Lufi::File->new(record => $file);
|
||||
$file->delete;
|
||||
}
|
||||
my $ldfile = Lufi::DB::File->new(app => $c->app);
|
||||
$ldfile->get_no_longer_viewed($time)->each(
|
||||
sub {
|
||||
my ($f, $num) = @_;
|
||||
$f->delete;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package Lufi::Command::cron::watch;
|
||||
use Mojo::Base 'Mojolicious::Command';
|
||||
use Filesys::DiskUsage qw/du/;
|
||||
use LufiDB;
|
||||
use Lufi::File;
|
||||
use Lufi::DB::File;
|
||||
use Switch;
|
||||
use FindBin qw($Bin);
|
||||
use File::Spec qw(catfile);
|
||||
|
||||
has description => 'Watch the files directory and take action when over quota';
|
||||
has usage => sub { shift->extract_usage };
|
||||
|
@ -13,9 +11,17 @@ has usage => sub { shift->extract_usage };
|
|||
sub run {
|
||||
my $c = shift;
|
||||
|
||||
my $cfile = Mojo::File->new($Bin, '..' , 'lufi.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, '..' ,'lufi.conf'),
|
||||
file => $cfile,
|
||||
default => {
|
||||
dbtype => 'sqlite',
|
||||
policy_when_full => 'warn'
|
||||
}
|
||||
});
|
||||
|
@ -36,11 +42,14 @@ sub run {
|
|||
}
|
||||
case 'delete' {
|
||||
say '[Lufi cron job watch] Older files are being deleted';
|
||||
my $ldfile = Lufi::DB::File->new(app => $c->app);
|
||||
do {
|
||||
for my $file (LufiDB::Files->select('WHERE deleted = 0 ORDER BY created_at ASC LIMIT 50')) {
|
||||
my $f = Lufi::File->new(record => $file);
|
||||
$file->delete;
|
||||
}
|
||||
$ldfile->get_oldest_undeleted_files(50)->each(
|
||||
sub {
|
||||
my ($f, $num) = @_;
|
||||
$f->delete;
|
||||
}
|
||||
);
|
||||
} while (du(qw/files/) > $config->{max_total_size});
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -4,9 +4,8 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||
use Mojo::JSON qw(encode_json decode_json to_json true false);
|
||||
use Mojo::Util qw(encode decode);
|
||||
use Mojo::File;
|
||||
use LufiDB;
|
||||
use Lufi::File;
|
||||
use Lufi::Slice;
|
||||
use Lufi::DB::File;
|
||||
use Lufi::DB::Slice;
|
||||
use File::Spec::Functions;
|
||||
use Number::Bytes::Human qw(format_bytes);
|
||||
use Filesys::DfPortable;
|
||||
|
@ -38,47 +37,46 @@ sub upload {
|
|||
# Check if stop_upload file is present
|
||||
if ($c->stop_upload) {
|
||||
$stop = 1;
|
||||
$c->send(encode_json(
|
||||
$c->send(decode('UTF-8', encode_json(
|
||||
{
|
||||
success => false,
|
||||
msg => $c->l('Sorry, uploading is disabled.'),
|
||||
sent_delay => $json->{delay},
|
||||
i => $json->{i}
|
||||
}
|
||||
));
|
||||
)));
|
||||
}
|
||||
# Check against max_size
|
||||
elsif (defined $c->config('max_file_size')) {
|
||||
if ($json->{size} > $c->config('max_file_size')) {
|
||||
$stop = 1;
|
||||
$c->send(encode_json(
|
||||
$c->send(decode('UTF-8', encode_json(
|
||||
{
|
||||
success => false,
|
||||
msg => $c->l('Your file is too big: %1 (maximum size allowed: %2)', format_bytes($json->{size}), format_bytes($c->config('max_file_size'))),
|
||||
sent_delay => $json->{delay},
|
||||
i => $json->{i}
|
||||
}
|
||||
));
|
||||
)));
|
||||
}
|
||||
}
|
||||
# Check that we have enough space (multiplying by 2 since it's encrypted, it takes more place that the original file)
|
||||
elsif ($json->{part} == 0 && ($json->{size} * 2) >= dfportable($c->config('upload_dir'))->{bavail}) {
|
||||
$stop = 1;
|
||||
$c->send(encode_json(
|
||||
$c->send(decode('UTF-8', encode_json(
|
||||
{
|
||||
success => false,
|
||||
msg => $c->l('No enough space available on the server for this file (size: %1).', format_bytes($json->{size})),
|
||||
sent_delay => $json->{delay},
|
||||
i => $json->{i}
|
||||
}
|
||||
));
|
||||
)));
|
||||
}
|
||||
|
||||
unless ($stop) {
|
||||
my $f;
|
||||
if (defined($json->{id})) {
|
||||
my @records = LufiDB::Files->select('WHERE short = ?', $json->{id});
|
||||
$f = Lufi::File->new(record => $records[0]) if scalar @records;
|
||||
$f = Lufi::DB::File->new(app => $c->app)->from_short($json->{id});
|
||||
} else {
|
||||
my $delay;
|
||||
unless (defined $json->{delay}) {
|
||||
|
@ -113,19 +111,17 @@ sub upload {
|
|||
if (defined($c->config('ldap')) || defined($c->config('htpasswd'))) {
|
||||
$creator = 'User: '.$c->current_user.', IP: '.$creator;
|
||||
}
|
||||
$f = Lufi::File->new(
|
||||
record => $c->get_empty,
|
||||
created_by => $creator,
|
||||
delete_at_first_view => ($json->{del_at_first_view}) ? 1 : 0,
|
||||
delete_at_day => $delay,
|
||||
mediatype => $json->{type},
|
||||
filename => $json->{name},
|
||||
filesize => $json->{size},
|
||||
nbslices => $json->{total},
|
||||
mod_token => $c->shortener($c->config('token_length')),
|
||||
passwd => $salted_pwd
|
||||
);
|
||||
$f->write;
|
||||
$f = Lufi::DB::File->new(app => $c->app)->get_empty()
|
||||
->created_by($creator)
|
||||
->delete_at_first_view(($json->{del_at_first_view}) ? 1 : 0)
|
||||
->delete_at_day($delay)
|
||||
->mediatype($json->{type})
|
||||
->filename($json->{name})
|
||||
->filesize($json->{size})
|
||||
->nbslices($json->{total})
|
||||
->mod_token($c->shortener($c->config('token_length')))
|
||||
->passwd($salted_pwd)
|
||||
->write;
|
||||
}
|
||||
|
||||
# This check is just in case we didn't succeed to find a corresponding record
|
||||
|
@ -140,7 +136,8 @@ sub upload {
|
|||
|
||||
# Create slice file
|
||||
my $file = catfile($dir, $json->{part}.'.part');
|
||||
my $s = Lufi::Slice->new(
|
||||
my $s = Lufi::DB::Slice->new(
|
||||
app => $c->app,
|
||||
short => $f->short,
|
||||
j => $json->{part},
|
||||
path => $file
|
||||
|
@ -176,14 +173,14 @@ sub upload {
|
|||
}
|
||||
));
|
||||
} else {
|
||||
$ws->send(encode_json(
|
||||
$ws->send(decode('UTF-8', encode_json(
|
||||
{
|
||||
success => false,
|
||||
msg => $c->l('The server was unable to find the file record to add your file part to. Please, contact the administrator.'),
|
||||
sent_delay => $json->{delay},
|
||||
i => $json->{i}
|
||||
}
|
||||
));
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -203,37 +200,35 @@ sub download {
|
|||
$c->inactivity_timeout(300000);
|
||||
$c->app->log->debug('Client connected');
|
||||
|
||||
my @records = LufiDB::Files->select('WHERE short = ?', $short);
|
||||
my $ldfile = Lufi::DB::File->new(app => $c->app)->from_short($short);
|
||||
|
||||
# Do we have a file?
|
||||
if (scalar @records) {
|
||||
my $record = $records[0];
|
||||
if (defined $ldfile) {
|
||||
# Is the file fully uploaded?
|
||||
if ($record->deleted
|
||||
if ($ldfile->deleted
|
||||
|| (
|
||||
$record->delete_at_day != 0
|
||||
$ldfile->delete_at_day != 0
|
||||
&& (
|
||||
($record->created_at + $record->delete_at_day * 86400) < time()
|
||||
($ldfile->created_at + $ldfile->delete_at_day * 86400) < time()
|
||||
)
|
||||
)
|
||||
) {
|
||||
unless ($record->deleted) {
|
||||
my $f = Lufi::File->new(record => $record);
|
||||
$f->delete;
|
||||
unless ($ldfile->deleted) {
|
||||
$ldfile->delete;
|
||||
}
|
||||
$c->on(
|
||||
message => sub {
|
||||
my ($ws, $json) = @_;
|
||||
$c->send(encode_json(
|
||||
$c->send(decode('UTF-8', encode_json(
|
||||
{
|
||||
success => false,
|
||||
msg => $c->l('Error: the file existed but was deleted.')
|
||||
}
|
||||
));
|
||||
)));
|
||||
}
|
||||
);
|
||||
} elsif ($record->complete) {
|
||||
my $f = Lufi::File->new(record => $record);
|
||||
} elsif ($ldfile->complete) {
|
||||
my $f = $ldfile;
|
||||
|
||||
$c->on(
|
||||
message => sub {
|
||||
|
@ -273,7 +268,11 @@ sub download {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
$c->send(encode_json({msg => $c->l('Your password is not valid. Please refresh the page to retry.')}));
|
||||
$c->send(decode('UTF-8', encode_json(
|
||||
{
|
||||
msg => $c->l('Your password is not valid. Please refresh the page to retry.')
|
||||
}
|
||||
)));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -286,22 +285,22 @@ sub download {
|
|||
$c->on(
|
||||
message => sub {
|
||||
my ($ws, $json) = @_;
|
||||
$c->send(encode_json(
|
||||
$c->send(decode('UTF-8', encode_json(
|
||||
{
|
||||
success => false,
|
||||
msg => $c->l('Error: the file has not been sent entirely.')
|
||||
}
|
||||
));
|
||||
)));
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$c->send(encode_json(
|
||||
$c->send(decode('UTF-8', encode_json(
|
||||
{
|
||||
success => false,
|
||||
msg => $c->l('Error: unable to find the file. Are you sure of your URL?')
|
||||
}
|
||||
));
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,13 +308,13 @@ sub r {
|
|||
my $c = shift;
|
||||
my $short = $c->param('short');
|
||||
|
||||
my @records = LufiDB::Files->select('WHERE short = ?', $short);
|
||||
if (scalar @records) {
|
||||
my $f = Lufi::File->new(record => $records[0]);
|
||||
my $ldfile = Lufi::DB::File->new(app => $c->app)->from_short($short);
|
||||
|
||||
if (defined $ldfile) {
|
||||
return $c->render(
|
||||
template => 'render',
|
||||
f => $f,
|
||||
file_pwd => ($c->config('allow_pwd_on_files') && defined($records[0]->{passwd}))
|
||||
f => $ldfile,
|
||||
file_pwd => ($c->config('allow_pwd_on_files') && defined($ldfile->passwd))
|
||||
);
|
||||
} else {
|
||||
return $c->render(
|
||||
|
@ -331,15 +330,16 @@ sub get_counter {
|
|||
my $token = $c->param('token');
|
||||
|
||||
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
|
||||
my @records = LufiDB::Files->select('WHERE short = ?', $short);
|
||||
if (scalar(@records)) {
|
||||
if ($records[0]->mod_token eq $token) {
|
||||
my $ldfile = Lufi::DB::File->new(app => $c->app)->from_short($short);
|
||||
|
||||
if (defined $ldfile) {
|
||||
if ($ldfile->mod_token eq $token) {
|
||||
return $c->render(
|
||||
json => {
|
||||
success => true,
|
||||
short => $short,
|
||||
counter => $records[0]->counter,
|
||||
deleted => ($records[0]->deleted) ? true : false
|
||||
counter => $ldfile->counter,
|
||||
deleted => ($ldfile->deleted) ? true : false
|
||||
}
|
||||
);
|
||||
} else {
|
||||
|
@ -380,14 +380,16 @@ sub delete {
|
|||
my $token = $c->param('token');
|
||||
|
||||
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
|
||||
my @records = LufiDB::Files->select('WHERE short = ? AND mod_token = ?', ($short, $token));
|
||||
if (scalar(@records)) {
|
||||
my $f = Lufi::File->new(record => $records[0]);
|
||||
my $ldfile = Lufi::DB::File->new(app => $c->app)->from_short($short);
|
||||
|
||||
$ldfile = undef unless (defined($ldfile) && $ldfile->mod_token eq $token);
|
||||
|
||||
if (defined $ldfile) {
|
||||
my $msg;
|
||||
if ($f->deleted) {
|
||||
if ($ldfile->deleted) {
|
||||
$msg = $c->l('The file has already been deleted');
|
||||
} else {
|
||||
$f->delete;
|
||||
$ldfile->delete;
|
||||
$msg = $c->l('File deleted');
|
||||
}
|
||||
return $c->respond_to(
|
||||
|
@ -400,7 +402,7 @@ sub delete {
|
|||
any => sub {
|
||||
$c->render(
|
||||
template => 'msg',
|
||||
f => $f,
|
||||
f => $ldfile,
|
||||
msg => $msg
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,22 +2,18 @@
|
|||
package Lufi::Controller::Misc;
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
use Mojo::File;
|
||||
use LufiDB;
|
||||
use Lufi::File;
|
||||
use Lufi::Slice;
|
||||
use Lufi::DB::File;
|
||||
|
||||
sub fullstats {
|
||||
my $c = shift;
|
||||
|
||||
my $files = LufiDB::Files->count('WHERE created_at IS NOT null AND deleted = 0');
|
||||
my $deleted = LufiDB::Files->count('WHERE created_at IS NOT null AND deleted = 1');
|
||||
my $empty = LufiDB::Files->count('WHERE created_at IS null');
|
||||
my $stats = Lufi::DB::File->new(app => $c->app)->get_stats;
|
||||
|
||||
return $c->render(
|
||||
json => {
|
||||
files => $files,
|
||||
deleted => $deleted,
|
||||
empty => $empty,
|
||||
files => $stats->{files},
|
||||
deleted => $stats->{deleted},
|
||||
empty => $stats->{empty},
|
||||
timestamp => time,
|
||||
}
|
||||
);
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package Lufi::DB::File;
|
||||
use Mojo::Base -base;
|
||||
use Mojo::Collection;
|
||||
|
||||
has 'short';
|
||||
has 'deleted' => 0;
|
||||
has 'mediatype';
|
||||
has 'filename';
|
||||
has 'filesize';
|
||||
has 'counter' => 0;
|
||||
has 'delete_at_first_view' => 0;
|
||||
has 'delete_at_day';
|
||||
has 'created_at' => sub {
|
||||
return time;
|
||||
};
|
||||
has 'created_by';
|
||||
has 'last_access_at';
|
||||
has 'mod_token';
|
||||
has 'nbslices';
|
||||
has 'complete' => 0;
|
||||
has 'slices' => sub {
|
||||
return Mojo::Collection->new();
|
||||
};
|
||||
has 'passwd';
|
||||
has 'app';
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Lufi::DB::File - DB abstraction layer for Lufi file
|
||||
|
||||
=head1 Contributing
|
||||
|
||||
When creating a new database accessor, make sure that it provides the following subroutines.
|
||||
After that, modify this file and modify the C<new> subroutine to allow to use your accessor.
|
||||
|
||||
Have a look at Lufi::DB::File::SQLite's code: it's simple and may be more understandable that this doc.
|
||||
|
||||
=head1 Attributes
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<short> : string
|
||||
|
||||
=item B<deleted> : boolean
|
||||
|
||||
=item B<mediatype> : string
|
||||
|
||||
=item B<filename> : string
|
||||
|
||||
=item B<filesize> : integer
|
||||
|
||||
=item B<counter> : integer
|
||||
|
||||
=item B<delete_at_first_view> : boolean
|
||||
|
||||
=item B<delete_at_day> : integer
|
||||
|
||||
=item B<created_at> : unix timestamp
|
||||
|
||||
=item B<created_by> : string
|
||||
|
||||
=item B<last_access_at> : unix timestamp
|
||||
|
||||
=item B<mod_token> : string
|
||||
|
||||
=item B<nbslices> : integer
|
||||
|
||||
=item B<complete> : boolean
|
||||
|
||||
=item B<slices> : Mojo::Collection of Lufi::DB::Slice
|
||||
|
||||
=item B<passwd> : string
|
||||
|
||||
=item B<app> : a Mojolicious object
|
||||
|
||||
=back
|
||||
|
||||
=head1 Sub routines
|
||||
|
||||
=head2 new
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c = Lufi::DB::File-E<gt>new(app =E<gt> $self);>
|
||||
|
||||
=item B<Arguments> : any of the attribute above
|
||||
|
||||
=item B<Purpose> : construct a new db accessor object. If the C<short> attribute is provided, it have to load the informations from the database.
|
||||
|
||||
=item B<Returns> : the db accessor object
|
||||
|
||||
=item B<Info> : the app argument is used by Lufi::DB::File to choose which db accessor will be used, you don't need to use it in new(), but you can use it to access helpers or configuration settings in the other subroutines
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $c = shift;
|
||||
|
||||
$c = $c->SUPER::new(@_);
|
||||
|
||||
if (ref($c) eq 'Lufi::DB::File') {
|
||||
my $dbtype = $c->app->config('dbtype');
|
||||
if ($dbtype eq 'sqlite') {
|
||||
use Lufi::DB::File::SQLite;
|
||||
$c = Lufi::DB::File::SQLite->new(@_);
|
||||
#} elsif ($dbtype eq 'postgresql') {
|
||||
#use Lufi::DB::File::Pg;
|
||||
#$c = Lufi::DB::File::Pg->new(@_);
|
||||
}
|
||||
}
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
=head2 delete
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>delet>
|
||||
|
||||
=item B<Arguments> : none
|
||||
|
||||
=item B<Purpose> : delete the files of the slices and the directory containing those files, then update the object by setting the deleted attribute to 1 (true)
|
||||
|
||||
=item B<Returns> : the db accessor object
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub delete {
|
||||
my $c = shift;
|
||||
|
||||
$c->slices->each(sub {
|
||||
my ($e, $num) = @_;
|
||||
unlink $e->path;
|
||||
});
|
||||
rmdir Mojo::File->new($c->app->config('upload_dir'), $c->short);
|
||||
$c->deleted(1);
|
||||
|
||||
$c->write;
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
=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_empty
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>count_empty>
|
||||
|
||||
=item B<Arguments> : none
|
||||
|
||||
=item B<Purpose> : count how many records have a null created_at column
|
||||
|
||||
=item B<Returns> : integer
|
||||
|
||||
=back
|
||||
|
||||
=head2 already_exists
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>already_exists($short)>
|
||||
|
||||
=item B<Arguments> : a string
|
||||
|
||||
=item B<Purpose> : check if the given string is already used as short attribute for a file
|
||||
|
||||
=item B<Returns> : 1 or 0
|
||||
|
||||
=back
|
||||
|
||||
=head2 get_empty
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>get_empty>
|
||||
|
||||
=item B<Arguments> : none
|
||||
|
||||
=item B<Purpose> : select an empty ready-to-use record from the database
|
||||
|
||||
=item B<Returns> : a db accessor object
|
||||
|
||||
=back
|
||||
|
||||
=head2 get_stats
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>get_stats>
|
||||
|
||||
=item B<Arguments> : none
|
||||
|
||||
=item B<Purpose> : get stats about how many empty files, deleted files and non-deleted files there is in the database
|
||||
|
||||
=item B<Returns> : a hash table reference containing three keys: files, deleted and empty
|
||||
|
||||
=back
|
||||
|
||||
=head2 from_short
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>from_short($short)>
|
||||
|
||||
=item B<Arguments> : string
|
||||
|
||||
=item B<Purpose> : find a file in the database from its short attribute
|
||||
|
||||
=item B<Returns> : a db accessor object
|
||||
|
||||
=back
|
||||
|
||||
=head2 get_oldest_undeleted_files
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>get_oldest_undeleted_files($num)>
|
||||
|
||||
=item B<Arguments> : integer
|
||||
|
||||
=item B<Purpose> : get the X oldest non-deleted files
|
||||
|
||||
=item B<Returns> : a Mojo::Collection of Lufi::DB::File objects
|
||||
|
||||
=back
|
||||
|
||||
=head2 get_expired
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>get_expired($time)>
|
||||
|
||||
=item B<Arguments> : unix timestamp
|
||||
|
||||
=item B<Purpose> : get the non-deleted files that are expired at the given timestamp minus 2 days
|
||||
|
||||
=item B<Returns> : a Mojo::Collection of Lufi::DB::File objects
|
||||
|
||||
=back
|
||||
|
||||
=head2 get_no_longer_viewed
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>get_no_longer_viewed($time)>
|
||||
|
||||
=item B<Arguments> : unix timestamp
|
||||
|
||||
=item B<Purpose> : get the files that have not been viewed after the given timestamp
|
||||
|
||||
=item B<Returns> : a Mojo::Collection of Lufi::DB::File objects
|
||||
|
||||
=back
|
||||
|
||||
=head2 delete_creator_before
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>delete_creator_before($time)>
|
||||
|
||||
=item B<Arguments> : unix timestamp
|
||||
|
||||
=item B<Purpose> : empty the created_by column for files created before the given timestamp
|
||||
|
||||
=item B<Returns> : nothing
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
|
@ -0,0 +1,192 @@
|
|||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package Lufi::DB::File::SQLite;
|
||||
use Mojo::Base 'Lufi::DB::File';
|
||||
use Mojo::File;
|
||||
use Mojo::Collection 'c';
|
||||
use Lufi::DB::SQLite;
|
||||
use Lufi::DB::Slice;
|
||||
|
||||
has 'record';
|
||||
|
||||
sub new {
|
||||
my $c = shift;
|
||||
|
||||
$c = $c->SUPER::new(@_);
|
||||
$c = $c->_slurp if defined $c->record;
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
sub write {
|
||||
my $c = shift;
|
||||
|
||||
if (defined $c->record) {
|
||||
$c->record->update(
|
||||
short => $c->short,
|
||||
deleted => $c->deleted,
|
||||
mediatype => $c->mediatype,
|
||||
filename => $c->filename,
|
||||
filesize => $c->filesize,
|
||||
counter => $c->counter,
|
||||
delete_at_first_view => $c->delete_at_first_view,
|
||||
delete_at_day => $c->delete_at_day,
|
||||
created_at => $c->created_at,
|
||||
created_by => $c->created_by,
|
||||
last_access_at => $c->last_access_at,
|
||||
mod_token => $c->mod_token,
|
||||
nbslices => $c->nbslices,
|
||||
complete => $c->complete,
|
||||
passwd => $c->passwd,
|
||||
);
|
||||
} else {
|
||||
my $record = Lufi::DB::SQLite::Files->create(
|
||||
short => $c->short,
|
||||
deleted => $c->deleted,
|
||||
mediatype => $c->mediatype,
|
||||
filename => $c->filename,
|
||||
filesize => $c->filesize,
|
||||
counter => $c->counter,
|
||||
delete_at_first_view => $c->delete_at_first_view,
|
||||
delete_at_day => $c->delete_at_day,
|
||||
created_at => $c->created_at,
|
||||
created_by => $c->created_by,
|
||||
last_access_at => $c->last_access_at,
|
||||
mod_token => $c->mod_token,
|
||||
nbslices => $c->nbslices,
|
||||
complete => $c->complete,
|
||||
passwd => $c->passwd,
|
||||
);
|
||||
$c->record($record);
|
||||
}
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
sub count_empty {
|
||||
my $c = shift;
|
||||
|
||||
return Lufi::DB::SQLite::Files->count('WHERE created_at IS NULL');
|
||||
}
|
||||
|
||||
sub already_exists {
|
||||
my $c = shift;
|
||||
my $short = shift;
|
||||
|
||||
return Lufi::DB::SQLite::Files->count('WHERE short = ?', $short);
|
||||
}
|
||||
|
||||
sub get_empty {
|
||||
my $c = shift;
|
||||
|
||||
my @records = Lufi::DB::SQLite::Files->select('WHERE created_at IS NULL LIMIT 1');
|
||||
$c->record($records[0]);
|
||||
$c->record->update(created_at => time);
|
||||
$c->write;
|
||||
$c->_slurp;
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
sub get_stats {
|
||||
my $c = shift;
|
||||
|
||||
my $files = Lufi::DB::SQLite::Files->count('WHERE created_at IS NOT null AND deleted = 0');
|
||||
my $deleted = Lufi::DB::SQLite::Files->count('WHERE created_at IS NOT null AND deleted = 1');
|
||||
my $empty = Lufi::DB::SQLite::Files->count('WHERE created_at IS null');
|
||||
|
||||
return {files => $files, deleted => $deleted, empty => $empty};
|
||||
}
|
||||
|
||||
sub from_short {
|
||||
my $c = shift;
|
||||
my $short = shift;
|
||||
|
||||
my @records = Lufi::DB::SQLite::Files->select('WHERE short = ?', $short);
|
||||
|
||||
if (scalar @records) {
|
||||
$c->record($records[0]);
|
||||
$c->_slurp;
|
||||
|
||||
return $c;
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
sub get_oldest_undeleted_files {
|
||||
my $c = shift;
|
||||
my $num = shift;
|
||||
|
||||
my @files = Lufi::DB::SQLite::Files->select('WHERE deleted = 0 ORDER BY created_at ASC LIMIT ?', $num);
|
||||
|
||||
return c(map { Lufi::DB::File->new(app => $c->app, record => $_) } @files);
|
||||
}
|
||||
|
||||
sub get_expired {
|
||||
my $c = shift;
|
||||
my $time = shift;
|
||||
|
||||
## Select only files expired since two days, to be sure that nobody is still downloading it
|
||||
my @files = LufiDB::Files->select('WHERE deleted = 0 AND ((delete_at_day + 2) * 86400) < (? - created_at) AND delete_at_day != 0', $time);
|
||||
|
||||
return c(map { Lufi::DB::File->new(app => $c->app, record => $_) } @files);
|
||||
}
|
||||
|
||||
sub get_no_longer_viewed {
|
||||
my $c = shift;
|
||||
my $time = shift;
|
||||
|
||||
my @files = LufiDB::Files->select('WHERE deleted = 0 AND last_access_at < ?', $time);
|
||||
|
||||
return c(map { Lufi::DB::File->new(app => $c->app, record => $_) } @files);
|
||||
}
|
||||
|
||||
sub delete_creator_before {
|
||||
my $c = shift;
|
||||
my $separation = shift;
|
||||
|
||||
Lufi::DB::SQLite->do(
|
||||
'UPDATE files SET created_by = NULL WHERE created_by IS NOT NULL AND created_at < ?',
|
||||
{},
|
||||
$separation
|
||||
);
|
||||
}
|
||||
|
||||
sub _slurp {
|
||||
my $c = shift;
|
||||
|
||||
my @files;
|
||||
if ($c->record) {
|
||||
@files = ($c->record);
|
||||
} elsif ($c->short) {
|
||||
@files = Lufi::DB::SQLite::Files->select('WHERE short = ?', $c->short);
|
||||
}
|
||||
|
||||
if (scalar @files) {
|
||||
my $file = $files[0];
|
||||
|
||||
$c->short($file->short);
|
||||
$c->deleted($file->deleted) if defined $file->deleted;
|
||||
$c->mediatype($file->mediatype) if defined $file->mediatype;
|
||||
$c->filename($file->filename) if defined $file->filename;
|
||||
$c->filesize($file->filesize) if defined $file->filesize;
|
||||
$c->counter($file->counter) if defined $file->counter;
|
||||
$c->delete_at_first_view($file->delete_at_first_view) if defined $file->delete_at_first_view;
|
||||
$c->delete_at_day($file->delete_at_day) if defined $file->delete_at_day;
|
||||
$c->created_at($file->created_at) if defined $file->created_at;
|
||||
$c->created_by($file->created_by) if defined $file->created_by;
|
||||
$c->last_access_at($file->last_access_at) if defined $file->last_access_at;
|
||||
$c->mod_token($file->mod_token) if defined $file->mod_token;
|
||||
$c->nbslices($file->nbslices) if defined $file->nbslices;
|
||||
$c->complete($file->complete) if defined $file->complete;
|
||||
$c->passwd($file->passwd) if defined $file->passwd;
|
||||
|
||||
$c->record($file) unless $c->record;
|
||||
}
|
||||
|
||||
$c->slices(Lufi::DB::Slice->new(app => $c->app)->get_slices_of_file($c->short));
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
1;
|
|
@ -1,14 +1,21 @@
|
|||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package LufiDB;
|
||||
package Lufi::DB::SQLite;
|
||||
use Mojolicious;
|
||||
use Mojo::File;
|
||||
use FindBin qw($Bin);
|
||||
use File::Spec::Functions;
|
||||
|
||||
BEGIN {
|
||||
my $m = Mojolicious->new;
|
||||
my $cfile = Mojo::File->new($Bin, '..' , 'lufi.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});
|
||||
}
|
||||
}
|
||||
our $config = $m->plugin('Config' =>
|
||||
{
|
||||
file => catfile($Bin, '..' ,'lufi.conf'),
|
||||
file => $cfile->to_abs->to_string,
|
||||
default => {
|
||||
db_path => 'lufi.db'
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package Lufi::DB::Slice;
|
||||
use Mojo::Base -base;
|
||||
|
||||
has 'short';
|
||||
has 'j';
|
||||
has 'path';
|
||||
has 'app';
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Lufi::DB::Slice - DB abstraction layer for Lufi file
|
||||
|
||||
=head1 Contributing
|
||||
|
||||
When creating a new database accessor, make sure that it provides the following subroutines.
|
||||
After that, modify this file and modify the C<new> subroutine to allow to use your accessor.
|
||||
|
||||
Have a look at Lufi::DB::Slice::SQLite's code: it's simple and may be more understandable that this doc.
|
||||
|
||||
=head1 Attributes
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<short> : string
|
||||
|
||||
=item B<j> : integer
|
||||
|
||||
=item B<path> : string
|
||||
|
||||
=item B<app> : A mojolicious object
|
||||
|
||||
=back
|
||||
|
||||
=head1 Sub routines
|
||||
|
||||
=head2 new
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c = Lufi::DB::Slice-E<gt>new(app =E<gt> $self);>
|
||||
|
||||
=item B<Arguments> : any of the attribute above
|
||||
|
||||
=item B<Purpose> : construct a new db accessor object. If the C<short> attribute is provided, it have to load the informations from the database.
|
||||
|
||||
=item B<Returns> : the db accessor object
|
||||
|
||||
=item B<Info> : the app argument is used by Lufi::DB::Slice to choose which db accessor will be used, you don't need to use it in new(), but you can use it to access helpers or configuration settings in the other subroutines
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my $c = shift;
|
||||
|
||||
$c = $c->SUPER::new(@_);
|
||||
|
||||
if (ref($c) eq 'Lufi::DB::Slice') {
|
||||
my $dbtype = $c->app->config('dbtype');
|
||||
if ($dbtype eq 'sqlite') {
|
||||
use Lufi::DB::Slice::SQLite;
|
||||
$c = Lufi::DB::Slice::SQLite->new(@_);
|
||||
#} elsif ($dbtype eq 'postgresql') {
|
||||
# use Lufi::DB::Slice::Pg;
|
||||
# $c = Lufi::DB::Slice::Pg->new(@_);
|
||||
}
|
||||
}
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
=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 get_slices_of_file
|
||||
|
||||
=over 1
|
||||
|
||||
=item B<Usage> : C<$c-E<gt>get_slices_of_file($short)>
|
||||
|
||||
=item B<Arguments> : string
|
||||
|
||||
=item B<Purpose> : get all Lufi::DB::Slice objects related to a file
|
||||
|
||||
=item B<Returns> : a Mojo::Collection of Lufi::DB::Slice objects
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
|
@ -1,12 +1,10 @@
|
|||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package Lufi::Slice;
|
||||
use Mojo::Base -base;
|
||||
use LufiDB;
|
||||
package Lufi::DB::Slice::SQLite;
|
||||
use Mojo::Base 'Lufi::DB::Slice';
|
||||
use Lufi::DB::SQLite;
|
||||
use Mojo::Collection 'c';
|
||||
|
||||
has 'record';
|
||||
has 'short';
|
||||
has 'j';
|
||||
has 'path';
|
||||
|
||||
sub new {
|
||||
my $c = shift;
|
||||
|
@ -28,7 +26,7 @@ sub write {
|
|||
path => $c->path
|
||||
);
|
||||
} else {
|
||||
my $record = LufiDB::Slices->create(
|
||||
my $record = Lufi::DB::SQLite::Slices->create(
|
||||
short => $c->short,
|
||||
j => $c->j,
|
||||
path => $c->path
|
||||
|
@ -39,6 +37,15 @@ sub write {
|
|||
return $c;
|
||||
}
|
||||
|
||||
sub get_slices_of_file {
|
||||
my $c = shift;
|
||||
my $short = shift;
|
||||
|
||||
my @slices = Lufi::DB::SQLite::Slices->select('WHERE short = ? ORDER BY j ASC', $short);
|
||||
|
||||
return c(map { Lufi::DB::Slice->new(app => $c->app, record => $_) } @slices);
|
||||
}
|
||||
|
||||
sub _slurp {
|
||||
my $c = shift;
|
||||
|
103
lib/Lufi/File.pm
103
lib/Lufi/File.pm
|
@ -1,103 +0,0 @@
|
|||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package Lufi::File;
|
||||
use Mojo::Base -base;
|
||||
use Mojo::Collection;
|
||||
use LufiDB;
|
||||
use Lufi::Slice;
|
||||
|
||||
has 'record';
|
||||
has 'short';
|
||||
has 'deleted' => 0;
|
||||
has 'mediatype';
|
||||
has 'filename';
|
||||
has 'filesize';
|
||||
has 'counter' => 0;
|
||||
has 'delete_at_first_view' => 0;
|
||||
has 'delete_at_day';
|
||||
has 'created_at' => sub {
|
||||
return time;
|
||||
};
|
||||
has 'created_by';
|
||||
has 'last_access_at';
|
||||
has 'mod_token';
|
||||
has 'nbslices';
|
||||
has 'complete' => 0;
|
||||
has 'slices' => sub {
|
||||
return Mojo::Collection->new();
|
||||
};
|
||||
has 'passwd';
|
||||
|
||||
sub new {
|
||||
my $c = shift;
|
||||
|
||||
$c = $c->SUPER::new(@_);
|
||||
|
||||
$c = $c->_slurp if defined $c->record;
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
sub write {
|
||||
my $c = shift;
|
||||
|
||||
$c->record->update(
|
||||
deleted => $c->deleted,
|
||||
mediatype => $c->mediatype,
|
||||
filename => $c->filename,
|
||||
filesize => $c->filesize,
|
||||
counter => $c->counter,
|
||||
delete_at_first_view => $c->delete_at_first_view,
|
||||
delete_at_day => $c->delete_at_day,
|
||||
created_at => $c->created_at,
|
||||
created_by => $c->created_by,
|
||||
last_access_at => $c->last_access_at,
|
||||
mod_token => $c->mod_token,
|
||||
nbslices => $c->nbslices,
|
||||
complete => $c->complete,
|
||||
passwd => $c->passwd,
|
||||
);
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
sub delete {
|
||||
my $c = shift;
|
||||
|
||||
$c->slices->each(sub {
|
||||
my ($e, $num) = @_;
|
||||
unlink $e->path;
|
||||
});
|
||||
$c->deleted(1);
|
||||
|
||||
$c->write;
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
sub _slurp {
|
||||
my $c = shift;
|
||||
|
||||
$c->short($c->record->short);
|
||||
$c->deleted($c->record->deleted) if defined $c->record->deleted;
|
||||
$c->mediatype($c->record->mediatype) if defined $c->record->mediatype;
|
||||
$c->filename($c->record->filename) if defined $c->record->filename;
|
||||
$c->filesize($c->record->filesize) if defined $c->record->filesize;
|
||||
$c->counter($c->record->counter) if defined $c->record->counter;
|
||||
$c->delete_at_first_view($c->record->delete_at_first_view) if defined $c->record->delete_at_first_view;
|
||||
$c->delete_at_day($c->record->delete_at_day) if defined $c->record->delete_at_day;
|
||||
$c->created_at($c->record->created_at) if defined $c->record->created_at;
|
||||
$c->created_by($c->record->created_by) if defined $c->record->created_by;
|
||||
$c->last_access_at($c->record->last_access_at) if defined $c->record->last_access_at;
|
||||
$c->mod_token($c->record->mod_token) if defined $c->record->mod_token;
|
||||
$c->nbslices($c->record->nbslices) if defined $c->record->nbslices;
|
||||
$c->complete($c->record->complete) if defined $c->record->complete;
|
||||
$c->passwd($c->record->passwd) if defined $c->record->passwd;
|
||||
|
||||
my @slices = LufiDB::Slices->select('WHERE short = ? ORDER BY j ASC', $c->short);
|
||||
|
||||
$c->slices(Mojo::Collection->new(map { Lufi::Slice->new(record => $_) } @slices));
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
1;
|
|
@ -1,20 +1,37 @@
|
|||
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
|
||||
package Lufi::Plugin::Helpers;
|
||||
use Mojo::Base 'Mojolicious::Plugin';
|
||||
use Lufi::DB::File;
|
||||
use Data::Entropy qw(entropy_source);
|
||||
use LufiDB;
|
||||
|
||||
sub register {
|
||||
my ($self, $app) = @_;
|
||||
|
||||
# SQLite database migration if needed
|
||||
my $columns = LufiDB::Files->table_info;
|
||||
my $pwd_col = 0;
|
||||
foreach my $col (@{$columns}) {
|
||||
$pwd_col = 1 if $col->{name} eq 'passwd';
|
||||
}
|
||||
unless ($pwd_col) {
|
||||
LufiDB->do('ALTER TABLE files ADD COLUMN passwd TEXT;');
|
||||
$app->plugin('PgURLHelper');
|
||||
#
|
||||
# if ($app->config('dbtype') eq 'postgresql') {
|
||||
# use Mojo::Pg;
|
||||
# $app->helper(pg => \&_pg);
|
||||
#
|
||||
# # Database migration
|
||||
# my $migrations = Mojo::Pg::Migrations->new(pg => $app->pg);
|
||||
# if ($app->mode eq 'development' && $ENV{LUFI_DEV} == 1) {
|
||||
# $migrations->from_file('utilities/migrations.sql')->migrate(0)->migrate(1);
|
||||
# } else {
|
||||
# $migrations->from_file('utilities/migrations.sql')->migrate(1);
|
||||
# }
|
||||
# } elsif ($app->config('dbtype') eq 'sqlite') {
|
||||
if ($app->config('dbtype') eq 'sqlite') {
|
||||
# SQLite database migration if needed
|
||||
use Lufi::DB::SQLite;
|
||||
my $columns = Lufi::DB::SQLite::Files->table_info;
|
||||
my $pwd_col = 0;
|
||||
foreach my $col (@{$columns}) {
|
||||
$pwd_col = 1 if $col->{name} eq 'passwd';
|
||||
}
|
||||
unless ($pwd_col) {
|
||||
Lufi::DB::SQLite->do('ALTER TABLE files ADD COLUMN passwd TEXT;');
|
||||
}
|
||||
}
|
||||
|
||||
$app->helper(provisioning => \&_provisioning);
|
||||
|
@ -27,23 +44,26 @@ sub register {
|
|||
$app->helper(stop_upload => \&_stop_upload);
|
||||
}
|
||||
|
||||
sub _pg {
|
||||
my $c = shift;
|
||||
|
||||
state $pg = Mojo::Pg->new($c->app->pg_url($c->app->config('pgdb')));
|
||||
return $pg;
|
||||
}
|
||||
|
||||
sub _provisioning {
|
||||
my $c = shift;
|
||||
|
||||
# Create some short patterns for provisioning
|
||||
if (LufiDB::Files->count('WHERE created_at IS NULL') < $c->config('provisioning')) {
|
||||
for (my $i = 0; $i < $c->config('provis_step'); $i++) {
|
||||
if (LufiDB->begin) {
|
||||
my $short;
|
||||
do {
|
||||
$short= $c->shortener($c->config('length'));
|
||||
} while (LufiDB::Files->count('WHERE short = ?', $short));
|
||||
my $ldfile = Lufi::DB::File->new(app => $c->app);
|
||||
if ($ldfile->count_empty < $c->app->config('provisioning')) {
|
||||
for (my $i = 0; $i < $c->app->config('provis_step'); $i++) {
|
||||
my $short;
|
||||
do {
|
||||
$short = $c->shortener($c->app->config('length'));
|
||||
} while ($ldfile->already_exists($short));
|
||||
|
||||
LufiDB::Files->create(
|
||||
short => $short
|
||||
);
|
||||
LufiDB->commit;
|
||||
}
|
||||
$ldfile->created_at(undef)->short($short)->write;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,8 +71,9 @@ sub _provisioning {
|
|||
sub _get_empty {
|
||||
my $c = shift;
|
||||
|
||||
my @records = LufiDB::Files->select('WHERE created_at IS NULL LIMIT 1');
|
||||
return $records[0];
|
||||
my $ldfile = Lufi::DB::File->new(app => $c->app)->get_empty;
|
||||
|
||||
return $ldfile;
|
||||
}
|
||||
|
||||
sub _shortener {
|
||||
|
@ -79,7 +100,7 @@ sub _ip {
|
|||
sub _default_delay {
|
||||
my $c = shift;
|
||||
|
||||
return $c->config('default_delay') if ($c->config('default_delay') >= 0);
|
||||
return $c->app->config('default_delay') if ($c->app->config('default_delay') >= 0);
|
||||
|
||||
warn "default_delay set to a negative value. Default to 0.";
|
||||
return 0;
|
||||
|
@ -88,7 +109,7 @@ sub _default_delay {
|
|||
sub _max_delay {
|
||||
my $c = shift;
|
||||
|
||||
return $c->config('max_delay') if ($c->config('max_delay') >= 0);
|
||||
return $c->app->config('max_delay') if ($c->app->config('max_delay') >= 0);
|
||||
|
||||
warn "max_delay set to a negative value. Default to 0.";
|
||||
return 0;
|
||||
|
|
|
@ -107,12 +107,28 @@
|
|||
# Optional, default to no-reply@lufi.io
|
||||
#mail_sender => 'no-reply@lufi.io',
|
||||
|
||||
# choose what database you want to use
|
||||
# valid choices are sqlite and postgresql (all lowercase)
|
||||
# optional, default is sqlite
|
||||
#dbtype => 'sqlite',
|
||||
|
||||
# SQLite ONLY - only used if dbtype is set to sqlite
|
||||
# define a path to the SQLite database
|
||||
# you can define it relative to lufi directory or set an absolute path
|
||||
# remember that it has to be in a directory writable by Lufi user
|
||||
# remember that it has to be in a directory writable by Lutim user
|
||||
# optional, default is lufi.db
|
||||
#db_path => 'lufi.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 => 'lufi',
|
||||
# host => 'localhost',
|
||||
# #user => 'DBUSER',
|
||||
# #pwd => 'DBPASSWORD'
|
||||
#},
|
||||
|
||||
# define a path to the upload directory, where the uploaded files will be stored
|
||||
# you can define it relative to lufi directory or set an absolute path
|
||||
# remember that it has to be in a directory writable by Lufi user
|
||||
|
|
|
@ -93,15 +93,15 @@ msgstr "Copia tots els enllaços al porta-retalls"
|
|||
msgid "Copy to clipboard"
|
||||
msgstr "Copia al porta-retalls"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:423
|
||||
#: lib/Lufi/Controller/Files.pm:429
|
||||
msgid "Could not delete the file. You are not authenticated."
|
||||
msgstr "No es pot esborrar el fitxer. No esteu autenticat."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:407
|
||||
#: lib/Lufi/Controller/Files.pm:411
|
||||
msgid "Could not find the file. Are you sure of the URL and the token?"
|
||||
msgstr "No es troba el fitxer. Esteu segur de la URL i el testimoni?"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:323
|
||||
#: lib/Lufi/Controller/Files.pm:322
|
||||
msgid "Could not find the file. Are you sure of the URL?"
|
||||
msgstr "No trobo el fitxer. Esteu segurs de la URL?"
|
||||
|
||||
|
@ -157,15 +157,15 @@ msgstr "correus electrònics"
|
|||
msgid "Encrypting part XX1 of XX2"
|
||||
msgstr "S'està xifrant la part XX1 de XX2"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:230
|
||||
#: lib/Lufi/Controller/Files.pm:225
|
||||
msgid "Error: the file existed but was deleted."
|
||||
msgstr "Error: el fitxer existia però va ser eliminat."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:292
|
||||
#: lib/Lufi/Controller/Files.pm:291
|
||||
msgid "Error: the file has not been sent entirely."
|
||||
msgstr "Error: el fitxer no s'ha enviat del tot."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:302
|
||||
#: lib/Lufi/Controller/Files.pm:301
|
||||
msgid "Error: unable to find the file. Are you sure of your URL?"
|
||||
msgstr "Error: no trobo el fitxer. Esteu segur de la URL ?"
|
||||
|
||||
|
@ -181,7 +181,7 @@ msgstr "Expira el"
|
|||
msgid "Export localStorage data"
|
||||
msgstr "Exporta dades a l'emmagatzematge local"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:391
|
||||
#: lib/Lufi/Controller/Files.pm:393
|
||||
msgid "File deleted"
|
||||
msgstr "Fitxer eliminat"
|
||||
|
||||
|
@ -275,7 +275,7 @@ msgid "My files"
|
|||
msgstr "Els meus fitxers"
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:70
|
||||
#: lib/Lufi/Controller/Files.pm:69
|
||||
msgid "No enough space available on the server for this file (size: %1)."
|
||||
msgstr "No hi ha prou espai al servidor per a aquest fitxer (mida: %1)"
|
||||
|
||||
|
@ -300,7 +300,7 @@ msgstr "Si us plau contacteu amb l'administrador: %1"
|
|||
msgid "Please wait while we are getting your file. We first need to download and decrypt all parts before you can get it."
|
||||
msgstr "Si us plau, espereu mentre obtenim el fitxer. Abans que el tingueu disponible primer cal descarregar i desxifrar tots els trossos."
|
||||
|
||||
#: lib/Lufi.pm:300
|
||||
#: lib/Lufi.pm:191
|
||||
msgid "Please, check your credentials: unable to authenticate."
|
||||
msgstr ""
|
||||
|
||||
|
@ -341,7 +341,7 @@ msgstr "Compartiu fitxers amb total privacitat a %1"
|
|||
msgid "Signin"
|
||||
msgstr "Autenticació"
|
||||
|
||||
#: lib/Lufi.pm:303
|
||||
#: lib/Lufi.pm:194
|
||||
msgid "Sorry mate, you are not authorised to use that service. Contact your sysadmin if you think there's a glitch in the matrix."
|
||||
msgstr ""
|
||||
|
||||
|
@ -349,7 +349,7 @@ msgstr ""
|
|||
msgid "Sorry, the uploading is currently disabled. Please try again later."
|
||||
msgstr "Disculpeu, les pujades estan actualment desactivades. Si us plau proveu-ho més tard."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:44
|
||||
#: lib/Lufi/Controller/Files.pm:43
|
||||
msgid "Sorry, uploading is disabled."
|
||||
msgstr "Disculpeu, les pujades estan deshabilitades"
|
||||
|
||||
|
@ -371,7 +371,7 @@ msgstr "El cos del correu no pot estar buit."
|
|||
msgid "The email subject can't be empty."
|
||||
msgstr "L'assumpte dle correu no pot estar buit."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:388
|
||||
#: lib/Lufi/Controller/Files.pm:390
|
||||
msgid "The file has already been deleted"
|
||||
msgstr "El fitxer ja ha estat esborrat"
|
||||
|
||||
|
@ -396,7 +396,7 @@ msgstr "El correu ja està enviat."
|
|||
msgid "The original (and only for now) author is <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. If you want to support him, you can do it via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> or via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
msgstr "L'autor original (i per ara l'únic) és <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. Si voleu fer una contribució podeu fer-ho via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> o via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:182
|
||||
#: lib/Lufi/Controller/Files.pm:179
|
||||
msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator."
|
||||
msgstr "El servidor no ha pogut trobar el registre del fitxer per afegir-hi el tros del fitxer. Si us plau, contacteu l'administrador."
|
||||
|
||||
|
@ -476,11 +476,11 @@ msgid "You must give email addresses."
|
|||
msgstr "Heu de donar l'adreça de correu electrònic."
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:57
|
||||
#: lib/Lufi/Controller/Files.pm:56
|
||||
msgid "Your file is too big: %1 (maximum size allowed: %2)"
|
||||
msgstr "El fitxer és massa gran: %1 (mida màxima admesa: %2)"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:276
|
||||
#: lib/Lufi/Controller/Files.pm:273
|
||||
msgid "Your password is not valid. Please refresh the page to retry."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -90,15 +90,15 @@ msgstr ""
|
|||
msgid "Copy to clipboard"
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:423
|
||||
#: lib/Lufi/Controller/Files.pm:429
|
||||
msgid "Could not delete the file. You are not authenticated."
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:407
|
||||
#: lib/Lufi/Controller/Files.pm:411
|
||||
msgid "Could not find the file. Are you sure of the URL and the token?"
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:323
|
||||
#: lib/Lufi/Controller/Files.pm:322
|
||||
msgid "Could not find the file. Are you sure of the URL?"
|
||||
msgstr ""
|
||||
|
||||
|
@ -154,15 +154,15 @@ msgstr ""
|
|||
msgid "Encrypting part XX1 of XX2"
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:230
|
||||
#: lib/Lufi/Controller/Files.pm:225
|
||||
msgid "Error: the file existed but was deleted."
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:292
|
||||
#: lib/Lufi/Controller/Files.pm:291
|
||||
msgid "Error: the file has not been sent entirely."
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:302
|
||||
#: lib/Lufi/Controller/Files.pm:301
|
||||
msgid "Error: unable to find the file. Are you sure of your URL?"
|
||||
msgstr ""
|
||||
|
||||
|
@ -178,7 +178,7 @@ msgstr ""
|
|||
msgid "Export localStorage data"
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:391
|
||||
#: lib/Lufi/Controller/Files.pm:393
|
||||
msgid "File deleted"
|
||||
msgstr ""
|
||||
|
||||
|
@ -271,7 +271,7 @@ msgid "My files"
|
|||
msgstr ""
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:70
|
||||
#: lib/Lufi/Controller/Files.pm:69
|
||||
msgid "No enough space available on the server for this file (size: %1)."
|
||||
msgstr ""
|
||||
|
||||
|
@ -296,7 +296,7 @@ msgstr ""
|
|||
msgid "Please wait while we are getting your file. We first need to download and decrypt all parts before you can get it."
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi.pm:300
|
||||
#: lib/Lufi.pm:191
|
||||
msgid "Please, check your credentials: unable to authenticate."
|
||||
msgstr ""
|
||||
|
||||
|
@ -337,7 +337,7 @@ msgstr ""
|
|||
msgid "Signin"
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi.pm:303
|
||||
#: lib/Lufi.pm:194
|
||||
msgid "Sorry mate, you are not authorised to use that service. Contact your sysadmin if you think there's a glitch in the matrix."
|
||||
msgstr ""
|
||||
|
||||
|
@ -345,7 +345,7 @@ msgstr ""
|
|||
msgid "Sorry, the uploading is currently disabled. Please try again later."
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:44
|
||||
#: lib/Lufi/Controller/Files.pm:43
|
||||
msgid "Sorry, uploading is disabled."
|
||||
msgstr ""
|
||||
|
||||
|
@ -365,7 +365,7 @@ msgstr ""
|
|||
msgid "The email subject can't be empty."
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:388
|
||||
#: lib/Lufi/Controller/Files.pm:390
|
||||
msgid "The file has already been deleted"
|
||||
msgstr ""
|
||||
|
||||
|
@ -390,7 +390,7 @@ msgstr ""
|
|||
msgid "The original (and only for now) author is <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. If you want to support him, you can do it via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> or via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:182
|
||||
#: lib/Lufi/Controller/Files.pm:179
|
||||
msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator."
|
||||
msgstr ""
|
||||
|
||||
|
@ -470,11 +470,11 @@ msgid "You must give email addresses."
|
|||
msgstr ""
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:57
|
||||
#: lib/Lufi/Controller/Files.pm:56
|
||||
msgid "Your file is too big: %1 (maximum size allowed: %2)"
|
||||
msgstr ""
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:276
|
||||
#: lib/Lufi/Controller/Files.pm:273
|
||||
msgid "Your password is not valid. Please refresh the page to retry."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -92,15 +92,15 @@ msgstr "Copier tous les liens dans le presse-papier"
|
|||
msgid "Copy to clipboard"
|
||||
msgstr "Copier dans le presse-papier"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:423
|
||||
#: lib/Lufi/Controller/Files.pm:429
|
||||
msgid "Could not delete the file. You are not authenticated."
|
||||
msgstr "Impossible de supprimer le fichier. Vous n’êtes pas connecté·e."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:407
|
||||
#: lib/Lufi/Controller/Files.pm:411
|
||||
msgid "Could not find the file. Are you sure of the URL and the token?"
|
||||
msgstr "Impossible de retrouver le fichier. Êtes-vous sûr(e) que l’URL et le jeton sont les bons ?"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:323
|
||||
#: lib/Lufi/Controller/Files.pm:322
|
||||
msgid "Could not find the file. Are you sure of the URL?"
|
||||
msgstr "Impossible de retrouver le fichier. Êtes-vous sûr(e) que l’URL est la bonne ?"
|
||||
|
||||
|
@ -156,15 +156,15 @@ msgstr "Mails"
|
|||
msgid "Encrypting part XX1 of XX2"
|
||||
msgstr "Chiffrement du fragment XX1 sur XX2"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:230
|
||||
#: lib/Lufi/Controller/Files.pm:225
|
||||
msgid "Error: the file existed but was deleted."
|
||||
msgstr "Erreur : le fichier existait mais a été supprimé"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:292
|
||||
#: lib/Lufi/Controller/Files.pm:291
|
||||
msgid "Error: the file has not been sent entirely."
|
||||
msgstr "Erreur : le fichier n’a pas été envoyé dans son intégralité"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:302
|
||||
#: lib/Lufi/Controller/Files.pm:301
|
||||
msgid "Error: unable to find the file. Are you sure of your URL?"
|
||||
msgstr "Erreur : impossible de retrouver le fichier. Êtes-vous sûr(e) de l’URL ?"
|
||||
|
||||
|
@ -180,7 +180,7 @@ msgstr "Expire le"
|
|||
msgid "Export localStorage data"
|
||||
msgstr "Exporter les données localStorage"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:391
|
||||
#: lib/Lufi/Controller/Files.pm:393
|
||||
msgid "File deleted"
|
||||
msgstr "Fichier supprimé"
|
||||
|
||||
|
@ -273,7 +273,7 @@ msgid "My files"
|
|||
msgstr "Mes fichiers"
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:70
|
||||
#: lib/Lufi/Controller/Files.pm:69
|
||||
msgid "No enough space available on the server for this file (size: %1)."
|
||||
msgstr "Espace disque insuffisant sur le serveur pour ce fichier (taille du fichier : %1)."
|
||||
|
||||
|
@ -298,7 +298,7 @@ msgstr "Veuillez contacter l’administrateur : %1"
|
|||
msgid "Please wait while we are getting your file. We first need to download and decrypt all parts before you can get it."
|
||||
msgstr "Veuillez patientez pendant la récupération de votre fichier. Nous devons d’abord récupérer et déchiffrer tous les fragments avant que vous puissiez le télécharger."
|
||||
|
||||
#: lib/Lufi.pm:300
|
||||
#: lib/Lufi.pm:191
|
||||
msgid "Please, check your credentials: unable to authenticate."
|
||||
msgstr "Veuillez vérifier vos identifiants : impossible de vous authentifier."
|
||||
|
||||
|
@ -339,7 +339,7 @@ msgstr "Partagez vos fichiers en toute confidentialité sur %1"
|
|||
msgid "Signin"
|
||||
msgstr "Connexion"
|
||||
|
||||
#: lib/Lufi.pm:303
|
||||
#: lib/Lufi.pm:194
|
||||
msgid "Sorry mate, you are not authorised to use that service. Contact your sysadmin if you think there's a glitch in the matrix."
|
||||
msgstr "Désolé, vous n’êtes pas autorisé à utiliser ce service. Contactez votre administrateur si vous pensez qu’il s’agit d’une erreur."
|
||||
|
||||
|
@ -347,7 +347,7 @@ msgstr "Désolé, vous n’êtes pas autorisé à utiliser ce service. Contactez
|
|||
msgid "Sorry, the uploading is currently disabled. Please try again later."
|
||||
msgstr "Désolé, l’envoi de fichier est actuellement désactivé. Veuillez réessayer plus tard."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:44
|
||||
#: lib/Lufi/Controller/Files.pm:43
|
||||
msgid "Sorry, uploading is disabled."
|
||||
msgstr "Désolé, l’envoi de fichier est désactivé."
|
||||
|
||||
|
@ -367,7 +367,7 @@ msgstr "Le corps du mail ne peut être vide."
|
|||
msgid "The email subject can't be empty."
|
||||
msgstr "Le sujet du mail ne peut être vide."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:388
|
||||
#: lib/Lufi/Controller/Files.pm:390
|
||||
msgid "The file has already been deleted"
|
||||
msgstr "Le fichier a déjà été supprimé"
|
||||
|
||||
|
@ -392,7 +392,7 @@ msgstr "Le mail a été envoyé."
|
|||
msgid "The original (and only for now) author is <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. If you want to support him, you can do it via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> or via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
msgstr "L’auteur originel (et pour l’instant, le seul) est <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. Si vous avez envie de le supporter, vous pouvez le faire via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> ou via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:182
|
||||
#: lib/Lufi/Controller/Files.pm:179
|
||||
msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator."
|
||||
msgstr "Le serveur a été incapable de retrouver l’enregistrement du fichier auquel ajouter votre fragment de fichier. Veuillez contacter l’administrateur."
|
||||
|
||||
|
@ -472,11 +472,11 @@ msgid "You must give email addresses."
|
|||
msgstr "Vous devez envoyer des adresses mail."
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:57
|
||||
#: lib/Lufi/Controller/Files.pm:56
|
||||
msgid "Your file is too big: %1 (maximum size allowed: %2)"
|
||||
msgstr "Votre fichier est trop volumineux : %1 (la taille maximum autorisée est %2)"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:276
|
||||
#: lib/Lufi/Controller/Files.pm:273
|
||||
msgid "Your password is not valid. Please refresh the page to retry."
|
||||
msgstr "Votre mot de passe est invalide. Veuillez rafraîchir la page pour réessayer."
|
||||
|
||||
|
|
|
@ -92,15 +92,15 @@ msgstr "Copiare tutti i link negli appunti"
|
|||
msgid "Copy to clipboard"
|
||||
msgstr "Copiare negli appunti"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:423
|
||||
#: lib/Lufi/Controller/Files.pm:429
|
||||
msgid "Could not delete the file. You are not authenticated."
|
||||
msgstr "Impossibile cancellare il file. Non siete autenticati."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:407
|
||||
#: lib/Lufi/Controller/Files.pm:411
|
||||
msgid "Could not find the file. Are you sure of the URL and the token?"
|
||||
msgstr "Impossibile trovare il file. Sei sicuro che URL e token siano corretti ?"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:323
|
||||
#: lib/Lufi/Controller/Files.pm:322
|
||||
msgid "Could not find the file. Are you sure of the URL?"
|
||||
msgstr "Impossibile trovare il file. Sei sicuro che l'URL sia corretto?"
|
||||
|
||||
|
@ -156,15 +156,15 @@ msgstr "Email"
|
|||
msgid "Encrypting part XX1 of XX2"
|
||||
msgstr "Cifratura della parte XX1 di XX2"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:230
|
||||
#: lib/Lufi/Controller/Files.pm:225
|
||||
msgid "Error: the file existed but was deleted."
|
||||
msgstr "Errore: il file esisteva ma è stato eliminato"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:292
|
||||
#: lib/Lufi/Controller/Files.pm:291
|
||||
msgid "Error: the file has not been sent entirely."
|
||||
msgstr "Errore: il file non è stato inviato completamente"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:302
|
||||
#: lib/Lufi/Controller/Files.pm:301
|
||||
msgid "Error: unable to find the file. Are you sure of your URL?"
|
||||
msgstr "Errore: impossibile trovare il file. Sei certo dell'URL ?"
|
||||
|
||||
|
@ -180,7 +180,7 @@ msgstr "Scade il"
|
|||
msgid "Export localStorage data"
|
||||
msgstr "Esportare i dati del localStorage"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:391
|
||||
#: lib/Lufi/Controller/Files.pm:393
|
||||
msgid "File deleted"
|
||||
msgstr "File cancellato"
|
||||
|
||||
|
@ -273,7 +273,7 @@ msgid "My files"
|
|||
msgstr "I miei file"
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:70
|
||||
#: lib/Lufi/Controller/Files.pm:69
|
||||
msgid "No enough space available on the server for this file (size: %1)."
|
||||
msgstr "Spazio disco insufficiente sul server per questo file (dimensione: %1)."
|
||||
|
||||
|
@ -298,7 +298,7 @@ msgstr "Contattare l'amministratore : %1"
|
|||
msgid "Please wait while we are getting your file. We first need to download and decrypt all parts before you can get it."
|
||||
msgstr "Attendere mentre otteniamo il vostro file. Dobbiamo prima scaricare e decifrare tutte le parti prima che possiate averlo."
|
||||
|
||||
#: lib/Lufi.pm:300
|
||||
#: lib/Lufi.pm:191
|
||||
msgid "Please, check your credentials: unable to authenticate."
|
||||
msgstr ""
|
||||
|
||||
|
@ -339,7 +339,7 @@ msgstr "Condividi tutti i file in totale riservatezza su %1"
|
|||
msgid "Signin"
|
||||
msgstr "Autenticazione"
|
||||
|
||||
#: lib/Lufi.pm:303
|
||||
#: lib/Lufi.pm:194
|
||||
msgid "Sorry mate, you are not authorised to use that service. Contact your sysadmin if you think there's a glitch in the matrix."
|
||||
msgstr ""
|
||||
|
||||
|
@ -347,7 +347,7 @@ msgstr ""
|
|||
msgid "Sorry, the uploading is currently disabled. Please try again later."
|
||||
msgstr "L'invio del file è attualemente disattivato. Riprovare più tardi."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:44
|
||||
#: lib/Lufi/Controller/Files.pm:43
|
||||
msgid "Sorry, uploading is disabled."
|
||||
msgstr "L'invio del file è attualemente disattivato."
|
||||
|
||||
|
@ -367,7 +367,7 @@ msgstr "Il corpo dell'email non può essere vuoto."
|
|||
msgid "The email subject can't be empty."
|
||||
msgstr "Il soggetto dell'email non può essere vuoto."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:388
|
||||
#: lib/Lufi/Controller/Files.pm:390
|
||||
msgid "The file has already been deleted"
|
||||
msgstr "Il file è già stato cancellato"
|
||||
|
||||
|
@ -392,7 +392,7 @@ msgstr "Email inviata."
|
|||
msgid "The original (and only for now) author is <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. If you want to support him, you can do it via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> or via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
msgstr "L'autore ( e per ora l'unico) è <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. Se aveste voglia di aiutarlo, potreste farlo tramite <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> ou via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:182
|
||||
#: lib/Lufi/Controller/Files.pm:179
|
||||
msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator."
|
||||
msgstr "Il server non è stato in grado di trovare il file record a cui aggiungere la vostra porzione di file. Prego contattare l'amministratore."
|
||||
|
||||
|
@ -472,11 +472,11 @@ msgid "You must give email addresses."
|
|||
msgstr "Devi fornire gli indirizzi email."
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:57
|
||||
#: lib/Lufi/Controller/Files.pm:56
|
||||
msgid "Your file is too big: %1 (maximum size allowed: %2)"
|
||||
msgstr "Il vostro file è troppo grande : %1 (la dimensione massima permessa è %2)"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:276
|
||||
#: lib/Lufi/Controller/Files.pm:273
|
||||
msgid "Your password is not valid. Please refresh the page to retry."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -79,15 +79,15 @@ msgstr "Kopieer alle links naar klembord"
|
|||
msgid "Copy to clipboard"
|
||||
msgstr "Kopieer naar klembord"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:423
|
||||
#: lib/Lufi/Controller/Files.pm:429
|
||||
msgid "Could not delete the file. You are not authenticated."
|
||||
msgstr "Kan het bestand niet verwijderen. Je bent niet geautoriseerd."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:407
|
||||
#: lib/Lufi/Controller/Files.pm:411
|
||||
msgid "Could not find the file. Are you sure of the URL and the token?"
|
||||
msgstr "Kan het bestand niet vinden. Klopt de URL en token wel?"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:323
|
||||
#: lib/Lufi/Controller/Files.pm:322
|
||||
msgid "Could not find the file. Are you sure of the URL?"
|
||||
msgstr "Kan het bestand niet vinden. Klopt de URL?"
|
||||
|
||||
|
@ -143,15 +143,15 @@ msgstr "Emails"
|
|||
msgid "Encrypting part XX1 of XX2"
|
||||
msgstr "Encrypten deel XX1 van XX2 "
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:230
|
||||
#: lib/Lufi/Controller/Files.pm:225
|
||||
msgid "Error: the file existed but was deleted."
|
||||
msgstr "Fout: het bestand bestond wel maar is verwijderd."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:292
|
||||
#: lib/Lufi/Controller/Files.pm:291
|
||||
msgid "Error: the file has not been sent entirely."
|
||||
msgstr "Fout: het bestand is niet volledig opgestuurd."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:302
|
||||
#: lib/Lufi/Controller/Files.pm:301
|
||||
msgid "Error: unable to find the file. Are you sure of your URL?"
|
||||
msgstr "Fout: kan het bestand niet vinden. Is de URL juist?"
|
||||
|
||||
|
@ -167,7 +167,7 @@ msgstr "Vervalt op"
|
|||
msgid "Export localStorage data"
|
||||
msgstr "Exporteer opgeslagen data"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:391
|
||||
#: lib/Lufi/Controller/Files.pm:393
|
||||
msgid "File deleted"
|
||||
msgstr "Bestand verwijderd"
|
||||
|
||||
|
@ -260,7 +260,7 @@ msgid "My files"
|
|||
msgstr "Mijn bestanden"
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:70
|
||||
#: lib/Lufi/Controller/Files.pm:69
|
||||
msgid "No enough space available on the server for this file (size: %1)."
|
||||
msgstr "Geen genoeg ruimte op de server voor deze bestand (grootte: %1)."
|
||||
|
||||
|
@ -285,7 +285,7 @@ msgstr "Neem contact op met administrator: %1"
|
|||
msgid "Please wait while we are getting your file. We first need to download and decrypt all parts before you can get it."
|
||||
msgstr "Een ogenblik geduld, we pakken je bestand er bij. We moeten alle delen downloaden en decrypten voordat je het kan downloaden."
|
||||
|
||||
#: lib/Lufi.pm:300
|
||||
#: lib/Lufi.pm:191
|
||||
msgid "Please, check your credentials: unable to authenticate."
|
||||
msgstr ""
|
||||
|
||||
|
@ -330,7 +330,7 @@ msgstr "Deel je bestanden met volledige privacy op %1"
|
|||
msgid "Signin"
|
||||
msgstr "Inloggen"
|
||||
|
||||
#: lib/Lufi.pm:303
|
||||
#: lib/Lufi.pm:194
|
||||
msgid "Sorry mate, you are not authorised to use that service. Contact your sysadmin if you think there's a glitch in the matrix."
|
||||
msgstr ""
|
||||
|
||||
|
@ -338,7 +338,7 @@ msgstr ""
|
|||
msgid "Sorry, the uploading is currently disabled. Please try again later."
|
||||
msgstr "Sorry, uploaden is momenteel uitgeschakeld. Probeer het later nogmaals."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:44
|
||||
#: lib/Lufi/Controller/Files.pm:43
|
||||
msgid "Sorry, uploading is disabled."
|
||||
msgstr "SOrry, uploaden is uitgeschakeld."
|
||||
|
||||
|
@ -358,7 +358,7 @@ msgstr "Mail inhoud kan niet leeg zijn."
|
|||
msgid "The email subject can't be empty."
|
||||
msgstr "Onderwerp kan niet leeg zijn."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:388
|
||||
#: lib/Lufi/Controller/Files.pm:390
|
||||
msgid "The file has already been deleted"
|
||||
msgstr "Bestand is reeds verwijderd"
|
||||
|
||||
|
@ -383,7 +383,7 @@ msgstr "Email is verzonden."
|
|||
msgid "The original (and only for now) author is <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. If you want to support him, you can do it via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> or via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
msgstr "De oorspronkelijke auteur is <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. Als je hem wilt ondersteunen, dan kan dat via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> of via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:182
|
||||
#: lib/Lufi/Controller/Files.pm:179
|
||||
msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator."
|
||||
msgstr "Server kon een deel van het bestand niet vinden. Neem contact op met beheerder."
|
||||
|
||||
|
@ -463,11 +463,11 @@ msgid "You must give email addresses."
|
|||
msgstr "Je moet een mail adres opgeven."
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:57
|
||||
#: lib/Lufi/Controller/Files.pm:56
|
||||
msgid "Your file is too big: %1 (maximum size allowed: %2)"
|
||||
msgstr "Je bestand is te groot: %1 (max: %2)"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:276
|
||||
#: lib/Lufi/Controller/Files.pm:273
|
||||
msgid "Your password is not valid. Please refresh the page to retry."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -92,15 +92,15 @@ msgstr "Copiar totes los ligams dins lo quichapapièrs"
|
|||
msgid "Copy to clipboard"
|
||||
msgstr "Copiar dins lo quichapapièrs"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:423
|
||||
#: lib/Lufi/Controller/Files.pm:429
|
||||
msgid "Could not delete the file. You are not authenticated."
|
||||
msgstr "Impossible de suprimir lo fichièr. Sètz pas connectat-ada."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:407
|
||||
#: lib/Lufi/Controller/Files.pm:411
|
||||
msgid "Could not find the file. Are you sure of the URL and the token?"
|
||||
msgstr "Impossible de trobar lo fichièr. Sètz segur-a que l’URL e lo geton son bons ?"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:323
|
||||
#: lib/Lufi/Controller/Files.pm:322
|
||||
msgid "Could not find the file. Are you sure of the URL?"
|
||||
msgstr "Impossible de trobar lo fichièr. Sètz segur-a que l’URL es bona ?"
|
||||
|
||||
|
@ -156,15 +156,15 @@ msgstr "Corrièl"
|
|||
msgid "Encrypting part XX1 of XX2"
|
||||
msgstr "Chiframent del tròç XX1 sus XX2"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:230
|
||||
#: lib/Lufi/Controller/Files.pm:225
|
||||
msgid "Error: the file existed but was deleted."
|
||||
msgstr "Error : lo fichièr existissiá mas es estat suprimit"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:292
|
||||
#: lib/Lufi/Controller/Files.pm:291
|
||||
msgid "Error: the file has not been sent entirely."
|
||||
msgstr "Error : lo fichièr es pas estat mandat completament"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:302
|
||||
#: lib/Lufi/Controller/Files.pm:301
|
||||
msgid "Error: unable to find the file. Are you sure of your URL?"
|
||||
msgstr "Error : impossible de trobar lo fichièr. Sètz segur-a de l’URL ?"
|
||||
|
||||
|
@ -180,7 +180,7 @@ msgstr "Expira lo"
|
|||
msgid "Export localStorage data"
|
||||
msgstr "Exportar las donadas localStorage"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:391
|
||||
#: lib/Lufi/Controller/Files.pm:393
|
||||
msgid "File deleted"
|
||||
msgstr "Fichièr suprimit"
|
||||
|
||||
|
@ -273,7 +273,7 @@ msgid "My files"
|
|||
msgstr "Mos fichièrs"
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:70
|
||||
#: lib/Lufi/Controller/Files.pm:69
|
||||
msgid "No enough space available on the server for this file (size: %1)."
|
||||
msgstr "Espaci disc insufisent sul servidor per aqueste fichièr (talha del fichièr : \"%1)."
|
||||
|
||||
|
@ -298,7 +298,7 @@ msgstr "Mercés de contactar l’administrator : %1"
|
|||
msgid "Please wait while we are getting your file. We first need to download and decrypt all parts before you can get it."
|
||||
msgstr "Mercés d’esperar pendent la recuperacion de vòstre fichièr. Nos cal d’en primièr recuperar e deschifrar totes los fragaments abans que poscatz o telecargar."
|
||||
|
||||
#: lib/Lufi.pm:300
|
||||
#: lib/Lufi.pm:191
|
||||
msgid "Please, check your credentials: unable to authenticate."
|
||||
msgstr ""
|
||||
|
||||
|
@ -339,7 +339,7 @@ msgstr "Partejatz vòstres fichièrs en tota confidencialitat sus %1"
|
|||
msgid "Signin"
|
||||
msgstr "Connexion"
|
||||
|
||||
#: lib/Lufi.pm:303
|
||||
#: lib/Lufi.pm:194
|
||||
msgid "Sorry mate, you are not authorised to use that service. Contact your sysadmin if you think there's a glitch in the matrix."
|
||||
msgstr ""
|
||||
|
||||
|
@ -347,7 +347,7 @@ msgstr ""
|
|||
msgid "Sorry, the uploading is currently disabled. Please try again later."
|
||||
msgstr "O planhèm, la foncion per mandar de fichièr es desactivada pel moment. Mercés de tornar ensajar mai tard."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:44
|
||||
#: lib/Lufi/Controller/Files.pm:43
|
||||
msgid "Sorry, uploading is disabled."
|
||||
msgstr "O planhèm, la foncion per mandar de fichièr es desactivada."
|
||||
|
||||
|
@ -367,7 +367,7 @@ msgstr "Lo contengut del corrièl pòt pas èsser void."
|
|||
msgid "The email subject can't be empty."
|
||||
msgstr "Lo sujècte del corrièl pòt pas èsser void."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:388
|
||||
#: lib/Lufi/Controller/Files.pm:390
|
||||
msgid "The file has already been deleted"
|
||||
msgstr "Lo fichièr es ja estat suprimit"
|
||||
|
||||
|
@ -392,7 +392,7 @@ msgstr "Lo corrièl es estat mandat."
|
|||
msgid "The original (and only for now) author is <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. If you want to support him, you can do it via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> or via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
msgstr "L’autor original (e pel moment, lo sol) es <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. S’avètz enveja de lo sostenir, podètz o far via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> o via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:182
|
||||
#: lib/Lufi/Controller/Files.pm:179
|
||||
msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator."
|
||||
msgstr "Lo servidor es pas estat capable de retrobar l’enregistrament del fichièr que li cal ajustar vòstre tròç de fichièr. Mercés de contactar l’administrator."
|
||||
|
||||
|
@ -472,11 +472,11 @@ msgid "You must give email addresses."
|
|||
msgstr "Vos cal donar d’adreças."
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:57
|
||||
#: lib/Lufi/Controller/Files.pm:56
|
||||
msgid "Your file is too big: %1 (maximum size allowed: %2)"
|
||||
msgstr "Vòstre fichièr es tròp voluminós : %1 (la talha maximum autorizada es %2)"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:276
|
||||
#: lib/Lufi/Controller/Files.pm:273
|
||||
msgid "Your password is not valid. Please refresh the page to retry."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -93,15 +93,15 @@ msgstr "Copiar todos os links para a área de transferência"
|
|||
msgid "Copy to clipboard"
|
||||
msgstr "Copiar para a área de transferência"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:423
|
||||
#: lib/Lufi/Controller/Files.pm:429
|
||||
msgid "Could not delete the file. You are not authenticated."
|
||||
msgstr "Impossível apagar o ficheiro. Não está conectado."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:407
|
||||
#: lib/Lufi/Controller/Files.pm:411
|
||||
msgid "Could not find the file. Are you sure of the URL and the token?"
|
||||
msgstr "Impossível encontrar o ficheiro.Tem a certeza que o URL e os símbolos estão corretos?"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:323
|
||||
#: lib/Lufi/Controller/Files.pm:322
|
||||
msgid "Could not find the file. Are you sure of the URL?"
|
||||
msgstr "Impossível encontar o ficheiro. Tem a certeza de que o URL está correto?"
|
||||
|
||||
|
@ -161,15 +161,15 @@ msgstr "E-mails"
|
|||
msgid "Encrypting part XX1 of XX2"
|
||||
msgstr "Codificação do fragmento XX1 de XX2"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:230
|
||||
#: lib/Lufi/Controller/Files.pm:225
|
||||
msgid "Error: the file existed but was deleted."
|
||||
msgstr "Erro: o ficheiro existia mas foi apagado."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:292
|
||||
#: lib/Lufi/Controller/Files.pm:291
|
||||
msgid "Error: the file has not been sent entirely."
|
||||
msgstr "Erro: o ficheiro não foi enviado na totalidade."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:302
|
||||
#: lib/Lufi/Controller/Files.pm:301
|
||||
msgid "Error: unable to find the file. Are you sure of your URL?"
|
||||
msgstr "Erro: impossível encontrar o ficheiro. Tem a certeza do URL?"
|
||||
|
||||
|
@ -185,7 +185,7 @@ msgstr "Expira no"
|
|||
msgid "Export localStorage data"
|
||||
msgstr "Exportar os dados localStorage"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:391
|
||||
#: lib/Lufi/Controller/Files.pm:393
|
||||
msgid "File deleted"
|
||||
msgstr "Ficheiro apagado"
|
||||
|
||||
|
@ -282,7 +282,7 @@ msgid "My files"
|
|||
msgstr "Meus ficheiros"
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:70
|
||||
#: lib/Lufi/Controller/Files.pm:69
|
||||
msgid "No enough space available on the server for this file (size: %1)."
|
||||
msgstr "O servidor não tem espaço suficiente para este ficheiro (tamanho: %1)."
|
||||
|
||||
|
@ -307,7 +307,7 @@ msgstr "Contacte o administrador: %1"
|
|||
msgid "Please wait while we are getting your file. We first need to download and decrypt all parts before you can get it."
|
||||
msgstr "Por favor aguarde durante a recuperação do seu ficheiro. Primeiro devemos recuperar e descodificar todos os fragmentos e depois poderá descarregar o ficheiro."
|
||||
|
||||
#: lib/Lufi.pm:300
|
||||
#: lib/Lufi.pm:191
|
||||
msgid "Please, check your credentials: unable to authenticate."
|
||||
msgstr ""
|
||||
|
||||
|
@ -348,7 +348,7 @@ msgstr "Partilhe os seus ficheiros com toda a privacidade em %1"
|
|||
msgid "Signin"
|
||||
msgstr "Conexão"
|
||||
|
||||
#: lib/Lufi.pm:303
|
||||
#: lib/Lufi.pm:194
|
||||
msgid "Sorry mate, you are not authorised to use that service. Contact your sysadmin if you think there's a glitch in the matrix."
|
||||
msgstr ""
|
||||
|
||||
|
@ -356,7 +356,7 @@ msgstr ""
|
|||
msgid "Sorry, the uploading is currently disabled. Please try again later."
|
||||
msgstr "Desculpe, o envio do ficheiro está atualmente desativado. Tente mais tarde."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:44
|
||||
#: lib/Lufi/Controller/Files.pm:43
|
||||
msgid "Sorry, uploading is disabled."
|
||||
msgstr "Desculpe, o envio do ficheiro está desativado."
|
||||
|
||||
|
@ -376,7 +376,7 @@ msgstr "A mensagem do e-mail não pode estar vazia."
|
|||
msgid "The email subject can't be empty."
|
||||
msgstr "O assunto do e-mail não pode estar vazio."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:388
|
||||
#: lib/Lufi/Controller/Files.pm:390
|
||||
msgid "The file has already been deleted"
|
||||
msgstr "O ficheiro já foi apagado"
|
||||
|
||||
|
@ -401,7 +401,7 @@ msgstr "O e-mail foi enviado."
|
|||
msgid "The original (and only for now) author is <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. If you want to support him, you can do it via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> or via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
msgstr "O autor original (e por agora, o único) é <a href=\"https://fiat-tux.fr\" class=\"classic\">Luc Didry</a>. Se o desejar apoiar pode fazer-lo via <a href=\"https://www.tipeee.com/fiat-tux\" class=\"classic\">Tipeee</a> ou via <a href=\"https://liberapay.com/sky/\" class=\"classic\">Liberapay</a>."
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:182
|
||||
#: lib/Lufi/Controller/Files.pm:179
|
||||
msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator."
|
||||
msgstr "O servidor foi incapaz de encontrar o registo do ficheiro no qual devia-se juntar o fragmento do seu ficheiro. Contacte o administrador."
|
||||
|
||||
|
@ -485,11 +485,11 @@ msgid "You must give email addresses."
|
|||
msgstr "Deve escrever os e-mails."
|
||||
|
||||
#. (format_bytes($json->{size})
|
||||
#: lib/Lufi/Controller/Files.pm:57
|
||||
#: lib/Lufi/Controller/Files.pm:56
|
||||
msgid "Your file is too big: %1 (maximum size allowed: %2)"
|
||||
msgstr "O seu ficheiro é grande de mais: %1 (o tamanho máximo autorizado é de %2)"
|
||||
|
||||
#: lib/Lufi/Controller/Files.pm:276
|
||||
#: lib/Lufi/Controller/Files.pm:273
|
||||
msgid "Your password is not valid. Please refresh the page to retry."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -106,6 +106,10 @@ function spawnWebsocket(pa) {
|
|||
innerHTML.push('<video class="responsive-video" controls>',
|
||||
'<source src="', blobURL, '" type="', data.type, '">',
|
||||
'</video>');
|
||||
} else if (data.type.match(/^audio\//) !== null) {
|
||||
innerHTML.push('<audio class="responsive-video" controls>',
|
||||
'<source src="', blobURL, '" type="', data.type, '">',
|
||||
'</audio>');
|
||||
}
|
||||
pbd.html(innerHTML.join(''));
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
-- 1 up
|
||||
CREATE TABLE IF NOT EXISTS files (
|
||||
short text PRIMARY KEY,
|
||||
deleted boolean default false,
|
||||
mediatype text,
|
||||
filename text,
|
||||
filesize integer,
|
||||
counter integer default 0,
|
||||
delete_at_first_view boolean,
|
||||
delete_at_day integer,
|
||||
created_at integer,
|
||||
created_by text,
|
||||
last_access_at integer,
|
||||
mod_token text,
|
||||
nbslices integer,
|
||||
complete boolean default false,
|
||||
passwd text
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS slices (
|
||||
short text REFERENCES files(short) ON DELETE CASCADE,
|
||||
j integer NOT NULL,
|
||||
path text unique NOT NULL,
|
||||
);
|
||||
-- 1 down
|
||||
DROP TABLE slices;
|
||||
DROP TABLE files;
|
Loading…
Reference in New Issue