Verified Commit 25ab7e64 authored by Luc Didry's avatar Luc Didry

Fix #78 - Allow to block files by setting an abuse field in DB

parent b6188097
......@@ -5,6 +5,7 @@ Revision history for Lufi
- Use FiatTux plugins
- Option to force "Burn after reading" for each uploaded file
- Use GzipStatic and StaticCache plugins for speed
- Allow to block files by setting an abuse field in DB
0.02.2 2017-09-18
- Fix cron tasks bug
......
......@@ -10,7 +10,6 @@ $ENV{MOJO_MAX_WEBSOCKET_SIZE} = 100485760; # 10 * 1024 * 1024 = 10MiB
# This method will run once at server start
sub startup {
my $self = shift;
my $entry;
my $config = $self->plugin('Config' => {
default => {
......@@ -112,65 +111,34 @@ sub startup {
my $r = $self->routes;
# Page for files uploading
$r->get('/' => sub {
my $c = shift;
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
$c->render(template => 'index');
} else {
$c->redirect_to('login');
}
})->name('index');
$r->get('/')
->to('Misc#index')
->name('index');
if (defined $self->config('ldap') || defined $self->config('htpasswd')) {
# Login page
$r->get('/login' => sub {
my $c = shift;
if ($c->is_user_authenticated) {
$c->redirect_to('index');
} else {
$c->render(template => 'login');
}
});
$r->get('/login')
->to('Auth#login_page');
# Authentication
$r->post('/login' => sub {
my $c = shift;
my $login = $c->param('login');
my $pwd = $c->param('password');
if($c->authenticate($login, $pwd)) {
$c->redirect_to('index');
} elsif (defined $entry) {
$c->stash(msg => $c->l('Please, check your credentials: unable to authenticate.'));
$c->render(template => 'login');
} else {
$c->stash(msg => $c->l('Sorry mate, you are not authorised to use that service. Contact your sysadmin if you think there\'s a glitch in the matrix.'));
$c->render(template => 'login');
}
});
$r->post('/login')
->to('Auth#login');
# Logout page
$r->get('/logout' => sub {
my $c = shift;
if ($c->is_user_authenticated) {
$c->logout;
}
$c->render(template => 'logout');
})->name('logout');
$r->get('/logout')
->to('Auth#logout')
->name('logout');
}
# About page
$r->get('/about' => sub {
shift->render(template => 'about');
})->name('about');
$r->get('/about')
->to('Misc#about')
->name('about');
# Generated js files
$r->get('/partial/:file' => sub {
my $c = shift;
$c->render(
template => 'partial/'.$c->param('file'),
format => 'js',
layout => undef,
);
})->name('partial');
$r->get('/partial/:file')
->to('Misc#js_files')
->name('partial');
# Get instance stats
$r->get('/fullstats')
......@@ -178,58 +146,48 @@ sub startup {
->name('fullstats');
# Get a file
$r->get('/r/:short')->
to('Files#r')->
name('render');
$r->get('/r/:short')
->to('Files#r')
->name('render');
# List of files (use localstorage, so the server know nothing about files)
$r->get('/files' => sub {
my $c = shift;
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
$c->render(template => 'files');
} else {
$c->redirect_to('login');
}
})->name('files');
$r->get('/files')
->to('Files#files')
->name('files');
# Get counter informations about a file
$r->post('/c')->
to('Files#get_counter')->
name('counter');
$r->post('/c')
->to('Files#get_counter')
->name('counter');
# Get counter informations about a file
$r->get('/d/:short/:token')->
to('Files#delete')->
name('delete');
$r->get('/d/:short/:token')
->to('Files#delete')
->name('delete');
# Get some informations about delays
$r->get('/delays' => sub {
shift->render(template => 'delays');
})->name('delays');
$r->get('/delays')
->to('Misc#delays')
->name('delays');
# Get mail page
$r->get('/m')->
to('Mail#render_mail')->
name('mail');
$r->get('/m')
->to('Mail#render_mail')
->name('mail');
# Submit mail
$r->post('/m')->
to('Mail#send_mail');
# About page
$r->get('/about' => sub {
shift->render(template => 'about');
})->name('about');
$r->post('/m')
->to('Mail#send_mail');
# Upload files websocket
$r->websocket('/upload')->
to('Files#upload')->
name('upload');
$r->websocket('/upload')
->to('Files#upload')
->name('upload');
# Get files websocket
$r->websocket('/download/:short')->
to('Files#download')->
name('download');
$r->websocket('/download/:short')
->to('Files#download')
->name('download');
}
1;
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::Controller::Auth;
use Mojo::Base 'Mojolicious::Controller';
sub login_page {
my $c = shift;
if ($c->is_user_authenticated) {
$c->redirect_to('index');
} else {
$c->render(template => 'login');
}
}
sub login {
my $c = shift;
my $login = $c->param('login');
my $pwd = $c->param('password');
if($c->authenticate($login, $pwd)) {
$c->redirect_to('index');
} else {
$c->stash(msg => $c->l('Please, check your credentials or your right to access this service: unable to authenticate.'));
$c->render(template => 'login');
}
}
sub logout {
my $c = shift;
if ($c->is_user_authenticated) {
$c->logout;
}
$c->render(template => 'logout');
}
1;
......@@ -11,6 +11,16 @@ use Number::Bytes::Human qw(format_bytes);
use Filesys::DfPortable;
use Crypt::SaltedHash;
sub files {
my $c = shift;
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
$c->render(template => 'files');
} else {
$c->redirect_to('login');
}
}
sub upload {
my $c = shift;
......@@ -229,6 +239,20 @@ sub download {
)));
}
);
} elsif (defined($ldfile->abuse)) {
my $abuse_msg = $c->l('This file has been deactivated by the admins. Contact them to know why.');
$abuse_msg = $c->app->config('abuse')->{$ldfile->abuse} if ($c->app->config('abuse') && $c->app->config('abuse')->{$ldfile->abuse});
$c->on(
message => sub {
my ($ws, $json) = @_;
$c->send(decode('UTF-8', encode_json(
{
success => false,
msg => $abuse_msg
}
)));
}
);
} elsif ($ldfile->complete) {
my $f = $ldfile;
......
......@@ -4,6 +4,30 @@ use Mojo::Base 'Mojolicious::Controller';
use Mojo::File;
use Lufi::DB::File;
sub index {
my $c = shift;
if ((!defined($c->config('ldap')) && !defined($c->config('htpasswd'))) || $c->is_user_authenticated) {
$c->render(template => 'index');
} else {
$c->redirect_to('login');
}
}
sub about {
shift->render(template => 'about');
}
sub js_files {
my $c = shift;
$c->stash($c->req->params->to_hash);
$c->render(
template => 'partial/'.$c->param('file'),
format => 'js',
layout => undef,
);
}
sub fullstats {
my $c = shift;
......@@ -19,4 +43,8 @@ sub fullstats {
);
}
sub delays {
shift->render(template => 'delays');
}
1;
......@@ -25,6 +25,7 @@ has 'slices' => sub {
return Mojo::Collection->new();
};
has 'passwd';
has 'abuse';
has 'record' => 0;
has 'app';
......@@ -75,6 +76,8 @@ Have a look at Lufi::DB::File::SQLite's code: it's simple and may be more unders
=item B<passwd> : string
=item B<abuse> : integer
=item B<app> : a Mojolicious object
=back
......@@ -169,9 +172,9 @@ sub write {
my $c = shift;
if ($c->record) {
$c->app->dbi->db->query('UPDATE files SET short = ?, deleted = ?, mediatype = ?, filename = ?, filesize = ?, counter = ?, delete_at_first_view = ?, delete_at_day = ?, created_at = ?, created_by = ?, last_access_at = ?, mod_token = ?, nbslices = ?, complete = ?, passwd = ? WHERE short = ?', $c->short, $c->deleted, $c->mediatype, $c->filename, $c->filesize, $c->counter, $c->delete_at_first_view, $c->delete_at_day, $c->created_at, $c->created_by, $c->last_access_at, $c->mod_token, $c->nbslices, $c->complete, $c->passwd, $c->short);
$c->app->dbi->db->query('UPDATE files SET short = ?, deleted = ?, mediatype = ?, filename = ?, filesize = ?, counter = ?, delete_at_first_view = ?, delete_at_day = ?, created_at = ?, created_by = ?, last_access_at = ?, mod_token = ?, nbslices = ?, complete = ?, passwd = ?, abuse = ? WHERE short = ?', $c->short, $c->deleted, $c->mediatype, $c->filename, $c->filesize, $c->counter, $c->delete_at_first_view, $c->delete_at_day, $c->created_at, $c->created_by, $c->last_access_at, $c->mod_token, $c->nbslices, $c->complete, $c->passwd, $c->abuse, $c->short);
} else {
$c->app->dbi->db->query('INSERT INTO files (short, deleted, mediatype, filename, filesize, counter, delete_at_first_view, delete_at_day, created_at, created_by, last_access_at, mod_token, nbslices, complete, passwd) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', $c->short, $c->deleted, $c->mediatype, $c->filename, $c->filesize, $c->counter, $c->delete_at_first_view, $c->delete_at_day, $c->created_at, $c->created_by, $c->last_access_at, $c->mod_token, $c->nbslices, $c->complete, $c->passwd);
$c->app->dbi->db->query('INSERT INTO files (short, deleted, mediatype, filename, filesize, counter, delete_at_first_view, delete_at_day, created_at, created_by, last_access_at, mod_token, nbslices, complete, passwd, abuse) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', $c->short, $c->deleted, $c->mediatype, $c->filename, $c->filesize, $c->counter, $c->delete_at_first_view, $c->delete_at_day, $c->created_at, $c->created_by, $c->last_access_at, $c->mod_token, $c->nbslices, $c->complete, $c->passwd, $c->abuse);
$c->record(1);
}
......@@ -475,6 +478,7 @@ sub _slurp {
$c->nbslices($file->{nbslices});
$c->complete($file->{complete});
$c->passwd($file->{passwd});
$c->abuse($file->{abuse});
$c->record(1) unless $c->record;
}
......
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::DB::File::SQLite;
use Mojo::Base 'Lufi::DB::File';
use Mojo::Collection 'c';
sub new {
my $c = shift;
......
......@@ -20,9 +20,9 @@ sub register {
# Database migration
my $migrations = Mojo::Pg::Migrations->new(pg => $app->dbi);
if ($app->mode eq 'development' && $ENV{LUFI_DEV}) {
$migrations->from_file('utilities/migrations/pg.sql')->migrate(0)->migrate(1);
$migrations->from_file('utilities/migrations/pg.sql')->migrate(0)->migrate(2);
} else {
$migrations->from_file('utilities/migrations/pg.sql')->migrate(1);
$migrations->from_file('utilities/migrations/pg.sql')->migrate(2);
}
} elsif ($app->config('dbtype') eq 'sqlite') {
require Mojo::SQLite;
......@@ -33,14 +33,19 @@ sub register {
my $sql = $app->dbi;
my $migrations = $sql->migrations;
if ($app->mode eq 'development' && $ENV{LUFI_DEV}) {
$migrations->from_file('utilities/migrations/sqlite.sql')->migrate(0)->migrate(1);
$migrations->from_file('utilities/migrations/sqlite.sql')->migrate(0)->migrate(2);
} else {
$migrations->from_file('utilities/migrations/sqlite.sql')->migrate(1);
$migrations->from_file('utilities/migrations/sqlite.sql')->migrate(2);
}
# Check if passwd column is missing
my $columns = $app->dbi->db->query('PRAGMA table_info(files)')->hashes;
if ($columns->size == 14) { # Missing passwd column
$app->dbi->db->query('ALTER TABLE files ADD COLUMN passwd TEXT');
}
my $pwd_col = 0;
$columns->each(sub {
my ($e, $num) = @_;
$pwd_col = 1 if $e->{name} eq 'passwd';
});
$app->dbi->db->query('ALTER TABLE files ADD COLUMN passwd TEXT') unless $pwd_col;
}
$app->helper(provisioning => \&_provisioning);
......
......@@ -172,9 +172,18 @@
#force_burn_after_reading => 0,
# if set, the files' URLs will always use this domain
# optional
# optional, no default
#fixed_domain => 'example.org',
# abuse reasons
# set an integer in the abuse field of a file in the database and it will not be downloadable anymore
# the reason will be displayed to the downloader, according to the reasons you will configure here.
# optional, no default
#abuse => {
# 0 => 'Copyright infringment',
# 1 => 'Illegal content',
#},
#########################
# Lufi cron jobs settings
#########################
......
......@@ -56,7 +56,7 @@ msgstr ""
msgid "As Lufi is a free software licensed under of the terms of the <a href=\"https://gnu.org/licenses/agpl.html\" class=\"classic\">AGPLv3</a>, you can install it on you own server. Have a look on the <a href=\"https://framagit.org/luc/lufi/wikis/home\" class=\"classic\">Wiki</a> for the procedure."
msgstr "Com que Lufi és programari lliure, autoritzat sota els termes de l'<a href=\"https://gnu.org/licenses/agpl.html\" class=\"classic\">AGPLv3</a>, el podeu instal·lar al vostre propi servidor. Pel que fa a com fer-ho, feu un cop d'ull al <a href=\"https://framagit.org/luc/lufi/wikis/home\" class=\"classic\">Wiki</a>."
#. (stash('f')
#. (stash('nbslices')
#: themes/default/templates/partial/render.js.ep:9
msgid "Asking for file part XX1 of %1"
msgstr "Demanem la part XX1 de %1 del fitxer"
......@@ -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:431
#: lib/Lufi/Controller/Files.pm:455
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:413
#: lib/Lufi/Controller/Files.pm:437
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:324
#: lib/Lufi/Controller/Files.pm:348
msgid "Could not find the file. Are you sure of the URL?"
msgstr "No trobo el fitxer. Esteu segurs de la URL?"
......@@ -161,15 +161,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:227
#: lib/Lufi/Controller/Files.pm:237
msgid "Error: the file existed but was deleted."
msgstr "Error: el fitxer existia però va ser eliminat."
#: lib/Lufi/Controller/Files.pm:293
#: lib/Lufi/Controller/Files.pm:317
msgid "Error: the file has not been sent entirely."
msgstr "Error: el fitxer no s'ha enviat del tot."
#: lib/Lufi/Controller/Files.pm:303
#: lib/Lufi/Controller/Files.pm:327
msgid "Error: unable to find the file. Are you sure of your URL?"
msgstr "Error: no trobo el fitxer. Esteu segur de la URL ?"
......@@ -185,7 +185,7 @@ msgstr "Expira el"
msgid "Export localStorage data"
msgstr "Exporta dades a l'emmagatzematge local"
#: lib/Lufi/Controller/Files.pm:395
#: lib/Lufi/Controller/Files.pm:419
msgid "File deleted"
msgstr "Fitxer eliminat"
......@@ -283,7 +283,7 @@ msgid "My files"
msgstr "Els meus fitxers"
#. (format_bytes($json->{size})
#: lib/Lufi/Controller/Files.pm:69
#: lib/Lufi/Controller/Files.pm:79
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)"
......@@ -308,8 +308,8 @@ 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:143
msgid "Please, check your credentials: unable to authenticate."
#: lib/Lufi/Controller/Auth.pm:24
msgid "Please, check your credentials or your right to access this service: unable to authenticate."
msgstr ""
#: themes/default/templates/about.html.ep:5
......@@ -349,15 +349,11 @@ msgstr "Compartiu fitxers amb total privacitat a %1"
msgid "Signin"
msgstr "Autenticació"
#: lib/Lufi.pm:146
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 ""
#: themes/default/templates/index.html.ep:30
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:43
#: lib/Lufi/Controller/Files.pm:53
msgid "Sorry, uploading is disabled."
msgstr "Disculpeu, les pujades estan deshabilitades"
......@@ -379,7 +375,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:392
#: lib/Lufi/Controller/Files.pm:416
msgid "The file has already been deleted"
msgstr "El fitxer ja ha estat esborrat"
......@@ -404,10 +400,14 @@ 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:181
#: lib/Lufi/Controller/Files.pm:191
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."
#: lib/Lufi/Controller/Files.pm:243
msgid "This file has been deactivated by the admins. Contact them to know why."
msgstr ""
#: themes/default/templates/delays.html.ep:10
msgid "This server sets limitations according to the file size. The expiration delay of your file will be the minimum between what you choose and the following limitations:"
msgstr "Aquest servidor estableix limitacions segons la mida del fitxer. La moratòria d'expiració del fitxer serà el mínim de l'escollida i aquestes limitacions:"
......@@ -417,17 +417,17 @@ msgid "Unable to copy the link(s) to your clipboard"
msgstr "No s'han pogut copiar l'enllaç o els enllaços al porta-retalls."
#. ($short)
#: lib/Lufi/Controller/Files.pm:363
#: lib/Lufi/Controller/Files.pm:387
msgid "Unable to get counter for %1. The file does not exists. It will be removed from your localStorage."
msgstr "No he pogut obtenir el comptador de %1. El fitxer no existeix. Serà eliminat del teu emmagatzematge local."
#. ($short)
#: lib/Lufi/Controller/Files.pm:353
#: lib/Lufi/Controller/Files.pm:377
msgid "Unable to get counter for %1. The token is invalid."
msgstr "No he pogut obtenir el comptador de %1. El testimoni no és vàlid."
#. ($short)
#: lib/Lufi/Controller/Files.pm:373
#: lib/Lufi/Controller/Files.pm:397
msgid "Unable to get counter for %1. You are not authenticated."
msgstr "No he pogut obtenir el comptador de %1. No esteu autenticat."
......@@ -484,11 +484,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:56
#: lib/Lufi/Controller/Files.pm:66
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:275
#: lib/Lufi/Controller/Files.pm:299
msgid "Your password is not valid. Please refresh the page to retry."
msgstr ""
......
......@@ -53,7 +53,7 @@ msgstr ""
msgid "As Lufi is a free software licensed under of the terms of the <a href=\"https://gnu.org/licenses/agpl.html\" class=\"classic\">AGPLv3</a>, you can install it on you own server. Have a look on the <a href=\"https://framagit.org/luc/lufi/wikis/home\" class=\"classic\">Wiki</a> for the procedure."
msgstr ""
#. (stash('f')
#. (stash('nbslices')
#: themes/default/templates/partial/render.js.ep:9
msgid "Asking for file part XX1 of %1"
msgstr ""
......@@ -90,15 +90,15 @@ msgstr ""
msgid "Copy to clipboard"
msgstr ""
#: lib/Lufi/Controller/Files.pm:431
#: lib/Lufi/Controller/Files.pm:455
msgid "Could not delete the file. You are not authenticated."
msgstr ""
#: lib/Lufi/Controller/Files.pm:413
#: lib/Lufi/Controller/Files.pm:437
msgid "Could not find the file. Are you sure of the URL and the token?"
msgstr ""
#: lib/Lufi/Controller/Files.pm:324
#: lib/Lufi/Controller/Files.pm:348
msgid "Could not find the file. Are you sure of the URL?"
msgstr ""
......@@ -158,15 +158,15 @@ msgstr ""
msgid "Encrypting part XX1 of XX2"
msgstr ""
#: lib/Lufi/Controller/Files.pm:227
#: lib/Lufi/Controller/Files.pm:237
msgid "Error: the file existed but was deleted."
msgstr ""
#: lib/Lufi/Controller/Files.pm:293
#: lib/Lufi/Controller/Files.pm:317
msgid "Error: the file has not been sent entirely."
msgstr ""
#: lib/Lufi/Controller/Files.pm:303
#: lib/Lufi/Controller/Files.pm:327
msgid "Error: unable to find the file. Are you sure of your URL?"
msgstr ""
......@@ -182,7 +182,7 @@ msgstr ""
msgid "Export localStorage data"
msgstr ""
#: lib/Lufi/Controller/Files.pm:395
#: lib/Lufi/Controller/Files.pm:419
msgid "File deleted"
msgstr ""
......@@ -279,7 +279,7 @@ msgid "My files"
msgstr ""
#. (format_bytes($json->{size})
#: lib/Lufi/Controller/Files.pm:69
#: lib/Lufi/Controller/Files.pm:79
msgid "No enough space available on the server for this file (size: %1)."
msgstr ""
......@@ -304,8 +304,8 @@ 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:143
msgid "Please, check your credentials: unable to authenticate."
#: lib/Lufi/Controller/Auth.pm:24
msgid "Please, check your credentials or your right to access this service: unable to authenticate."
msgstr ""
#: themes/default/templates/about.html.ep:5
......@@ -345,15 +345,11 @@ msgstr ""
msgid "Signin"
msgstr ""
#: lib/Lufi.pm:146
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 ""
#: themes/default/templates/index.html.ep:30
msgid "Sorry, the uploading is currently disabled. Please try again later."
msgstr ""
#: lib/Lufi/Controller/Files.pm:43
#: lib/Lufi/Controller/Files.pm:53
msgid "Sorry, uploading is disabled."
msgstr ""
......@@ -373,7 +369,7 @@ msgstr ""
msgid "The email subject can't be empty."
msgstr ""
#: lib/Lufi/Controller/Files.pm:392
#: lib/Lufi/Controller/Files.pm:416
msgid "The file has already been deleted"
msgstr ""
......@@ -398,10 +394,14 @@ 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:181
#: lib/Lufi/Controller/Files.pm:191
msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator."
msgstr ""
#: lib/Lufi/Controller/Files.pm:243
msgid "This file has been deactivated by the admins. Contact them to know why."
msgstr ""
#: themes/default/templates/delays.html.ep:10
msgid "This server sets limitations according to the file size. The expiration delay of your file will be the minimum between what you choose and the following limitations:"
msgstr ""
......@@ -411,17 +411,17 @@ msgid "Unable to copy the link(s) to your clipboard"
msgstr ""
#. ($short)
#: lib/Lufi/Controller/Files.pm:363
#: lib/Lufi/Controller/Files.pm:387
msgid "Unable to get counter for %1. The file does not exists. It will be removed from your localStorage."
msgstr ""
#. ($short)
#: lib/Lufi/Controller/Files.pm:353
#: lib/Lufi/Controller/Files.pm:377
msgid "Unable to get counter for %1. The token is invalid."
msgstr ""
#. ($short)
#: lib/Lufi/Controller/Files.pm:373
#: lib/Lufi/Controller/Files.pm:397
msgid "Unable to get counter for %1. You are not authenticated."
msgstr ""
......@@ -478,11 +478,11 @@ msgid "You must give email addresses."
msgstr ""
#. (format_bytes($json->{size})
#: lib/Lufi/Controller/Files.pm:56
#: lib/Lufi/Controller/Files.pm:66
msgid "Your file is too big: %1 (maximum size allowed: %2)"
msgstr ""
#: lib/Lufi/Controller/Files.pm:275
#: lib/Lufi/Controller/Files.pm:299
msgid "Your password is not valid. Please refresh the page to retry."
msgstr ""
......
......@@ -55,7 +55,7 @@ msgstr "Ajouter un mot de passe au(x) fichier(s)"
msgid "As Lufi is a free software licensed under of the terms of the <a href=\"https://gnu.org/licenses/agpl.html\" class=\"classic\">AGPLv3</a>, you can install it on you own server. Have a look on the <a href=\"https://framagit.org/luc/lufi/wikis/home\" class=\"classic\">Wiki</a> for the procedure."
msgstr "Comme Lufi est un logiciel libre soumis aux termes de la license <a href=\"https://gnu.org/licenses/agpl.html\" class=\"classic\">AGPLv3</a>, vous pouvez l’installer sur votre propre serveur. Veuillez consulter le <a href=\"https://framagit.org/luc/lufi/wikis/home\" class=\"classic\">Wiki</a> pour voir la procédure."
#. (stash('f')
#. (stash('nbslices')
#: themes/default/templates/partial/render.js.ep:9
msgid "Asking for file part XX1 of %1"
msgstr "Demande de récupération du fragment de fichier XX1 sur %1"
......@@ -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:431
#: lib/Lufi/Controller/Files.pm:455
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:413
#: lib/Lufi/Controller/Files.pm:437
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:324
#: lib/Lufi/Controller/Files.pm:348
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 ?"
......@@ -160,15 +160,15 @@ msgstr "Mails"
msgid "Encrypting part XX1 of XX2"
msgstr "Chiffrement du fragment XX1 sur XX2"
#: lib/Lufi/Controller/Files.pm:227
#: lib/Lufi/Controller/Files.pm:237
msgid "Error: the file existed but was deleted."
msgstr "Erreur : le fichier existait mais a été supprimé"
#: lib/Lufi/Controller/Files.pm:293
#: lib/Lufi/Controller/Files.pm:317
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:303
#: lib/Lufi/Controller/Files.pm:327
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 ?"
......@@ -184,7 +184,7 @@ msgstr "Expire le"
msgid "Export localStorage data"
msgstr "Exporter les données localStorage"