From b3c6a28c732e6bf24744744462afc651eed17951 Mon Sep 17 00:00:00 2001 From: s7b4 Date: Sat, 11 Nov 2017 23:06:08 +0100 Subject: [PATCH 01/49] use MOJO_CONFIG variable in Mounter.pm --- lib/Mounter.pm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/Mounter.pm b/lib/Mounter.pm index 8575d8b..dce85a0 100644 --- a/lib/Mounter.pm +++ b/lib/Mounter.pm @@ -9,9 +9,16 @@ sub startup { push @{$self->commands->namespaces}, 'Lufi::Command'; + 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 = $self->plugin('Config' => { - file => File::Spec->catfile($Bin, '..' ,'lufi.conf'), + file => $cfile, default => { prefix => '/', theme => 'default', From 1c5c76f172e6cc444ac6d4ae5e5cbf809a015aa9 Mon Sep 17 00:00:00 2001 From: s7b4 Date: Sun, 12 Nov 2017 20:05:31 +0100 Subject: [PATCH 02/49] Add me to AUTHORS.md --- AUTHORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.md b/AUTHORS.md index 6fa6d7a..4ae6796 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -14,3 +14,4 @@ * Yann Le Brech (htpasswd file support) * Jéssica Da Cunha (portuguese translation) * Ilker Kulgu (fix IE11 compatibility, Dutch translation) +* Stéphane Baron (bugfix) From a2a578cdfebf38933ecf8cf6c2946f286ca039b5 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Mon, 27 Nov 2017 19:03:37 +0100 Subject: [PATCH 03/49] Fix #103 Add a fixed_domain option This commit is dedicated to Schoumi, who is supporting me on Tipeee. Many thanks :-) --- lufi.conf.template | 6 ++++- themes/default/lib/Lufi/I18N/ca.po | 34 +++++++++++++------------- themes/default/lib/Lufi/I18N/en.po | 34 +++++++++++++------------- themes/default/lib/Lufi/I18N/fr.po | 34 +++++++++++++------------- themes/default/lib/Lufi/I18N/it.po | 34 +++++++++++++------------- themes/default/lib/Lufi/I18N/nl.po | 34 +++++++++++++------------- themes/default/lib/Lufi/I18N/oc.po | 34 +++++++++++++------------- themes/default/lib/Lufi/I18N/pt.po | 34 +++++++++++++------------- themes/default/public/js/lufi-files.js | 4 +-- themes/default/public/js/lufi-up.js | 8 +++--- themes/default/templates/files.html.ep | 7 +++++- themes/default/templates/index.html.ep | 5 ++++ 12 files changed, 141 insertions(+), 127 deletions(-) diff --git a/lufi.conf.template b/lufi.conf.template index ac0b7f2..64df2be 100644 --- a/lufi.conf.template +++ b/lufi.conf.template @@ -10,7 +10,7 @@ # if you use Lufi behind a reverse proxy like Nginx, you want ro set proxy to 1 # if you use Lufi directly, let it commented #proxy => 1, - + # Please read http://mojolicious.org/perldoc/Mojo/Server/Hypnotoad#workers # to adjust this to your server workers => 30, @@ -161,6 +161,10 @@ # optional, default to 0 #allow_pwd_on_files => 0, + # if set, the files' URLs will always use this domain + # optional + #fixed_domain => 'example.org', + ######################### # Lufi cron jobs settings ######################### diff --git a/themes/default/lib/Lufi/I18N/ca.po b/themes/default/lib/Lufi/I18N/ca.po index 85ff22c..87c102e 100644 --- a/themes/default/lib/Lufi/I18N/ca.po +++ b/themes/default/lib/Lufi/I18N/ca.po @@ -85,11 +85,11 @@ msgstr "Tanca" msgid "Comma-separated email addresses" msgstr "Adreces de correu electrònic separades per comes" -#: themes/default/templates/index.html.ep:100 +#: themes/default/templates/index.html.ep:105 msgid "Copy all links to clipboard" msgstr "Copia tots els enllaços al porta-retalls" -#: themes/default/templates/index.html.ep:103 +#: themes/default/templates/index.html.ep:108 msgid "Copy to clipboard" msgstr "Copia al porta-retalls" @@ -117,7 +117,7 @@ msgstr "Eliminar-lo a la primera descàrrega?" msgid "Delete selected files" msgstr "" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:104 +#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 msgid "Deletion link" msgstr "Enllaç per a eliminació" @@ -125,7 +125,7 @@ msgstr "Enllaç per a eliminació" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "No patiu per si un usuari comença a descarregar el fitxer abans de l'expiració i la descàrrega acaba després de l'expiració, encara podrà obtenir el fitxer." -#: themes/default/templates/index.html.ep:106 themes/default/templates/render.html.ep:28 +#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Descàrrega" @@ -133,7 +133,7 @@ msgstr "Descàrrega" msgid "Download aborted." msgstr "Descàrrega avortada." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:105 +#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 msgid "Download link" msgstr "Enllaç per a descàrrega" @@ -157,7 +157,7 @@ msgstr "Assumpte del correu electrònic" msgid "Emails" msgstr "correus electrònics" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/index.html.ep:112 msgid "Encrypting part XX1 of XX2" msgstr "S'està xifrant la part XX1 de XX2" @@ -173,7 +173,7 @@ msgstr "Error: el fitxer no s'ha enviat del tot." msgid "Error: unable to find the file. Are you sure of your URL?" msgstr "Error: no trobo el fitxer. Esteu segur de la URL ?" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/index.html.ep:113 msgid "Expiration:" msgstr "Expiració:" @@ -209,11 +209,11 @@ msgstr "Hola,\\n\\nVe't aquí uns fitxers que vull compartir amb tu:" msgid "Here's some files" msgstr "Ve't aquí uns fitxers" -#: themes/default/templates/index.html.ep:110 +#: themes/default/templates/index.html.ep:115 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Prem Retorn, i després Ctrl+C per copiar tots els enllaços de descàrrega" -#: themes/default/templates/index.html.ep:109 +#: themes/default/templates/index.html.ep:114 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Prem Retorn, i després Ctrl+C per copiar l'enllaç de descàrrega" @@ -283,7 +283,7 @@ msgstr "Els meus fitxers" 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)" -#: themes/default/templates/files.html.ep:45 themes/default/templates/index.html.ep:112 +#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 msgid "No expiration delay" msgstr "Sense moratòria d'expiració" @@ -320,7 +320,7 @@ msgstr "Netegeu els fitxers expirats de l'emmagatzematge local." msgid "Rows in red mean that the files have expired and are no longer available." msgstr "Les files en vermell indiquen que els fitxers han expirat i ja no són disponibles." -#: themes/default/templates/index.html.ep:111 +#: themes/default/templates/index.html.ep:116 msgid "Send all links by email" msgstr "Envia tots els enllaços per correu electrònic" @@ -332,7 +332,7 @@ msgstr "Envia amb aquest servidor" msgid "Send with your own mail software" msgstr "Envia amb el vostre propi programa de correu" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/index.html.ep:118 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "S'està enviant el tros XX1 de XX2. Si us plau, paciència; la barra de progrés pot trigar una mica a bellugar-se. " @@ -363,7 +363,7 @@ msgstr "" "L'administrador només pot veure el nom del fitxer, la seva mida i el seu\n" "mimetype (quina mena de fitxer és: vídeo, text, etc.)" -#: themes/default/templates/files.html.ep:46 +#: themes/default/templates/files.html.ep:51 msgid "The data has been successfully imported." msgstr "La importació de les dades ha reeixit." @@ -388,7 +388,7 @@ msgstr "Els fitxers que es pugen a una instaŀlació de Lufi són xifrats abans msgid "The following email addresses are not valid: %1" msgstr "Les següents adreces de correu electrònic no són vàlides: %1" -#: themes/default/templates/index.html.ep:101 +#: themes/default/templates/index.html.ep:106 msgid "The link(s) has been copied to your clipboard" msgstr "L'enllaç/ els enllaços ja estan copiats al portaretalls" @@ -408,7 +408,7 @@ msgstr "El servidor no ha pogut trobar el registre del fitxer per afegir-hi el t 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:" -#: themes/default/templates/index.html.ep:102 +#: themes/default/templates/index.html.ep:107 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." @@ -439,7 +439,7 @@ msgstr "Pujat a les" msgid "Uploaded files" msgstr "Fitxers pujats" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/index.html.ep:119 msgid "Websocket communication error" msgstr "Error de comunicacions del websocket" @@ -467,7 +467,7 @@ msgstr "No sembla que hi hagi una clau a la URL. No podreu desxifrar el fitxer. msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Heu intentat deixar aquesta pàgina. Es canceŀlarà la descàrrega. N'esteu segur?" -#: themes/default/templates/index.html.ep:99 +#: themes/default/templates/index.html.ep:104 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Heu intentat deixar aquesta pàgina. Es canceŀlarà la pujada. N'esteu segur?" diff --git a/themes/default/lib/Lufi/I18N/en.po b/themes/default/lib/Lufi/I18N/en.po index f1f284c..f79e4fb 100644 --- a/themes/default/lib/Lufi/I18N/en.po +++ b/themes/default/lib/Lufi/I18N/en.po @@ -82,11 +82,11 @@ msgstr "" msgid "Comma-separated email addresses" msgstr "" -#: themes/default/templates/index.html.ep:100 +#: themes/default/templates/index.html.ep:105 msgid "Copy all links to clipboard" msgstr "" -#: themes/default/templates/index.html.ep:103 +#: themes/default/templates/index.html.ep:108 msgid "Copy to clipboard" msgstr "" @@ -114,7 +114,7 @@ msgstr "" msgid "Delete selected files" msgstr "" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:104 +#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 msgid "Deletion link" msgstr "" @@ -122,7 +122,7 @@ msgstr "" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "" -#: themes/default/templates/index.html.ep:106 themes/default/templates/render.html.ep:28 +#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "" @@ -130,7 +130,7 @@ msgstr "" msgid "Download aborted." msgstr "" -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:105 +#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 msgid "Download link" msgstr "" @@ -154,7 +154,7 @@ msgstr "" msgid "Emails" msgstr "" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/index.html.ep:112 msgid "Encrypting part XX1 of XX2" msgstr "" @@ -170,7 +170,7 @@ msgstr "" msgid "Error: unable to find the file. Are you sure of your URL?" msgstr "" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/index.html.ep:113 msgid "Expiration:" msgstr "" @@ -206,11 +206,11 @@ msgstr "" msgid "Here's some files" msgstr "" -#: themes/default/templates/index.html.ep:110 +#: themes/default/templates/index.html.ep:115 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "" -#: themes/default/templates/index.html.ep:109 +#: themes/default/templates/index.html.ep:114 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "" @@ -279,7 +279,7 @@ msgstr "" msgid "No enough space available on the server for this file (size: %1)." msgstr "" -#: themes/default/templates/files.html.ep:45 themes/default/templates/index.html.ep:112 +#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 msgid "No expiration delay" msgstr "" @@ -316,7 +316,7 @@ msgstr "" msgid "Rows in red mean that the files have expired and are no longer available." msgstr "" -#: themes/default/templates/index.html.ep:111 +#: themes/default/templates/index.html.ep:116 msgid "Send all links by email" msgstr "" @@ -328,7 +328,7 @@ msgstr "" msgid "Send with your own mail software" msgstr "" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/index.html.ep:118 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "" @@ -357,7 +357,7 @@ msgstr "" msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "" -#: themes/default/templates/files.html.ep:46 +#: themes/default/templates/files.html.ep:51 msgid "The data has been successfully imported." msgstr "" @@ -382,7 +382,7 @@ msgstr "" msgid "The following email addresses are not valid: %1" msgstr "" -#: themes/default/templates/index.html.ep:101 +#: themes/default/templates/index.html.ep:106 msgid "The link(s) has been copied to your clipboard" msgstr "" @@ -402,7 +402,7 @@ msgstr "" 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 "" -#: themes/default/templates/index.html.ep:102 +#: themes/default/templates/index.html.ep:107 msgid "Unable to copy the link(s) to your clipboard" msgstr "" @@ -433,7 +433,7 @@ msgstr "" msgid "Uploaded files" msgstr "" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/index.html.ep:119 msgid "Websocket communication error" msgstr "" @@ -461,7 +461,7 @@ msgstr "" msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "" -#: themes/default/templates/index.html.ep:99 +#: themes/default/templates/index.html.ep:104 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "" diff --git a/themes/default/lib/Lufi/I18N/fr.po b/themes/default/lib/Lufi/I18N/fr.po index 4efb92c..dbeaf2d 100644 --- a/themes/default/lib/Lufi/I18N/fr.po +++ b/themes/default/lib/Lufi/I18N/fr.po @@ -84,11 +84,11 @@ msgstr "Fermer" msgid "Comma-separated email addresses" msgstr "Adresses mails séparées par des virgules" -#: themes/default/templates/index.html.ep:100 +#: themes/default/templates/index.html.ep:105 msgid "Copy all links to clipboard" msgstr "Copier tous les liens dans le presse-papier" -#: themes/default/templates/index.html.ep:103 +#: themes/default/templates/index.html.ep:108 msgid "Copy to clipboard" msgstr "Copier dans le presse-papier" @@ -116,7 +116,7 @@ msgstr "Supprimer après le premier téléchargement ?" msgid "Delete selected files" msgstr "Supprimer les fichiers sélectionnés" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:104 +#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 msgid "Deletion link" msgstr "Lien de suppression" @@ -124,7 +124,7 @@ msgstr "Lien de suppression" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "Ne vous inquiétez pas : si un utilisateur commence à télécharger le fichier avant son expiration et que le téléchargement se termine après l’expiration, l’utilisateur pourra quand même récupérer le fichier." -#: themes/default/templates/index.html.ep:106 themes/default/templates/render.html.ep:28 +#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Télécharger" @@ -132,7 +132,7 @@ msgstr "Télécharger" msgid "Download aborted." msgstr "Téléchargement abandonné." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:105 +#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 msgid "Download link" msgstr "Lien de téléchargement" @@ -156,7 +156,7 @@ msgstr "Sujet du mail" msgid "Emails" msgstr "Mails" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/index.html.ep:112 msgid "Encrypting part XX1 of XX2" msgstr "Chiffrement du fragment XX1 sur XX2" @@ -172,7 +172,7 @@ msgstr "Erreur : le fichier n’a pas été envoyé dans son intégralité" 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 ?" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/index.html.ep:113 msgid "Expiration:" msgstr "Expiration :" @@ -208,11 +208,11 @@ msgstr "Bonjour,\\n\\nVoici quelques fichiers que je souhaite partager avec toi msgid "Here's some files" msgstr "Voici quelques fichiers" -#: themes/default/templates/index.html.ep:110 +#: themes/default/templates/index.html.ep:115 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Appuyez sur la touche Entrée puis faites Ctrl+C pour copier tous les liens de téléchargement" -#: themes/default/templates/index.html.ep:109 +#: themes/default/templates/index.html.ep:114 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Appuyez sur la touche Entrée puis faites Ctrl+C pour copier le lien de téléchargement" @@ -281,7 +281,7 @@ msgstr "Mes fichiers" 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)." -#: themes/default/templates/files.html.ep:45 themes/default/templates/index.html.ep:112 +#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 msgid "No expiration delay" msgstr "Pas de délai d’expiration" @@ -318,7 +318,7 @@ msgstr "Supprimer du localStorage les fichiers expirés" msgid "Rows in red mean that the files have expired and are no longer available." msgstr "Les lignes en rouge indiquent que le fichier a expiré et n’est plus disponible." -#: themes/default/templates/index.html.ep:111 +#: themes/default/templates/index.html.ep:116 msgid "Send all links by email" msgstr "Envoyer tous les liens par mail" @@ -330,7 +330,7 @@ msgstr "Envoyer avec ce serveur" msgid "Send with your own mail software" msgstr "Envoyer avec votre propre logiciel de mail" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/index.html.ep:118 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "Envoi du fragment XX1 sur XX2. Veuillez patienter, la barre de progression peut mettre du temps avant d’avancer." @@ -359,7 +359,7 @@ msgstr "Désolé, l’envoi de fichier est désactivé." msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "L’administrateur ne peut voir que le nom du fichier, sa taille et son type mime (son type de fichier : vidéo, texte, etc.)." -#: themes/default/templates/files.html.ep:46 +#: themes/default/templates/files.html.ep:51 msgid "The data has been successfully imported." msgstr "Les données ont été importées avec succès." @@ -384,7 +384,7 @@ msgstr "Les fichiers envoyés sur une instance de Lufi sont chiffrés avant l’ msgid "The following email addresses are not valid: %1" msgstr "Les adresses mail suivantes ne sont pas valides : %1" -#: themes/default/templates/index.html.ep:101 +#: themes/default/templates/index.html.ep:106 msgid "The link(s) has been copied to your clipboard" msgstr "Le(s) lien(s) a/ont été copié dans votre presse-papier" @@ -404,7 +404,7 @@ msgstr "Le serveur a été incapable de retrouver l’enregistrement du fichier 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 "Ce serveur impose des limitations selon la taille des fichiers. Le délai d’expiration de votre fichier sera le minimum entre ce que vous avez choisi et les limites suivantes :" -#: themes/default/templates/index.html.ep:102 +#: themes/default/templates/index.html.ep:107 msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossible de copier le(s) lien(s) dans votre presse-papier" @@ -435,7 +435,7 @@ msgstr "Envoyé le" msgid "Uploaded files" msgstr "Fichiers envoyés" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/index.html.ep:119 msgid "Websocket communication error" msgstr "Erreur de communication WebSocket" @@ -463,7 +463,7 @@ msgstr "Il semble que vous n’ayez pas de clé dans votre URL. Vous ne serez pa msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Vous essayez de quitter la page. Le téléchargement sera annulé. Êtes-vous sûr(e) ?" -#: themes/default/templates/index.html.ep:99 +#: themes/default/templates/index.html.ep:104 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Vous essayez de quitter la page. L’envoi sera annulé. Êtes-vous sûr(e) ?" diff --git a/themes/default/lib/Lufi/I18N/it.po b/themes/default/lib/Lufi/I18N/it.po index 9bc5eec..8813017 100644 --- a/themes/default/lib/Lufi/I18N/it.po +++ b/themes/default/lib/Lufi/I18N/it.po @@ -84,11 +84,11 @@ msgstr "Chiudi" msgid "Comma-separated email addresses" msgstr "Indirizzi email separati da virgole" -#: themes/default/templates/index.html.ep:100 +#: themes/default/templates/index.html.ep:105 msgid "Copy all links to clipboard" msgstr "Copiare tutti i link negli appunti" -#: themes/default/templates/index.html.ep:103 +#: themes/default/templates/index.html.ep:108 msgid "Copy to clipboard" msgstr "Copiare negli appunti" @@ -116,7 +116,7 @@ msgstr "Cancellare al primo download?" msgid "Delete selected files" msgstr "" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:104 +#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 msgid "Deletion link" msgstr "Link per l'eliminazione" @@ -124,7 +124,7 @@ msgstr "Link per l'eliminazione" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "Non preoccuparti: se un utente cominciasse il download del file prima della scadenza ed il download terminasse dopo la scadenza, potrebbe ottenere il file." -#: themes/default/templates/index.html.ep:106 themes/default/templates/render.html.ep:28 +#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Download" @@ -132,7 +132,7 @@ msgstr "Download" msgid "Download aborted." msgstr "Download annullato." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:105 +#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 msgid "Download link" msgstr "Link per il download" @@ -156,7 +156,7 @@ msgstr "Oggetto dell'email" msgid "Emails" msgstr "Email" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/index.html.ep:112 msgid "Encrypting part XX1 of XX2" msgstr "Cifratura della parte XX1 di XX2" @@ -172,7 +172,7 @@ msgstr "Errore: il file non è stato inviato completamente" msgid "Error: unable to find the file. Are you sure of your URL?" msgstr "Errore: impossibile trovare il file. Sei certo dell'URL ?" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/index.html.ep:113 msgid "Expiration:" msgstr "Scadenza:" @@ -208,11 +208,11 @@ msgstr "Buongiorno,\\n\\necco qualche file che vorrei condividere con te:\\n" msgid "Here's some files" msgstr "Ecco qualche file" -#: themes/default/templates/index.html.ep:110 +#: themes/default/templates/index.html.ep:115 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Premere Enter, poi Ctrl+C per copiare tutti i link di download" -#: themes/default/templates/index.html.ep:109 +#: themes/default/templates/index.html.ep:114 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Premere Enter, poi Ctrl+C per copiare il link di download" @@ -281,7 +281,7 @@ msgstr "I miei file" msgid "No enough space available on the server for this file (size: %1)." msgstr "Spazio disco insufficiente sul server per questo file (dimensione: %1)." -#: themes/default/templates/files.html.ep:45 themes/default/templates/index.html.ep:112 +#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 msgid "No expiration delay" msgstr "Nessun ritardo per la scadenza" @@ -322,7 +322,7 @@ msgstr "Le righe in viola indicano che il file è scaduto e non è più disponib msgid "Rows in red mean that the files have expired and are no longer available." msgstr "" -#: themes/default/templates/index.html.ep:111 +#: themes/default/templates/index.html.ep:116 msgid "Send all links by email" msgstr "Inviare tutti i link tramite email" @@ -334,7 +334,7 @@ msgstr "Inviare tramite questo server" msgid "Send with your own mail software" msgstr "Inviare tramite il vostro programma di posta" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/index.html.ep:118 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "Invio della parte XX1 su XX2. Prego attendere, la barra di avanzamento può impiegare del tempo prima di colorarsi." @@ -367,7 +367,7 @@ msgstr "L'amministratore pu vedere solo il nome del file, la sua dimensione e il msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "" -#: themes/default/templates/files.html.ep:46 +#: themes/default/templates/files.html.ep:51 msgid "The data has been successfully imported." msgstr "I dati sono stati importati correttamente." @@ -392,7 +392,7 @@ msgstr "I file inviati su un istanza di Lufi sono cifrati prima dell'invio al se msgid "The following email addresses are not valid: %1" msgstr "I seguenti indirizzi email non sono validi: %1" -#: themes/default/templates/index.html.ep:101 +#: themes/default/templates/index.html.ep:106 msgid "The link(s) has been copied to your clipboard" msgstr "I link sono stati copiati negli appunti" @@ -412,7 +412,7 @@ msgstr "Il server non è stato in grado di trovare il file record a cui aggiunge 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 "Questo server pone delle limitazioni in base alla dimensione del file.La data di scadenza del tuo file sarà la minore tra quella scelta e queste limitazioni:" -#: themes/default/templates/index.html.ep:102 +#: themes/default/templates/index.html.ep:107 msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossibile copiare i link negli appunti" @@ -443,7 +443,7 @@ msgstr "Invio il" msgid "Uploaded files" msgstr "File inviati" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/index.html.ep:119 msgid "Websocket communication error" msgstr "Errore di comunicazione WebSocket" @@ -471,7 +471,7 @@ msgstr "Sembra che non ci sia una chiave nel tuo URL. Non sarai in grado di deci msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Hai cercato di uscire da questa pagina. Il download sarà cancellato. Sei sicuro?" -#: themes/default/templates/index.html.ep:99 +#: themes/default/templates/index.html.ep:104 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Hai cercato di uscire da questa pagina. L'invio sarà cancellato. Sei sicuro?" diff --git a/themes/default/lib/Lufi/I18N/nl.po b/themes/default/lib/Lufi/I18N/nl.po index 21e0078..84fefda 100644 --- a/themes/default/lib/Lufi/I18N/nl.po +++ b/themes/default/lib/Lufi/I18N/nl.po @@ -71,11 +71,11 @@ msgstr "Sluiten" msgid "Comma-separated email addresses" msgstr "Komma gescheiden email adressen" -#: themes/default/templates/index.html.ep:100 +#: themes/default/templates/index.html.ep:105 msgid "Copy all links to clipboard" msgstr "Kopieer alle links naar klembord" -#: themes/default/templates/index.html.ep:103 +#: themes/default/templates/index.html.ep:108 msgid "Copy to clipboard" msgstr "Kopieer naar klembord" @@ -103,7 +103,7 @@ msgstr "Verwijder na eerste download?" msgid "Delete selected files" msgstr "" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:104 +#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 msgid "Deletion link" msgstr "Verwijderingslink" @@ -111,7 +111,7 @@ msgstr "Verwijderingslink" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "Geen zorgen: als een gebruiker de download start voor de vervaldatum, dan zal die het bestand kunnen binnenhalen." -#: themes/default/templates/index.html.ep:106 themes/default/templates/render.html.ep:28 +#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Download" @@ -119,7 +119,7 @@ msgstr "Download" msgid "Download aborted." msgstr "Download geannuleerd." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:105 +#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 msgid "Download link" msgstr "Download link" @@ -143,7 +143,7 @@ msgstr "Onderwerp" msgid "Emails" msgstr "Emails" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/index.html.ep:112 msgid "Encrypting part XX1 of XX2" msgstr "Encrypten deel XX1 van XX2 " @@ -159,7 +159,7 @@ msgstr "Fout: het bestand is niet volledig opgestuurd." msgid "Error: unable to find the file. Are you sure of your URL?" msgstr "Fout: kan het bestand niet vinden. Is de URL juist?" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/index.html.ep:113 msgid "Expiration:" msgstr "Vervaldatum:" @@ -195,11 +195,11 @@ msgstr "Hallo,\\n\\nHier zijn enkele bestanden die ik met je wil delen:\\n\\n" msgid "Here's some files" msgstr "Hier zijn enkele bestanden" -#: themes/default/templates/index.html.ep:110 +#: themes/default/templates/index.html.ep:115 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Druk Enter, vervolgens CTRL+C om alle download links te kopieeren" -#: themes/default/templates/index.html.ep:109 +#: themes/default/templates/index.html.ep:114 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Druk Enter, vervolgens CTRL+C om de download link te kopieeren" @@ -268,7 +268,7 @@ msgstr "Mijn bestanden" 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)." -#: themes/default/templates/files.html.ep:45 themes/default/templates/index.html.ep:112 +#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 msgid "No expiration delay" msgstr "Geen verloop uitstel" @@ -309,7 +309,7 @@ msgstr "Registreer" msgid "Rows in red mean that the files have expired and are no longer available." msgstr "Rode rijen betekenen dat deze bestanden verlopen en verwijderd zijn." -#: themes/default/templates/index.html.ep:111 +#: themes/default/templates/index.html.ep:116 msgid "Send all links by email" msgstr "Verstuur alle links via mail" @@ -321,7 +321,7 @@ msgstr "Verstuur via deze server" msgid "Send with your own mail software" msgstr "Verstuur via eigen mail software" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/index.html.ep:118 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "Versturen deel XX1 van XX2. Een ogenblik geduld..." @@ -350,7 +350,7 @@ msgstr "SOrry, uploaden is uitgeschakeld." msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "Beheerders zien alleen bestandsnamen, grootte en mimetype (wat voor soort bestand het is: video, tekst etc.)." -#: themes/default/templates/files.html.ep:46 +#: themes/default/templates/files.html.ep:51 msgid "The data has been successfully imported." msgstr "Data is succesvol geimporteerd." @@ -375,7 +375,7 @@ msgstr "Bestanden die geupload zijn naar Lufi worden voor de upload versleuteld: msgid "The following email addresses are not valid: %1" msgstr "Volgende email adressen zijn niet geldig: %1" -#: themes/default/templates/index.html.ep:101 +#: themes/default/templates/index.html.ep:106 msgid "The link(s) has been copied to your clipboard" msgstr "De link is gekopieerd naar je klembord" @@ -395,7 +395,7 @@ msgstr "Server kon een deel van het bestand niet vinden. Neem contact op met beh 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 "Deze server stelt beperkingen vast volgens de bestandsgrootte. De vervaldatum van uw bestand zal het minimum zijn tussen wat u kiest en de volgende beperkingen:" -#: themes/default/templates/index.html.ep:102 +#: themes/default/templates/index.html.ep:107 msgid "Unable to copy the link(s) to your clipboard" msgstr "Kan de link(s) niet naar je klembord kopieeren" @@ -426,7 +426,7 @@ msgstr "Geupload op" msgid "Uploaded files" msgstr "Geuploade bestanden" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/index.html.ep:119 msgid "Websocket communication error" msgstr "Websocket communicatie fout" @@ -454,7 +454,7 @@ msgstr "Je hebt geen sleutel in je URL. Je kan het bestand niet decrypten. Downl msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Je verlaat deze pagina. Download zal geannuleerd worden. Weet je het zeker?" -#: themes/default/templates/index.html.ep:99 +#: themes/default/templates/index.html.ep:104 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Je verlaat deze pagina. Upload zal geannuleerd worden. Weet je het zeker? " diff --git a/themes/default/lib/Lufi/I18N/oc.po b/themes/default/lib/Lufi/I18N/oc.po index 861a413..7824144 100644 --- a/themes/default/lib/Lufi/I18N/oc.po +++ b/themes/default/lib/Lufi/I18N/oc.po @@ -84,11 +84,11 @@ msgstr "Tampar" msgid "Comma-separated email addresses" msgstr "Adreças de corrièl separadas per de virgulas" -#: themes/default/templates/index.html.ep:100 +#: themes/default/templates/index.html.ep:105 msgid "Copy all links to clipboard" msgstr "Copiar totes los ligams al quicha-papièrs" -#: themes/default/templates/index.html.ep:103 +#: themes/default/templates/index.html.ep:108 msgid "Copy to clipboard" msgstr "Copiar al quicha-papièrs" @@ -116,7 +116,7 @@ msgstr "Suprimir aprèp lo primièr telecargament ?" msgid "Delete selected files" msgstr "Suprimir los fichièrs seleccionats" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:104 +#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 msgid "Deletion link" msgstr "Ligam de supression" @@ -124,7 +124,7 @@ msgstr "Ligam de supression" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "Vos copetz pas lo cap : se un utilizaire comença a telecargar lo fichièr abans son expiracion e que lo telecargament s’acaba aprèp l’expiracion, utilizaire poirà recuperar lo fichièr." -#: themes/default/templates/index.html.ep:106 themes/default/templates/render.html.ep:28 +#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Telecargar" @@ -132,7 +132,7 @@ msgstr "Telecargar" msgid "Download aborted." msgstr "Telecargament abandonat." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:105 +#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 msgid "Download link" msgstr "Ligam de telecargament" @@ -156,7 +156,7 @@ msgstr "Subjècte del corrièl" msgid "Emails" msgstr "Corrièl" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/index.html.ep:112 msgid "Encrypting part XX1 of XX2" msgstr "Chiframent del tròç XX1 sus XX2" @@ -172,7 +172,7 @@ msgstr "Error : lo fichièr es pas estat mandat completament" 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 ?" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/index.html.ep:113 msgid "Expiration:" msgstr "Expiracion :" @@ -208,11 +208,11 @@ msgstr "Bonjorn,\\n\\nVaquí qualques fichièrs que desiri partejar amb tu :\\ msgid "Here's some files" msgstr "Vaquí qualques fichièrs" -#: themes/default/templates/index.html.ep:110 +#: themes/default/templates/index.html.ep:115 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Picatz sus Entrada puèi fasètz Ctrl+C per copiar totes los ligams per telecargar" -#: themes/default/templates/index.html.ep:109 +#: themes/default/templates/index.html.ep:114 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Picatz sus Entrada puèi fasètz Ctrl+C per copiar lo ligam per telecargar" @@ -281,7 +281,7 @@ msgstr "Mos fichièrs" 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)." -#: themes/default/templates/files.html.ep:45 themes/default/templates/index.html.ep:112 +#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 msgid "No expiration delay" msgstr "Pas cap de relambi d’expiracion" @@ -318,7 +318,7 @@ msgstr "Suprimir del localStorage los fichièrs expirats" msgid "Rows in red mean that the files have expired and are no longer available." msgstr "Las linhas en roge indican que lo fichièr a expirat e es pas mai disponible." -#: themes/default/templates/index.html.ep:111 +#: themes/default/templates/index.html.ep:116 msgid "Send all links by email" msgstr "Mandar totes los ligams per corrièl" @@ -330,7 +330,7 @@ msgstr "Mandar amb aqueste servidor" msgid "Send with your own mail software" msgstr "Mandar amb vòstre pròpri logicial de corrièl" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/index.html.ep:118 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "Mandadís del fragment XX1 sus XX2. Pacientatz, la barra de progression pòt metre de temps abans d’avançar." @@ -359,7 +359,7 @@ msgstr "O planhèm, la foncion per mandar de fichièr es desactivada." msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "L’administrator pòt pas que veire lo nom del fichièr, sa talha e son mimetype (Quina mena de fichièr es : vidèo, tèxte, etc.)." -#: themes/default/templates/files.html.ep:46 +#: themes/default/templates/files.html.ep:51 msgid "The data has been successfully imported." msgstr "Las donadas son ben estadas importadas." @@ -384,7 +384,7 @@ msgstr "Los fichièrs mandats amb una instància Lufi son chifrats abans la mand msgid "The following email addresses are not valid: %1" msgstr "Las adreças de corrièl seguentas son pas validas : %1" -#: themes/default/templates/index.html.ep:101 +#: themes/default/templates/index.html.ep:106 msgid "The link(s) has been copied to your clipboard" msgstr "Lo(s) ligam(s) es/son estat(s) copiat(s) dins vòstre quicha-papièrs" @@ -404,7 +404,7 @@ msgstr "Lo servidor es pas estat capable de retrobar l’enregistrament del fich 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 "Aqueste servidor impausa de limitacions segon la talha dels fichièrs. Lo relambi d’expiracion de vòstre fichièr serà lo minimum entre çò qu’avètz causit e los limits seguents :" -#: themes/default/templates/index.html.ep:102 +#: themes/default/templates/index.html.ep:107 msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossible de copiar lo(s) ligams(s) dins vòstre quicha-papièrs" @@ -435,7 +435,7 @@ msgstr "Mandat lo" msgid "Uploaded files" msgstr "Fichièrs mandats" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/index.html.ep:119 msgid "Websocket communication error" msgstr "Error de comunicacion WebSocket" @@ -463,7 +463,7 @@ msgstr "Sembla qu’avètz pas la bona clau dins l’URL. Poiretz pas deschifrar msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Ensajatz de partir de la pagina. Lo telecargament serà anullat. Sètz segur-a ?" -#: themes/default/templates/index.html.ep:99 +#: themes/default/templates/index.html.ep:104 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Ensajatz de partir de la pagina. Lo mandadís serà anullat. Sètz segur-a ?" diff --git a/themes/default/lib/Lufi/I18N/pt.po b/themes/default/lib/Lufi/I18N/pt.po index 851ebcb..dac9017 100644 --- a/themes/default/lib/Lufi/I18N/pt.po +++ b/themes/default/lib/Lufi/I18N/pt.po @@ -85,11 +85,11 @@ msgstr "Fechar" msgid "Comma-separated email addresses" msgstr "Os e-mails devem ser separados por vírgulas" -#: themes/default/templates/index.html.ep:100 +#: themes/default/templates/index.html.ep:105 msgid "Copy all links to clipboard" msgstr "Copiar todos os links para a área de transferência" -#: themes/default/templates/index.html.ep:103 +#: themes/default/templates/index.html.ep:108 msgid "Copy to clipboard" msgstr "Copiar para a área de transferência" @@ -117,7 +117,7 @@ msgstr "Apagar após o primeiro download?" msgid "Delete selected files" msgstr "" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:104 +#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 msgid "Deletion link" msgstr "Eliminar o link" @@ -125,7 +125,7 @@ msgstr "Eliminar o link" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "Não se preocupe: se um utilizador começa a descarregar um ficheiro antes a sua expiração e que o descarregamento acaba após a sua expiração, o utilizador pode ainda assim recuperar o ficheiro." -#: themes/default/templates/index.html.ep:106 themes/default/templates/render.html.ep:28 +#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Download" @@ -133,7 +133,7 @@ msgstr "Download" msgid "Download aborted." msgstr "Download interrompido." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:105 +#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 msgid "Download link" msgstr "Link para o download" @@ -161,7 +161,7 @@ msgstr "Assunto do e-mail" msgid "Emails" msgstr "E-mails" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/index.html.ep:112 msgid "Encrypting part XX1 of XX2" msgstr "Codificação do fragmento XX1 de XX2" @@ -177,7 +177,7 @@ msgstr "Erro: o ficheiro não foi enviado na totalidade." 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?" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/index.html.ep:113 msgid "Expiration:" msgstr "Expiração:" @@ -213,11 +213,11 @@ msgstr "Olá,\\n\\nAqui estão alguns ficheiros que gostaria de partilhar contig msgid "Here's some files" msgstr "Aqui estão alguns ficheiros" -#: themes/default/templates/index.html.ep:110 +#: themes/default/templates/index.html.ep:115 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Clique no Enter e depois Ctrl+C para copiar todos os links de download" -#: themes/default/templates/index.html.ep:109 +#: themes/default/templates/index.html.ep:114 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Clique no Enter e depois Ctrl+C para copiar o link de download" @@ -290,7 +290,7 @@ msgstr "Meus ficheiros" 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)." -#: themes/default/templates/files.html.ep:45 themes/default/templates/index.html.ep:112 +#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 msgid "No expiration delay" msgstr "Não tem prazo de expiração" @@ -327,7 +327,7 @@ msgstr "Apagar do localStorage os ficheiros expirados" msgid "Rows in red mean that the files have expired and are no longer available." msgstr "As linhas a vermelho indicam que o ficheiro expirou e já não está disponível." -#: themes/default/templates/index.html.ep:111 +#: themes/default/templates/index.html.ep:116 msgid "Send all links by email" msgstr "Enviar todos os links por e-mail" @@ -339,7 +339,7 @@ msgstr "Enviar com este servidor" msgid "Send with your own mail software" msgstr "Enviar com o seu e-mail pessoal" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/index.html.ep:118 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "Envio do fragmento XX1 de XX2. Por favor aguarde, a barra de progressão pode levar algum tempo antes de avançar." @@ -368,7 +368,7 @@ msgstr "Desculpe, o envio do ficheiro está desativado." msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "O administrador pode apenas ver o nome do ficheiro, o seu tamanho e o tipo de mime (o tipo de ficheiro: texto, vídeo, etc.)." -#: themes/default/templates/files.html.ep:46 +#: themes/default/templates/files.html.ep:51 msgid "The data has been successfully imported." msgstr "Os dados foram importados com sucesso." @@ -393,7 +393,7 @@ msgstr "Os ficheiros enviados no Lufi são codificados antes de serem enviados a msgid "The following email addresses are not valid: %1" msgstr "Os e-mails seguintes não são válidos: %1" -#: themes/default/templates/index.html.ep:101 +#: themes/default/templates/index.html.ep:106 msgid "The link(s) has been copied to your clipboard" msgstr "O(s) link(s) foi/foram copiados para a área de transferência" @@ -413,7 +413,7 @@ msgstr "O servidor foi incapaz de encontrar o registo do ficheiro no qual devia- 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 "O servidor exige limites segundo o tamanho dos ficheiros. O prazo de expiração dos seu ficheiro sera o minimo entre o que você escolheu e os limites seguintes:" -#: themes/default/templates/index.html.ep:102 +#: themes/default/templates/index.html.ep:107 msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossível copiar o(s) link(s) na sua área de transferência" @@ -444,7 +444,7 @@ msgstr "Enviar a" msgid "Uploaded files" msgstr "Ficheiros enviados" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/index.html.ep:119 msgid "Websocket communication error" msgstr "Erro de comunicação com WebSocket" @@ -476,7 +476,7 @@ msgstr "Parece que não tem a chave no seu URL. Não poderá descodificar o fich msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Está a tentar sair da página. O download será anulado. Tem a certeza?" -#: themes/default/templates/index.html.ep:99 +#: themes/default/templates/index.html.ep:104 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Está a tentar sair da página. O envio será anulado. Tem a certeza?" diff --git a/themes/default/public/js/lufi-files.js b/themes/default/public/js/lufi-files.js index 58e64e5..7bcfff0 100644 --- a/themes/default/public/js/lufi-files.js +++ b/themes/default/public/js/lufi-files.js @@ -159,7 +159,7 @@ function populateFilesTable() { }); files.forEach(function(element, index, array) { var del_view = (element.del_at_first_view) ? '' : ''; - var dlink = baseURL+'d/'+element.short+'/'+element.token; + var dlink = actionURL+'d/'+element.short+'/'+element.token; var limit = (element.delay === 0) ? i18n.noExpiration : moment.unix(element.delay * 86400 + element.created_at).locale(window.navigator.language).format('LLLL'); var created_at = moment.unix(element.created_at).locale(window.navigator.language).format('LLLL'); @@ -189,7 +189,7 @@ function populateFilesTable() { '', '', '', - '', + '', ''].join('')); $('#myfiles').append(tr); $('#del-'+element.short).on('click', delFile); diff --git a/themes/default/public/js/lufi-up.js b/themes/default/public/js/lufi-up.js index e2b5376..e594927 100644 --- a/themes/default/public/js/lufi-up.js +++ b/themes/default/public/js/lufi-up.js @@ -94,7 +94,7 @@ function updateMailLink() { for (i = 0; i < a.length; i++) { l.push(a[i].id); } - var u = baseURL+'m?links='+JSON.stringify(l); + var u = actionURL+'m?links='+JSON.stringify(l); $('#mailto').attr('href', u); } @@ -268,10 +268,10 @@ function updateProgressBar(data) { var n = $('#name-'+window.fc); var d = $('
'); var url = baseURL+'r/'+short+'#'+key; - var del_url = baseURL+'d/'+short+'/'+data.token; + var del_url = actionURL+'d/'+short+'/'+data.token; var links = encodeURIComponent('["'+short+'"]'); var limit = (delay === 0) ? i18n.noLimit : i18n.expiration+' '+moment.unix(delay * 86400 + created_at).locale(window.navigator.language).format('LLLL'); - n.html(n.html()+'
'+limit); + n.html(n.html()+'
'+limit); d.html(['
', '
', '', @@ -306,7 +306,7 @@ function updateProgressBar(data) { // Add copy all and mailto buttons var misc = $('#misc'); if (misc.html() === '') { - misc.html(''+i18n.copyAll+' '+i18n.mailTo+''); + misc.html(''+i18n.copyAll+' '+i18n.mailTo+''); } else { updateMailLink(); } diff --git a/themes/default/templates/files.html.ep b/themes/default/templates/files.html.ep index a7441e3..cf1ac15 100644 --- a/themes/default/templates/files.html.ep +++ b/themes/default/templates/files.html.ep @@ -39,7 +39,12 @@
%= javascript begin -var baseURL = '<%== url_for('/')->to_abs() %>'; +% if (defined($self->config('fixed_domain')) && $self->config('fixed_domain')) { +var baseURL = '<%= url_for('/')->host($self->config('fixed_domain'))->to_abs() %>'; +% } else { +var baseURL = '<%= url_for('/')->to_abs() %>'; +% } +var actionURL = '<%= url_for('/')->to_abs() %>'; var counterURL = '<%== url_for('counter') %>'; var i18n = { noExpiration: '<%= l('No expiration delay') %>', diff --git a/themes/default/templates/index.html.ep b/themes/default/templates/index.html.ep index 7e98932..95991e8 100644 --- a/themes/default/templates/index.html.ep +++ b/themes/default/templates/index.html.ep @@ -94,7 +94,12 @@ $(document).ready(function(){ $('select').material_select(); }); var ws_url = '<%= url_for('upload')->to_abs() %>'; +% if (defined($self->config('fixed_domain')) && $self->config('fixed_domain')) { +var baseURL = '<%= url_for('/')->host($self->config('fixed_domain'))->to_abs() %>'; +% } else { var baseURL = '<%= url_for('/')->to_abs() %>'; +% } +var actionURL = '<%= url_for('/')->to_abs() %>'; var i18n = { confirmExit: '<%= l('You have attempted to leave this page. The upload will be canceled. Are you sure?') %>', copyAll: '<%= l('Copy all links to clipboard') %>', From 7c8ac69ffe59f0050ae96e9d9d3c5f8e18aa7336 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Mon, 27 Nov 2017 19:20:26 +0100 Subject: [PATCH 04/49] Fix #104 Use config->prefix to set cookie path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit is dedicated to Michael Kozma, who is supporting me with Ğ1. Many thanks :-) --- lib/Lufi.pm | 8 ++++++++ themes/default/lib/Lufi/I18N/ca.po | 4 ++-- themes/default/lib/Lufi/I18N/en.po | 4 ++-- themes/default/lib/Lufi/I18N/fr.po | 4 ++-- themes/default/lib/Lufi/I18N/it.po | 4 ++-- themes/default/lib/Lufi/I18N/nl.po | 4 ++-- themes/default/lib/Lufi/I18N/oc.po | 4 ++-- themes/default/lib/Lufi/I18N/pt.po | 4 ++-- 8 files changed, 22 insertions(+), 14 deletions(-) diff --git a/lib/Lufi.pm b/lib/Lufi.pm index e703ec4..c046529 100644 --- a/lib/Lufi.pm +++ b/lib/Lufi.pm @@ -3,6 +3,7 @@ package Lufi; use Mojo::Base 'Mojolicious'; use Net::LDAP; use Apache::Htpasswd; +use Mojolicious::Sessions; $ENV{MOJO_MAX_WEBSOCKET_SIZE} = 100485760; # 10 * 1024 * 1024 = 10MiB @@ -13,6 +14,7 @@ sub startup { my $config = $self->plugin('Config' => { default => { + prefix => '/', provisioning => 100, provis_step => 5, length => 10, @@ -153,6 +155,12 @@ sub startup { mkdir($self->config('upload_dir'), 0700) unless (-d $self->config('upload_dir')); die ('The upload directory ('.$self->config('upload_dir').') is not writable') unless (-w $self->config('upload_dir')); + # Configure sessions + my $sessions = Mojolicious::Sessions->new; + $sessions->cookie_name('lufi'); + $sessions->cookie_path($self->config('prefix')); + $self->sessions($sessions); + # Default layout $self->defaults(layout => 'default'); diff --git a/themes/default/lib/Lufi/I18N/ca.po b/themes/default/lib/Lufi/I18N/ca.po index 87c102e..4e45272 100644 --- a/themes/default/lib/Lufi/I18N/ca.po +++ b/themes/default/lib/Lufi/I18N/ca.po @@ -304,7 +304,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:191 +#: lib/Lufi.pm:199 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -345,7 +345,7 @@ msgstr "Compartiu fitxers amb total privacitat a %1" msgid "Signin" msgstr "Autenticació" -#: lib/Lufi.pm:194 +#: lib/Lufi.pm:202 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 "" diff --git a/themes/default/lib/Lufi/I18N/en.po b/themes/default/lib/Lufi/I18N/en.po index f79e4fb..92915a0 100644 --- a/themes/default/lib/Lufi/I18N/en.po +++ b/themes/default/lib/Lufi/I18N/en.po @@ -300,7 +300,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:191 +#: lib/Lufi.pm:199 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -341,7 +341,7 @@ msgstr "" msgid "Signin" msgstr "" -#: lib/Lufi.pm:194 +#: lib/Lufi.pm:202 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 "" diff --git a/themes/default/lib/Lufi/I18N/fr.po b/themes/default/lib/Lufi/I18N/fr.po index dbeaf2d..d2c24d2 100644 --- a/themes/default/lib/Lufi/I18N/fr.po +++ b/themes/default/lib/Lufi/I18N/fr.po @@ -302,7 +302,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:191 +#: lib/Lufi.pm:199 msgid "Please, check your credentials: unable to authenticate." msgstr "Veuillez vérifier vos identifiants : impossible de vous authentifier." @@ -343,7 +343,7 @@ msgstr "Partagez vos fichiers en toute confidentialité sur %1" msgid "Signin" msgstr "Connexion" -#: lib/Lufi.pm:194 +#: lib/Lufi.pm:202 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." diff --git a/themes/default/lib/Lufi/I18N/it.po b/themes/default/lib/Lufi/I18N/it.po index 8813017..6030a39 100644 --- a/themes/default/lib/Lufi/I18N/it.po +++ b/themes/default/lib/Lufi/I18N/it.po @@ -302,7 +302,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:191 +#: lib/Lufi.pm:199 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -347,7 +347,7 @@ msgstr "Condividi tutti i file in totale riservatezza su %1" msgid "Signin" msgstr "Autenticazione" -#: lib/Lufi.pm:194 +#: lib/Lufi.pm:202 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 "" diff --git a/themes/default/lib/Lufi/I18N/nl.po b/themes/default/lib/Lufi/I18N/nl.po index 84fefda..d3099da 100644 --- a/themes/default/lib/Lufi/I18N/nl.po +++ b/themes/default/lib/Lufi/I18N/nl.po @@ -289,7 +289,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:191 +#: lib/Lufi.pm:199 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -334,7 +334,7 @@ msgstr "Deel je bestanden met volledige privacy op %1" msgid "Signin" msgstr "Inloggen" -#: lib/Lufi.pm:194 +#: lib/Lufi.pm:202 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 "" diff --git a/themes/default/lib/Lufi/I18N/oc.po b/themes/default/lib/Lufi/I18N/oc.po index 7824144..aa6867c 100644 --- a/themes/default/lib/Lufi/I18N/oc.po +++ b/themes/default/lib/Lufi/I18N/oc.po @@ -302,7 +302,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:191 +#: lib/Lufi.pm:199 msgid "Please, check your credentials: unable to authenticate." msgstr "Mercés de verificar vòstres identificants : impossible de vos autentificar." @@ -343,7 +343,7 @@ msgstr "Partejatz vòstres fichièrs en tota confidencialitat sus %1" msgid "Signin" msgstr "Connexion" -#: lib/Lufi.pm:194 +#: lib/Lufi.pm:202 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 "O planhèm collèga, sètz pas autorizat a utilizar aqueste servici. Contactatz vòstre administrator sistèma se pensatz que i a un problèma." diff --git a/themes/default/lib/Lufi/I18N/pt.po b/themes/default/lib/Lufi/I18N/pt.po index dac9017..c87e965 100644 --- a/themes/default/lib/Lufi/I18N/pt.po +++ b/themes/default/lib/Lufi/I18N/pt.po @@ -311,7 +311,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:191 +#: lib/Lufi.pm:199 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -352,7 +352,7 @@ msgstr "Partilhe os seus ficheiros com toda a privacidade em %1" msgid "Signin" msgstr "Conexão" -#: lib/Lufi.pm:194 +#: lib/Lufi.pm:202 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 "" From d4ac8f678d964f294d819b7e31305cb906488d3e Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Mon, 27 Nov 2017 19:51:36 +0100 Subject: [PATCH 05/49] Related to #80 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit is dedicated to Jean-Yves Toumit, who is supporting me with Ğ1. Many thanks :-) --- themes/default/public/css/lufi.css | 6 ++++++ themes/default/templates/layouts/default.html.ep | 2 +- themes/default/templates/render.html.ep | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/themes/default/public/css/lufi.css b/themes/default/public/css/lufi.css index 496901a..64ebd46 100644 --- a/themes/default/public/css/lufi.css +++ b/themes/default/public/css/lufi.css @@ -102,3 +102,9 @@ a.classic:focus { .files-buttons a { margin-bottom: 10px; } +#pb { + width: 0; +} +.no_border { + border: 0; +} diff --git a/themes/default/templates/layouts/default.html.ep b/themes/default/templates/layouts/default.html.ep index cd426d0..e406644 100644 --- a/themes/default/templates/layouts/default.html.ep +++ b/themes/default/templates/layouts/default.html.ep @@ -87,7 +87,7 @@ <%= content %>
% if (defined(config('piwik_img'))) { - + % } %= javascript '/js/materialize.js' %= javascript begin diff --git a/themes/default/templates/render.html.ep b/themes/default/templates/render.html.ep index 7c757ad..d867d8a 100644 --- a/themes/default/templates/render.html.ep +++ b/themes/default/templates/render.html.ep @@ -33,7 +33,7 @@

<%= l('Please wait while we are getting your file. We first need to download and decrypt all parts before you can get it.') %>

-
+
0%
From 6306c317ec46bd5536d1ce3a31e8d4cb8716b5cb Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Thu, 12 Apr 2018 18:28:11 +0200 Subject: [PATCH 06/49] Fix #114 - missing Debian Strech Perl dependency --- cpanfile | 1 + 1 file changed, 1 insertion(+) diff --git a/cpanfile b/cpanfile index ed14502..d9a9ba0 100644 --- a/cpanfile +++ b/cpanfile @@ -1,3 +1,4 @@ +requires 'inc::Module::Install'; requires 'Mojolicious', '>= 7.31'; requires 'ORLite'; requires 'Mojolicious::Plugin::DebugDumperHelper'; From 413e13a801acfd01f325f626f4688ce4a1a913e0 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 21 Oct 2018 09:46:31 +0200 Subject: [PATCH 07/49] Fix #118 Put some deps in cpanfile features --- cpanfile | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/cpanfile b/cpanfile index d9a9ba0..ce9893b 100644 --- a/cpanfile +++ b/cpanfile @@ -1,12 +1,8 @@ requires 'inc::Module::Install'; 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'; @@ -17,6 +13,20 @@ requires 'Number::Bytes::Human'; requires 'Filesys::DfPortable'; requires 'Switch'; requires 'Data::Entropy'; -requires 'Net::LDAP'; requires 'Crypt::SaltedHash'; -requires 'Apache::Htpasswd'; + +feature 'ldap', 'LDAP authentication support' => sub { + requires 'Net::LDAP'; + requires 'Mojolicious::Plugin::Authentication'; +}; +feature 'htpasswd', 'Htpasswd authentication support' => sub { + requires 'Apache::Htpasswd'; + requires 'Mojolicious::Plugin::Authentication'; +}; +feature 'postgresql', 'PostgreSQL support' => sub { + requires 'Mojo::Pg'; + requires 'Mojolicious::Plugin::PgURLHelper'; +}; +feature 'sqlite', 'SQLite support' => sub { + requires 'ORLite'; +} From 1646980c227b733cbca032dffdced266f54c5122 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 21 Oct 2018 11:58:51 +0200 Subject: [PATCH 08/49] Use Mojo::SQLite instead of ORLite + update deps --- .gitignore | 5 +- CHANGELOG | 3 + Makefile | 2 +- cpanfile | 2 +- cpanfile.snapshot | 887 +++++++++++++++++++---------- lib/Lufi.pm | 1 + lib/Lufi/DB/File.pm | 198 ++++++- lib/Lufi/DB/File/Pg.pm | 164 ------ lib/Lufi/DB/File/SQLite.pm | 173 ------ lib/Lufi/DB/SQLite.pm | 64 --- lib/Lufi/DB/Slice.pm | 77 +++ lib/Lufi/DB/Slice/Pg.pm | 60 -- lib/Lufi/DB/Slice/SQLite.pm | 44 -- lib/Lufi/Plugin/Helpers.pm | 61 +- lib/Mounter.pm | 18 + lufi.conf.template | 2 +- themes/default/lib/Lufi/I18N/ca.po | 4 +- themes/default/lib/Lufi/I18N/en.po | 4 +- themes/default/lib/Lufi/I18N/fr.po | 4 +- themes/default/lib/Lufi/I18N/it.po | 4 +- themes/default/lib/Lufi/I18N/nl.po | 4 +- themes/default/lib/Lufi/I18N/oc.po | 4 +- themes/default/lib/Lufi/I18N/pt.po | 4 +- utilities/migrations/pg.sql | 28 + utilities/migrations/sqlite.sql | 28 + utilities/migrations_pg.sql | 28 - 26 files changed, 1000 insertions(+), 873 deletions(-) delete mode 100644 lib/Lufi/DB/SQLite.pm create mode 100644 utilities/migrations/pg.sql create mode 100644 utilities/migrations/sqlite.sql delete mode 100644 utilities/migrations_pg.sql diff --git a/.gitignore b/.gitignore index 0ccd925..b994b06 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ local/* files/* lufi.conf -lufi.db +*.db +*.db-shm +*.db-wal +*.bak *.swp script/hypnotoad.pid stop-upload diff --git a/CHANGELOG b/CHANGELOG index 2c9740b..acebc26 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ Revision history for Lufi +0.03 2018-??-?? + - Use Mojo::SQLite instead of ORLite + 0.02.2 2017-09-18 - Fix cron tasks bug diff --git a/Makefile b/Makefile index d56ddf4..8b75700 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ podcheck: podchecker lib/Lufi/DB/File.pm lib/Lufi/DB/Slice.pm test: - $(CARTON) $(REAL_LUFI) test + $(CARTON) prove -l -f -o t/basic.t clean: rm -rf lufi.db files/ diff --git a/cpanfile b/cpanfile index ce9893b..3ab3ad7 100644 --- a/cpanfile +++ b/cpanfile @@ -28,5 +28,5 @@ feature 'postgresql', 'PostgreSQL support' => sub { requires 'Mojolicious::Plugin::PgURLHelper'; }; feature 'sqlite', 'SQLite support' => sub { - requires 'ORLite'; + requires 'Mojo::SQLite', '>= 3.000'; } diff --git a/cpanfile.snapshot b/cpanfile.snapshot index 19226ce..423a1de 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -36,21 +36,6 @@ DISTRIBUTIONS Canary::Stability 2012 requirements: ExtUtils::MakeMaker 0 - Capture-Tiny-0.46 - pathname: D/DA/DAGOLDEN/Capture-Tiny-0.46.tar.gz - provides: - Capture::Tiny 0.46 - requirements: - Carp 0 - Exporter 0 - ExtUtils::MakeMaker 6.17 - File::Spec 0 - File::Temp 0 - IO::Handle 0 - Scalar::Util 0 - perl 5.006 - strict 0 - warnings 0 Class-Method-Modifiers-2.12 pathname: E/ET/ETHER/Class-Method-Modifiers-2.12.tar.gz provides: @@ -64,13 +49,14 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Clone-0.39 - pathname: G/GA/GARU/Clone-0.39.tar.gz + Clone-Choose-0.010 + pathname: H/HE/HERMES/Clone-Choose-0.010.tar.gz provides: - Clone 0.39 + Clone::Choose 0.010 requirements: ExtUtils::MakeMaker 0 - Test::More 0 + Storable 0 + perl 5.008001 Convert-ASN1-0.27 pathname: G/GB/GBARR/Convert-ASN1-0.27.tar.gz provides: @@ -105,24 +91,24 @@ 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 + DBD-Pg-3.7.4 + pathname: T/TU/TURNSTEP/DBD-Pg-3.7.4.tar.gz provides: - Bundle::DBD::Pg v3.6.2 - DBD::Pg v3.6.2 + Bundle::DBD::Pg v3.7.4 + DBD::Pg v3.7.4 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 + DBD-SQLite-1.58 + pathname: I/IS/ISHIGAKI/DBD-SQLite-1.58.tar.gz provides: - DBD::SQLite 1.54 + DBD::SQLite 1.58 DBD::SQLite::Constants undef - DBD::SQLite::VirtualTable 1.54 - DBD::SQLite::VirtualTable::Cursor 1.54 + DBD::SQLite::VirtualTable 1.58 + DBD::SQLite::VirtualTable::Cursor 1.58 DBD::SQLite::VirtualTable::FileContent undef DBD::SQLite::VirtualTable::FileContent::Cursor undef DBD::SQLite::VirtualTable::PerlData undef @@ -135,8 +121,8 @@ DISTRIBUTIONS Test::More 0.47 Tie::Hash 0 perl 5.006 - DBI-1.636 - pathname: T/TI/TIMB/DBI-1.636.tar.gz + DBI-1.641 + pathname: T/TI/TIMB/DBI-1.641.tar.gz provides: Bundle::DBI 12.008696 DBD::DBM 0.08 @@ -171,6 +157,13 @@ DISTRIBUTIONS DBD::Gofer::db 0.015327 DBD::Gofer::dr 0.015327 DBD::Gofer::st 0.015327 + DBD::Mem 0.001 + DBD::Mem::DataSource 0.001 + DBD::Mem::Statement 0.001 + DBD::Mem::Table 0.001 + DBD::Mem::db 0.001 + DBD::Mem::dr 0.001 + DBD::Mem::st 0.001 DBD::NullP 12.014715 DBD::NullP::db 12.014715 DBD::NullP::dr 12.014715 @@ -185,7 +178,7 @@ DISTRIBUTIONS DBD::Sponge::dr 12.010003 DBD::Sponge::st 12.010003 DBDI 12.015129 - DBI 1.636 + DBI 1.641 DBI::Const::GetInfo::ANSI 2.008697 DBI::Const::GetInfo::ODBC 2.011374 DBI::Const::GetInfoReturn 2.008697 @@ -225,7 +218,7 @@ DISTRIBUTIONS DBI::SQL::Nano::Table_ 1.015544 DBI::Util::CacheMemory 0.010315 DBI::Util::_accessor 0.009479 - DBI::common 1.636 + DBI::common 1.641 requirements: ExtUtils::MakeMaker 6.48 Test::Simple 0.90 @@ -257,10 +250,10 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - Data-Float-0.012 - pathname: Z/ZE/ZEFRAM/Data-Float-0.012.tar.gz + Data-Float-0.013 + pathname: Z/ZE/ZEFRAM/Data-Float-0.013.tar.gz provides: - Data::Float 0.012 + Data::Float 0.013 requirements: Carp 0 Exporter 0 @@ -317,6 +310,7 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 Mail::Address 0 + Net::DNS 0 Scalar::Util 0 Test::More 0 perl 5.006 @@ -329,6 +323,45 @@ DISTRIBUTIONS Encode::Alias 0 ExtUtils::MakeMaker 0 perl 5.008 + ExtUtils-Config-0.008 + pathname: L/LE/LEONT/ExtUtils-Config-0.008.tar.gz + provides: + ExtUtils::Config 0.008 + requirements: + Data::Dumper 0 + ExtUtils::MakeMaker 6.30 + strict 0 + warnings 0 + ExtUtils-Helpers-0.026 + pathname: L/LE/LEONT/ExtUtils-Helpers-0.026.tar.gz + provides: + ExtUtils::Helpers 0.026 + ExtUtils::Helpers::Unix 0.026 + ExtUtils::Helpers::VMS 0.026 + ExtUtils::Helpers::Windows 0.026 + requirements: + Carp 0 + Exporter 5.57 + ExtUtils::MakeMaker 0 + File::Basename 0 + File::Copy 0 + File::Spec::Functions 0 + Text::ParseWords 3.24 + perl 5.006 + strict 0 + warnings 0 + ExtUtils-InstallPaths-0.012 + pathname: L/LE/LEONT/ExtUtils-InstallPaths-0.012.tar.gz + provides: + ExtUtils::InstallPaths 0.012 + requirements: + Carp 0 + ExtUtils::Config 0.002 + ExtUtils::MakeMaker 0 + File::Spec 0 + perl 5.006 + strict 0 + warnings 0 File-Listing-6.04 pathname: G/GA/GAAS/File-Listing-6.04.tar.gz provides: @@ -342,16 +375,17 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 HTTP::Date 6 perl 5.006002 - File-Remove-1.57 - pathname: S/SH/SHLOMIF/File-Remove-1.57.tar.gz + File-Remove-1.58 + pathname: S/SH/SHLOMIF/File-Remove-1.58.tar.gz provides: - File::Remove 1.57 + File::Remove 1.58 requirements: Cwd 3.29 ExtUtils::MakeMaker 0 File::Glob 0 File::Path 0 File::Spec 3.29 + Module::Build 0.28 constant 0 perl 5.006 strict 0 @@ -363,10 +397,10 @@ DISTRIBUTIONS Filesys::DfPortable 0.85 requirements: ExtUtils::MakeMaker 0 - Filesys-DiskUsage-0.10 - pathname: M/MA/MANWAR/Filesys-DiskUsage-0.10.tar.gz + Filesys-DiskUsage-0.11 + pathname: M/MA/MANWAR/Filesys-DiskUsage-0.11.tar.gz provides: - Filesys::DiskUsage 0.10 + Filesys::DiskUsage 0.11 requirements: ExtUtils::MakeMaker 0 File::Basename 0 @@ -396,12 +430,12 @@ DISTRIBUTIONS HTML::Tagset 3.20 requirements: ExtUtils::MakeMaker 0 - HTTP-Cookies-6.03 - pathname: O/OA/OALDERS/HTTP-Cookies-6.03.tar.gz + HTTP-Cookies-6.04 + pathname: O/OA/OALDERS/HTTP-Cookies-6.04.tar.gz provides: - HTTP::Cookies 6.03 - HTTP::Cookies::Microsoft 6.03 - HTTP::Cookies::Netscape 6.03 + HTTP::Cookies 6.04 + HTTP::Cookies::Microsoft 6.04 + HTTP::Cookies::Netscape 6.04 requirements: Carp 0 ExtUtils::MakeMaker 0 @@ -447,19 +481,19 @@ DISTRIBUTIONS perl 5.005 strict 0 warnings 0 - HTTP-Message-6.13 - pathname: O/OA/OALDERS/HTTP-Message-6.13.tar.gz + HTTP-Message-6.18 + pathname: O/OA/OALDERS/HTTP-Message-6.18.tar.gz provides: - HTTP::Config 6.13 - HTTP::Headers 6.13 - HTTP::Headers::Auth 6.13 - HTTP::Headers::ETag 6.13 - HTTP::Headers::Util 6.13 - HTTP::Message 6.13 - HTTP::Request 6.13 - HTTP::Request::Common 6.13 - HTTP::Response 6.13 - HTTP::Status 6.13 + HTTP::Config 6.18 + HTTP::Headers 6.18 + HTTP::Headers::Auth 6.18 + HTTP::Headers::ETag 6.18 + HTTP::Headers::Util 6.18 + HTTP::Message 6.18 + HTTP::Request 6.18 + HTTP::Request::Common 6.18 + HTTP::Response 6.18 + HTTP::Status 6.18 requirements: Carp 0 Compress::Raw::Zlib 0 @@ -493,13 +527,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 + Hash-Merge-0.300 + pathname: R/RE/REHSACK/Hash-Merge-0.300.tar.gz provides: - Hash::Merge 0.200 + Hash::Merge 0.300 requirements: - Clone 0 - ExtUtils::MakeMaker 0 + Clone::Choose 0.008 + ExtUtils::MakeMaker 6.64 + Scalar::Util 0 perl 5.008001 IO-HTML-1.001 pathname: C/CJ/CJM/IO-HTML-1.001.tar.gz @@ -510,28 +545,36 @@ DISTRIBUTIONS Encode 2.10 Exporter 5.57 ExtUtils::MakeMaker 6.30 - IO-Socket-SSL-2.049 - pathname: S/SU/SULLR/IO-Socket-SSL-2.049.tar.gz + IO-Socket-IP-0.39 + pathname: P/PE/PEVANS/IO-Socket-IP-0.39.tar.gz provides: - IO::Socket::SSL 2.049 - IO::Socket::SSL::Intercept 2.014 - IO::Socket::SSL::OCSP_Cache 2.049 - IO::Socket::SSL::OCSP_Resolver 2.049 + IO::Socket::IP 0.39 + requirements: + IO::Socket 0 + Socket 1.97 + Test::More 0.88 + IO-Socket-SSL-2.060 + pathname: S/SU/SULLR/IO-Socket-SSL-2.060.tar.gz + provides: + IO::Socket::SSL 2.060 + IO::Socket::SSL::Intercept 2.056 + IO::Socket::SSL::OCSP_Cache 2.060 + IO::Socket::SSL::OCSP_Resolver 2.060 IO::Socket::SSL::PublicSuffix undef - IO::Socket::SSL::SSL_Context 2.049 - IO::Socket::SSL::SSL_HANDLE 2.049 - IO::Socket::SSL::Session_Cache 2.049 + IO::Socket::SSL::SSL_Context 2.060 + IO::Socket::SSL::SSL_HANDLE 2.060 + IO::Socket::SSL::Session_Cache 2.060 IO::Socket::SSL::Utils 2.014 requirements: ExtUtils::MakeMaker 0 Mozilla::CA 0 Net::SSLeay 1.46 Scalar::Util 0 - JSON-2.94 - pathname: I/IS/ISHIGAKI/JSON-2.94.tar.gz + JSON-2.97001 + pathname: I/IS/ISHIGAKI/JSON-2.97001.tar.gz provides: - JSON 2.94 - JSON::Backend::PP 2.94 + JSON 2.97001 + JSON::Backend::PP 2.97001 requirements: ExtUtils::MakeMaker 0 Test::More 0 @@ -606,12 +649,12 @@ DISTRIBUTIONS File::Basename 0 File::Spec 0 MIME::Types 1.28 - MIME-Types-2.13 - pathname: M/MA/MARKOV/MIME-Types-2.13.tar.gz + MIME-Types-2.17 + pathname: M/MA/MARKOV/MIME-Types-2.17.tar.gz provides: - MIME::Type 2.13 - MIME::Types 2.13 - MojoX::MIME::Types 2.13 + MIME::Type 2.17 + MIME::Types 2.17 + MojoX::MIME::Types 2.17 requirements: ExtUtils::MakeMaker 0 File::Basename 0 @@ -625,31 +668,31 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 perl 5.006 - MailTools-2.18 - pathname: M/MA/MARKOV/MailTools-2.18.tar.gz + MailTools-2.20 + pathname: M/MA/MARKOV/MailTools-2.20.tar.gz provides: - Mail undef - Mail::Address 2.18 - Mail::Cap 2.18 - Mail::Field 2.18 - Mail::Field::AddrList 2.18 - Mail::Field::Date 2.18 - Mail::Field::Generic 2.18 - Mail::Filter 2.18 - Mail::Header 2.18 - Mail::Internet 2.18 - Mail::Mailer 2.18 - Mail::Mailer::qmail 2.18 - Mail::Mailer::rfc822 2.18 - Mail::Mailer::sendmail 2.18 - Mail::Mailer::smtp 2.18 - Mail::Mailer::smtp::pipe 2.18 - Mail::Mailer::smtps 2.18 - Mail::Mailer::smtps::pipe 2.18 - Mail::Mailer::testfile 2.18 - Mail::Mailer::testfile::pipe 2.18 - Mail::Send 2.18 - Mail::Util 2.18 + Mail::Address 2.20 + Mail::Cap 2.20 + Mail::Field 2.20 + Mail::Field::AddrList 2.20 + Mail::Field::Date 2.20 + Mail::Field::Generic 2.20 + Mail::Filter 2.20 + Mail::Header 2.20 + Mail::Internet 2.20 + Mail::Mailer 2.20 + Mail::Mailer::qmail 2.20 + Mail::Mailer::rfc822 2.20 + Mail::Mailer::sendmail 2.20 + Mail::Mailer::smtp 2.20 + Mail::Mailer::smtp::pipe 2.20 + Mail::Mailer::smtps 2.20 + Mail::Mailer::smtps::pipe 2.20 + Mail::Mailer::testfile 2.20 + Mail::Mailer::testfile::pipe 2.20 + Mail::Send 2.20 + Mail::Util 2.20 + MailTools 2.20 requirements: Date::Format 0 Date::Parse 0 @@ -708,33 +751,151 @@ DISTRIBUTIONS Text::ParseWords 0 perl 5.006001 version 0.87 - Module-Runtime-0.015 - pathname: Z/ZE/ZEFRAM/Module-Runtime-0.015.tar.gz + Module-Build-Tiny-0.039 + pathname: L/LE/LEONT/Module-Build-Tiny-0.039.tar.gz provides: - Module::Runtime 0.015 + Module::Build::Tiny 0.039 + requirements: + CPAN::Meta 0 + DynaLoader 0 + Exporter 5.57 + ExtUtils::CBuilder 0 + ExtUtils::Config 0.003 + ExtUtils::Helpers 0.020 + ExtUtils::Install 0 + ExtUtils::InstallPaths 0.002 + ExtUtils::ParseXS 0 + File::Basename 0 + File::Find 0 + File::Path 0 + File::Spec::Functions 0 + Getopt::Long 2.36 + JSON::PP 2 + Pod::Man 0 + TAP::Harness::Env 0 + perl 5.006 + strict 0 + warnings 0 + Module-Install-1.19 + pathname: E/ET/ETHER/Module-Install-1.19.tar.gz + provides: + Module::AutoInstall 1.19 + Module::Install 1.19 + Module::Install::Admin 1.19 + Module::Install::Admin::Bundle 1.19 + Module::Install::Admin::Compiler 1.19 + Module::Install::Admin::Find 1.19 + Module::Install::Admin::Include 1.19 + Module::Install::Admin::Makefile 1.19 + Module::Install::Admin::Manifest 1.19 + Module::Install::Admin::Metadata 1.19 + Module::Install::Admin::ScanDeps 1.19 + Module::Install::Admin::WriteAll 1.19 + Module::Install::AutoInstall 1.19 + Module::Install::Base 1.19 + Module::Install::Base::FakeAdmin 1.19 + Module::Install::Bundle 1.19 + Module::Install::Can 1.19 + Module::Install::Compiler 1.19 + Module::Install::DSL 1.19 + Module::Install::Deprecated 1.19 + Module::Install::External 1.19 + Module::Install::Fetch 1.19 + Module::Install::Include 1.19 + Module::Install::Inline 1.19 + Module::Install::MakeMaker 1.19 + Module::Install::Makefile 1.19 + Module::Install::Metadata 1.19 + Module::Install::PAR 1.19 + Module::Install::Run 1.19 + Module::Install::Scripts 1.19 + Module::Install::Share 1.19 + Module::Install::Win32 1.19 + Module::Install::With 1.19 + Module::Install::WriteAll 1.19 + inc::Module::Install 1.19 + inc::Module::Install::DSL 1.19 + requirements: + Devel::PPPort 3.16 + ExtUtils::Install 1.52 + ExtUtils::MakeMaker 6.59 + ExtUtils::ParseXS 2.19 + File::Path 0 + File::Remove 1.42 + File::Spec 3.28 + Module::Build 0.29 + Module::CoreList 2.17 + Module::ScanDeps 1.09 + Parse::CPAN::Meta 1.4413 + Test::Harness 3.13 + Test::More 0.86 + YAML::Tiny 1.38 + autodie 0 + perl 5.006 + Module-Runtime-0.016 + pathname: Z/ZE/ZEFRAM/Module-Runtime-0.016.tar.gz + provides: + Module::Runtime 0.016 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 + Module-ScanDeps-1.25 + pathname: R/RS/RSCHUPP/Module-ScanDeps-1.25.tar.gz provides: - Mojo::Pg 4.0 + Module::ScanDeps 1.25 + requirements: + ExtUtils::MakeMaker 0 + File::Spec 0 + File::Temp 0 + Getopt::Long 0 + Module::Metadata 0 + Text::ParseWords 0 + perl 5.008001 + version 0 + Mojo-Pg-4.11 + pathname: S/SR/SRI/Mojo-Pg-4.11.tar.gz + provides: + Mojo::Pg 4.11 Mojo::Pg::Database undef Mojo::Pg::Migrations undef Mojo::Pg::PubSub undef Mojo::Pg::Results undef Mojo::Pg::Transaction undef + SQL::Abstract::Pg undef requirements: DBD::Pg 3.005001 ExtUtils::MakeMaker 0 + Mojolicious 8.03 + SQL::Abstract 1.86 + perl 5.010001 + Mojo-SQLite-3.001 + pathname: D/DB/DBOOK/Mojo-SQLite-3.001.tar.gz + provides: + Mojo::SQLite 3.001 + Mojo::SQLite::Database 3.001 + Mojo::SQLite::Migrations 3.001 + Mojo::SQLite::PubSub 3.001 + Mojo::SQLite::Results 3.001 + Mojo::SQLite::Transaction 3.001 + requirements: + Carp 0 + DBD::SQLite 1.54 + DBI 1.627 + File::Spec::Functions 0 + File::Temp 0 + Module::Build::Tiny 0.034 Mojolicious 7.32 SQL::Abstract 1.81 + Scalar::Util 0 + URI 1.69 + URI::db 0.15 + URI::file 4.21 perl 5.010001 - Mojolicious-7.36 - pathname: S/SR/SRI/Mojolicious-7.36.tar.gz + Mojolicious-8.03 + pathname: S/SR/SRI/Mojolicious-8.03.tar.gz provides: Mojo undef Mojo::Asset undef @@ -776,6 +937,7 @@ DISTRIBUTIONS Mojo::Message::Response undef Mojo::Parameters undef Mojo::Path undef + Mojo::Promise undef Mojo::Reactor undef Mojo::Reactor::EV undef Mojo::Reactor::Poll undef @@ -802,23 +964,22 @@ DISTRIBUTIONS Mojo::UserAgent::Transactor undef Mojo::Util undef Mojo::WebSocket undef - Mojolicious 7.36 + Mojolicious 8.03 Mojolicious::Command undef + Mojolicious::Command::Author::cpanify undef + Mojolicious::Command::Author::generate undef + Mojolicious::Command::Author::generate::app undef + Mojolicious::Command::Author::generate::lite_app undef + Mojolicious::Command::Author::generate::makefile undef + Mojolicious::Command::Author::generate::plugin undef + Mojolicious::Command::Author::inflate undef Mojolicious::Command::cgi undef - Mojolicious::Command::cpanify undef Mojolicious::Command::daemon undef Mojolicious::Command::eval undef - Mojolicious::Command::generate undef - Mojolicious::Command::generate::app undef - Mojolicious::Command::generate::lite_app undef - Mojolicious::Command::generate::makefile undef - Mojolicious::Command::generate::plugin undef Mojolicious::Command::get undef - Mojolicious::Command::inflate undef Mojolicious::Command::prefork undef Mojolicious::Command::psgi undef Mojolicious::Command::routes undef - Mojolicious::Command::test undef Mojolicious::Command::version undef Mojolicious::Commands undef Mojolicious::Controller undef @@ -851,13 +1012,14 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 IO::Socket::IP 0.37 JSON::PP 2.27103 + List::Util 1.41 Pod::Simple 3.09 Time::Local 1.2 perl 5.010001 - Mojolicious-Plugin-Authentication-1.32 - pathname: J/JJ/JJATRIA/Mojolicious-Plugin-Authentication-1.32.tar.gz + Mojolicious-Plugin-Authentication-1.33 + pathname: J/JJ/JJATRIA/Mojolicious-Plugin-Authentication-1.33.tar.gz provides: - Mojolicious::Plugin::Authentication 1.32 + Mojolicious::Plugin::Authentication 1.33 requirements: ExtUtils::MakeMaker 0 Mojo::Base 0 @@ -899,20 +1061,20 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 Mojolicious 7.23 - Moo-2.003002 - pathname: H/HA/HAARG/Moo-2.003002.tar.gz + Moo-2.003004 + pathname: H/HA/HAARG/Moo-2.003004.tar.gz provides: Method::Generate::Accessor undef Method::Generate::BuildAll undef Method::Generate::Constructor undef Method::Generate::DemolishAll undef - Moo 2.003002 + Moo 2.003004 Moo::HandleMoose undef Moo::HandleMoose::FakeConstructor undef Moo::HandleMoose::FakeMetaClass undef Moo::HandleMoose::_TypeMap undef Moo::Object undef - Moo::Role 2.003002 + Moo::Role 2.003004 Moo::_Utils undef Moo::_mro undef Moo::_strictures undef @@ -929,21 +1091,137 @@ DISTRIBUTIONS Sub::Defer 2.003001 Sub::Quote 2.003001 perl 5.006 - Mozilla-CA-20160104 - pathname: A/AB/ABH/Mozilla-CA-20160104.tar.gz + Mozilla-CA-20180117 + pathname: A/AB/ABH/Mozilla-CA-20180117.tar.gz provides: - Mozilla::CA 20160104 + Mozilla::CA 20180117 requirements: ExtUtils::MakeMaker 0 Test 0 perl 5.006 - Net-HTTP-6.16 - pathname: O/OA/OALDERS/Net-HTTP-6.16.tar.gz + Net-DNS-1.18 + pathname: N/NL/NLNETLABS/Net-DNS-1.18.tar.gz provides: - Net::HTTP 6.16 - Net::HTTP::Methods 6.16 - Net::HTTP::NB 6.16 - Net::HTTPS 6.16 + Net::DNS 1.18 + Net::DNS::Domain 1698 + Net::DNS::DomainName 1605 + Net::DNS::DomainName1035 1605 + Net::DNS::DomainName2535 1605 + Net::DNS::Header 1709 + Net::DNS::Mailbox 1605 + Net::DNS::Mailbox1035 1605 + Net::DNS::Mailbox2535 1605 + Net::DNS::Nameserver 1692 + Net::DNS::Packet 1714 + Net::DNS::Parameters 1714 + Net::DNS::Question 1714 + Net::DNS::RR 1714 + Net::DNS::RR::A 1597 + Net::DNS::RR::AAAA 1597 + Net::DNS::RR::AFSDB 1597 + Net::DNS::RR::APL 1597 + Net::DNS::RR::APL::Item 1597 + Net::DNS::RR::CAA 1597 + Net::DNS::RR::CDNSKEY 1586 + Net::DNS::RR::CDS 1586 + Net::DNS::RR::CERT 1597 + Net::DNS::RR::CNAME 1597 + Net::DNS::RR::CSYNC 1597 + Net::DNS::RR::DHCID 1597 + Net::DNS::RR::DLV 1528 + Net::DNS::RR::DNAME 1597 + Net::DNS::RR::DNSKEY 1597 + Net::DNS::RR::DS 1597 + Net::DNS::RR::EUI48 1597 + Net::DNS::RR::EUI64 1597 + Net::DNS::RR::GPOS 1528 + Net::DNS::RR::HINFO 1597 + Net::DNS::RR::HIP 1597 + Net::DNS::RR::IPSECKEY 1597 + Net::DNS::RR::ISDN 1597 + Net::DNS::RR::KEY 1528 + Net::DNS::RR::KX 1597 + Net::DNS::RR::L32 1597 + Net::DNS::RR::L64 1597 + Net::DNS::RR::LOC 1597 + Net::DNS::RR::LP 1597 + Net::DNS::RR::MB 1528 + Net::DNS::RR::MG 1528 + Net::DNS::RR::MINFO 1597 + Net::DNS::RR::MR 1528 + Net::DNS::RR::MX 1597 + Net::DNS::RR::NAPTR 1597 + Net::DNS::RR::NID 1597 + Net::DNS::RR::NS 1597 + Net::DNS::RR::NSEC 1696 + Net::DNS::RR::NSEC3 1694 + Net::DNS::RR::NSEC3PARAM 1597 + Net::DNS::RR::NULL 1528 + Net::DNS::RR::OPENPGPKEY 1597 + Net::DNS::RR::OPT 1605 + Net::DNS::RR::OPT::CHAIN 1605 + Net::DNS::RR::OPT::CLIENT_SUBNET 1605 + Net::DNS::RR::OPT::COOKIE 1605 + Net::DNS::RR::OPT::DAU 1605 + Net::DNS::RR::OPT::DHU 1605 + Net::DNS::RR::OPT::EXPIRE 1605 + Net::DNS::RR::OPT::KEY_TAG 1605 + Net::DNS::RR::OPT::N3U 1605 + Net::DNS::RR::OPT::PADDING 1605 + Net::DNS::RR::OPT::TCP_KEEPALIVE 1605 + Net::DNS::RR::PTR 1597 + Net::DNS::RR::PX 1597 + Net::DNS::RR::RP 1597 + Net::DNS::RR::RRSIG 1709 + Net::DNS::RR::RT 1597 + Net::DNS::RR::SIG 1709 + Net::DNS::RR::SMIMEA 1597 + Net::DNS::RR::SOA 1597 + Net::DNS::RR::SPF 1593 + Net::DNS::RR::SRV 1597 + Net::DNS::RR::SSHFP 1597 + Net::DNS::RR::TKEY 1528 + Net::DNS::RR::TLSA 1597 + Net::DNS::RR::TSIG 1597 + Net::DNS::RR::TXT 1597 + Net::DNS::RR::URI 1597 + Net::DNS::RR::X25 1597 + Net::DNS::Resolver 1714 + Net::DNS::Resolver::Base 1709 + Net::DNS::Resolver::MSWin32 1568 + Net::DNS::Resolver::Recurse 1709 + Net::DNS::Resolver::UNIX 1573 + Net::DNS::Resolver::android 1568 + Net::DNS::Resolver::cygwin 1568 + Net::DNS::Resolver::os2 1568 + Net::DNS::Resolver::os390 1579 + Net::DNS::Text 1698 + Net::DNS::Update 1714 + Net::DNS::ZoneFile 1709 + Net::DNS::ZoneFile::Generator 1709 + Net::DNS::ZoneFile::Text 1709 + requirements: + Digest::HMAC 1.03 + Digest::MD5 2.13 + Digest::SHA 5.23 + ExtUtils::MakeMaker 0 + File::Spec 0.86 + IO::File 1.08 + IO::Select 1.14 + IO::Socket::IP 0.38 + MIME::Base64 2.11 + PerlIO 1.05 + Scalar::Util 1.25 + Test::More 0.52 + Time::Local 1.19 + perl 5.006 + Net-HTTP-6.18 + pathname: O/OA/OALDERS/Net-HTTP-6.18.tar.gz + provides: + Net::HTTP 6.18 + Net::HTTP::Methods 6.18 + Net::HTTP::NB 6.18 + Net::HTTPS 6.18 requirements: Carp 0 Compress::Raw::Zlib 0 @@ -956,10 +1234,10 @@ DISTRIBUTIONS strict 0 vars 0 warnings 0 - Net-SSLeay-1.81 - pathname: M/MI/MIKEM/Net-SSLeay-1.81.tar.gz + Net-SSLeay-1.85 + pathname: M/MI/MIKEM/Net-SSLeay-1.85.tar.gz provides: - Net::SSLeay 1.81 + Net::SSLeay 1.85 Net::SSLeay::Handle 0.61 requirements: ExtUtils::MakeMaker 6.36 @@ -975,29 +1253,12 @@ DISTRIBUTIONS ExtUtils::MakeMaker 0 POSIX 0 Test::More 0 - ORLite-1.98 - pathname: A/AD/ADAMK/ORLite-1.98.tar.gz + Params-Classify-0.015 + pathname: Z/ZE/ZEFRAM/Params-Classify-0.015.tar.gz provides: - ORLite 1.98 - requirements: - DBD::SQLite 1.27 - DBI 1.607 - ExtUtils::MakeMaker 6.59 - File::Path 2.08 - File::Remove 1.40 - File::Spec 0.80 - File::Temp 0.20 - Params::Util 1.00 - Test::More 0.47 - Test::Script 1.06 - perl 5.006 - Params-Classify-0.013 - pathname: Z/ZE/ZEFRAM/Params-Classify-0.013.tar.gz - provides: - Params::Classify 0.013 + Params::Classify 0.015 requirements: Exporter 0 - ExtUtils::ParseXS 2.2006 Module::Build 0 Scalar::Util 1.01 Test::More 0 @@ -1005,38 +1266,18 @@ DISTRIBUTIONS perl 5.006001 strict 0 warnings 0 - Params-Util-1.07 - pathname: A/AD/ADAMK/Params-Util-1.07.tar.gz + Role-Tiny-2.000006 + pathname: H/HA/HAARG/Role-Tiny-2.000006.tar.gz provides: - Params::Util 1.07 - requirements: - ExtUtils::CBuilder 0.27 - ExtUtils::MakeMaker 6.52 - File::Spec 0.80 - Scalar::Util 1.18 - Test::More 0.42 - perl 5.00503 - Probe-Perl-0.03 - pathname: K/KW/KWILLIAMS/Probe-Perl-0.03.tar.gz - provides: - Probe::Perl 0.03 - requirements: - Config 0 - 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 + Role::Tiny 2.000006 + Role::Tiny::With 2.000006 requirements: Exporter 5.57 perl 5.006 - SQL-Abstract-1.84 - pathname: I/IL/ILMARI/SQL-Abstract-1.84.tar.gz + SQL-Abstract-1.86 + pathname: I/IL/ILMARI/SQL-Abstract-1.86.tar.gz provides: - SQL::Abstract 1.84 + SQL::Abstract 1.86 SQL::Abstract::Test undef SQL::Abstract::Tree undef requirements: @@ -1049,17 +1290,18 @@ DISTRIBUTIONS Scalar::Util 0 Sub::Quote 2.000001 Text::Balanced 2.00 + perl 5.006 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 + Sub-Quote-2.005001 + pathname: H/HA/HAARG/Sub-Quote-2.005001.tar.gz provides: - Sub::Defer 2.004000 - Sub::Quote 2.004000 + Sub::Defer 2.005001 + Sub::Quote 2.005001 requirements: ExtUtils::MakeMaker 0 Scalar::Util 0 @@ -1097,24 +1339,10 @@ DISTRIBUTIONS Try::Tiny 0.07 strict 0 warnings 0 - Test-Script-1.20 - pathname: P/PL/PLICEASE/Test-Script-1.20.tar.gz + Test-Warn-0.36 + pathname: B/BI/BIGJ/Test-Warn-0.36.tar.gz provides: - Test::Script 1.20 - requirements: - Capture::Tiny 0 - ExtUtils::MakeMaker 0 - File::Spec 0.80 - IO::Handle 0 - Probe::Perl 0.01 - Test::Builder 0.32 - Test::More 0.96 - perl 5.008001 - Test-Warn-0.32 - pathname: B/BI/BIGJ/Test-Warn-0.32.tar.gz - provides: - Test::Warn 0.32 - Test::Warn::Categorization 0.32 + Test::Warn 0.36 requirements: Carp 1.22 ExtUtils::MakeMaker 0 @@ -1172,10 +1400,10 @@ DISTRIBUTIONS Time::Zone 2.24 requirements: ExtUtils::MakeMaker 0 - Try-Tiny-0.28 - pathname: E/ET/ETHER/Try-Tiny-0.28.tar.gz + Try-Tiny-0.30 + pathname: E/ET/ETHER/Try-Tiny-0.30.tar.gz provides: - Try::Tiny 0.28 + Try::Tiny 0.30 requirements: Carp 0 Exporter 5.57 @@ -1184,70 +1412,129 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 - URI-1.71 - pathname: E/ET/ETHER/URI-1.71.tar.gz + URI-1.74 + pathname: E/ET/ETHER/URI-1.74.tar.gz provides: - URI 1.71 + URI 1.74 URI::Escape 3.31 URI::Heuristic 4.20 - URI::IRI 1.71 - URI::QueryParam 1.71 - URI::Split 1.71 + URI::IRI 1.74 + URI::QueryParam 1.74 + URI::Split 1.74 URI::URL 5.04 URI::WithBase 2.20 - URI::_foreign 1.71 - URI::_generic 1.71 - URI::_idna 1.71 - URI::_ldap 1.71 - URI::_login 1.71 - URI::_punycode 1.71 - URI::_query 1.71 - URI::_segment 1.71 - URI::_server 1.71 - URI::_userpass 1.71 - URI::data 1.71 + URI::data 1.74 URI::file 4.21 - URI::file::Base 1.71 - URI::file::FAT 1.71 - URI::file::Mac 1.71 - URI::file::OS2 1.71 - URI::file::QNX 1.71 - URI::file::Unix 1.71 - URI::file::Win32 1.71 - URI::ftp 1.71 - URI::gopher 1.71 - URI::http 1.71 - URI::https 1.71 - URI::ldap 1.71 - URI::ldapi 1.71 - URI::ldaps 1.71 - URI::mailto 1.71 - URI::mms 1.71 - URI::news 1.71 - URI::nntp 1.71 - URI::pop 1.71 - URI::rlogin 1.71 - URI::rsync 1.71 - URI::rtsp 1.71 - URI::rtspu 1.71 - URI::sftp 1.71 - URI::sip 1.71 - URI::sips 1.71 - URI::snews 1.71 - URI::ssh 1.71 - URI::telnet 1.71 - URI::tn3270 1.71 - URI::urn 1.71 - URI::urn::isbn undef - URI::urn::oid 1.71 + URI::file::Base 1.74 + URI::file::FAT 1.74 + URI::file::Mac 1.74 + URI::file::OS2 1.74 + URI::file::QNX 1.74 + URI::file::Unix 1.74 + URI::file::Win32 1.74 + URI::ftp 1.74 + URI::gopher 1.74 + URI::http 1.74 + URI::https 1.74 + URI::ldap 1.74 + URI::ldapi 1.74 + URI::ldaps 1.74 + URI::mailto 1.74 + URI::mms 1.74 + URI::news 1.74 + URI::nntp 1.74 + URI::pop 1.74 + URI::rlogin 1.74 + URI::rsync 1.74 + URI::rtsp 1.74 + URI::rtspu 1.74 + URI::sftp 1.74 + URI::sip 1.74 + URI::sips 1.74 + URI::snews 1.74 + URI::ssh 1.74 + URI::telnet 1.74 + URI::tn3270 1.74 + URI::urn 1.74 + URI::urn::isbn 1.74 + URI::urn::oid 1.74 requirements: + Carp 0 + Cwd 0 + Data::Dumper 0 + Encode 0 Exporter 5.57 ExtUtils::MakeMaker 0 MIME::Base64 2 + Net::Domain 0 Scalar::Util 0 + constant 0 + integer 0 + overload 0 parent 0 perl 5.008001 + strict 0 utf8 0 + warnings 0 + URI-Nested-0.10 + pathname: D/DW/DWHEELER/URI-Nested-0.10.tar.gz + provides: + URI::Nested 0.10 + requirements: + Module::Build 0.30 + Test::More 0.88 + URI 1.40 + perl 5.008001 + URI-db-0.19 + pathname: D/DW/DWHEELER/URI-db-0.19.tar.gz + provides: + URI::cassandra 0.19 + URI::couch 0.19 + URI::couchdb 0.19 + URI::cubrid 0.19 + URI::db 0.19 + URI::db2 0.19 + URI::derby 0.19 + URI::exasol 0.19 + URI::firebird 0.19 + URI::hive 0.19 + URI::impala 0.19 + URI::informix 0.19 + URI::ingres 0.19 + URI::interbase 0.19 + URI::ldapdb 0.19 + URI::maria 0.19 + URI::mariadb 0.19 + URI::max 0.19 + URI::maxdb 0.19 + URI::monet 0.19 + URI::monetdb 0.19 + URI::mongo 0.19 + URI::mongodb 0.19 + URI::mssql 0.19 + URI::mysql 0.19 + URI::oracle 0.19 + URI::pg 0.19 + URI::pgsql 0.19 + URI::pgxc 0.19 + URI::postgres 0.19 + URI::postgresql 0.19 + URI::postgresxc 0.19 + URI::redshift 0.19 + URI::snowflake 0.19 + URI::sqlite 0.19 + URI::sqlite3 0.19 + URI::sqlserver 0.19 + URI::sybase 0.19 + URI::teradata 0.19 + URI::unify 0.19 + URI::vertica 0.19 + requirements: + Module::Build 0.30 + Test::More 0.88 + URI 1.40 + URI::Nested 0.10 + perl 5.008001 WWW-RobotRules-6.02 pathname: G/GA/GAAS/WWW-RobotRules-6.02.tar.gz provides: @@ -1260,53 +1547,55 @@ DISTRIBUTIONS Fcntl 0 URI 1.10 perl 5.008001 - XML-SAX-Base-1.09 - pathname: G/GR/GRANTM/XML-SAX-Base-1.09.tar.gz + YAML-Tiny-1.73 + pathname: E/ET/ETHER/YAML-Tiny-1.73.tar.gz provides: - XML::SAX::Base 1.09 - XML::SAX::Base::NoHandler 1.09 - XML::SAX::Exception 1.09 + YAML::Tiny 1.73 requirements: + B 0 + Carp 0 + Exporter 0 ExtUtils::MakeMaker 0 - perl 5.008 + Fcntl 0 + Scalar::Util 0 + perl 5.008001 + strict 0 + warnings 0 common-sense-3.74 pathname: M/ML/MLEHMANN/common-sense-3.74.tar.gz provides: common::sense 3.74 requirements: ExtUtils::MakeMaker 0 - libwww-perl-6.26 - pathname: O/OA/OALDERS/libwww-perl-6.26.tar.gz + libwww-perl-6.36 + pathname: E/ET/ETHER/libwww-perl-6.36.tar.gz provides: - LWP 6.26 - LWP::Authen::Basic 6.26 - LWP::Authen::Digest 6.26 - LWP::Authen::Ntlm 6.26 - LWP::ConnCache 6.26 - LWP::Debug 6.26 - LWP::Debug::TraceHTTP 6.26 - LWP::Debug::TraceHTTP::Socket 6.26 - LWP::DebugFile 6.26 - LWP::MemberMixin 6.26 - LWP::Protocol 6.26 - LWP::Protocol::MyFTP 6.26 - LWP::Protocol::cpan 6.26 - LWP::Protocol::data 6.26 - LWP::Protocol::file 6.26 - LWP::Protocol::ftp 6.26 - LWP::Protocol::gopher 6.26 - LWP::Protocol::http 6.26 - LWP::Protocol::http::Socket 6.26 - LWP::Protocol::http::SocketMethods 6.26 - LWP::Protocol::loopback 6.26 - LWP::Protocol::mailto 6.26 - LWP::Protocol::nntp 6.26 - LWP::Protocol::nogo 6.26 - LWP::RobotUA 6.26 - LWP::Simple 6.26 - LWP::UserAgent 6.26 + LWP 6.36 + LWP::Authen::Basic 6.36 + LWP::Authen::Digest 6.36 + LWP::Authen::Ntlm 6.36 + LWP::ConnCache 6.36 + LWP::Debug 6.36 + LWP::Debug::TraceHTTP 6.36 + LWP::DebugFile 6.36 + LWP::MemberMixin 6.36 + LWP::Protocol 6.36 + LWP::Protocol::cpan 6.36 + LWP::Protocol::data 6.36 + LWP::Protocol::file 6.36 + LWP::Protocol::ftp 6.36 + LWP::Protocol::gopher 6.36 + LWP::Protocol::http 6.36 + LWP::Protocol::loopback 6.36 + LWP::Protocol::mailto 6.36 + LWP::Protocol::nntp 6.36 + LWP::Protocol::nogo 6.36 + LWP::RobotUA 6.36 + LWP::Simple 6.36 + LWP::UserAgent 6.36 libwww::perl undef requirements: + CPAN::Meta::Requirements 2.120620 Digest::MD5 0 Encode 2.12 Encode::Locale 0 @@ -1323,11 +1612,12 @@ DISTRIBUTIONS HTTP::Request 6 HTTP::Request::Common 6 HTTP::Response 6 - HTTP::Status 6 + HTTP::Status 6.18 IO::Select 0 IO::Socket 0 LWP::MediaTypes 6 MIME::Base64 2.1 + Module::Metadata 0 Net::FTP 2.58 Net::HTTP 6.07 Scalar::Util 0 @@ -1419,5 +1709,4 @@ DISTRIBUTIONS Text::Soundex 0 Time::Local 0 URI::ldap 1.1 - XML::SAX::Base 0 perl 5.008001 diff --git a/lib/Lufi.pm b/lib/Lufi.pm index c046529..bb7103e 100644 --- a/lib/Lufi.pm +++ b/lib/Lufi.pm @@ -31,6 +31,7 @@ sub startup { session_duration => 3600, allow_pwd_on_files => 0, dbtype => 'sqlite', + db_path => 'lufi.db', } }); diff --git a/lib/Lufi/DB/File.pm b/lib/Lufi/DB/File.pm index d323b9e..6ffc001 100644 --- a/lib/Lufi/DB/File.pm +++ b/lib/Lufi/DB/File.pm @@ -1,7 +1,9 @@ # vim:set sw=4 ts=4 sts=4 ft=perl expandtab: package Lufi::DB::File; use Mojo::Base -base; -use Mojo::Collection; +use Mojo::File; +use Mojo::Collection 'c'; +use Lufi::DB::Slice; has 'short'; has 'deleted' => 0; @@ -23,6 +25,7 @@ has 'slices' => sub { return Mojo::Collection->new(); }; has 'passwd'; +has 'record' => 0; has 'app'; =head1 NAME @@ -160,6 +163,21 @@ sub delete { =back +=cut + +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); + } 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->record(1); + } + + return $c; +} + =head2 count_empty =over 1 @@ -174,6 +192,14 @@ sub delete { =back +=cut + +sub count_empty { + my $c = shift; + + return $c->app->dbi->db->query('SELECT count(short) AS count FROM files WHERE created_at IS NULL')->hashes->first->{count}; +} + =head2 already_exists =over 1 @@ -188,6 +214,15 @@ sub delete { =back +=cut + +sub already_exists { + my $c = shift; + my $short = shift; + + return $c->app->dbi->db->query('SELECT count(short) AS count FROM files WHERE short = ?', $short)->hashes->first->{count}; +} + =head2 get_empty =over 1 @@ -202,6 +237,16 @@ sub delete { =back +=cut + +sub get_empty { + my $c = shift; + + my $r = $c->app->dbi->db->query('SELECT * FROM files WHERE created_at IS NULL')->hashes->shuffle->first; + + return $c->_slurp($r)->created_at(time)->write; +} + =head2 get_stats =over 1 @@ -216,6 +261,18 @@ sub delete { =back +=cut + +sub get_stats { + my $c = shift; + + my $files = $c->app->dbi->db->query('SELECT count(short) AS count FROM files WHERE created_at IS NOT null AND deleted = ?', 0)->hashes->first->{count}; + my $deleted = $c->app->dbi->db->query('SELECT count(short) AS count FROM files WHERE created_at IS NOT null AND deleted = ?', 1)->hashes->first->{count}; + my $empty = $c->app->dbi->db->query('SELECT count(short) AS count FROM files WHERE created_at IS null')->hashes->first->{count}; + + return { files => $files, deleted => $deleted, empty => $empty }; +} + =head2 from_short =over 1 @@ -230,6 +287,21 @@ sub delete { =back +=cut + +sub from_short { + my $c = shift; + my $short = shift; + + my $r = $c->app->dbi->db->query('SELECT * FROM files WHERE short = ?', $short)->hashes; + + if ($r->size) { + return $c->_slurp($r->first)->record(1); + } else { + return undef; + } +} + =head2 get_oldest_undeleted_files =over 1 @@ -244,6 +316,26 @@ sub delete { =back +=cut + +sub get_oldest_undeleted_files { + my $c = shift; + my $num = shift; + + my @files; + my $records = $c->app->dbi->db->query('SELECT * FROM files WHERE deleted = ? ORDER BY created_at ASC LIMIT ?', 0, $num)->hashes; + $records->each( + sub { + my ($e, $num) = @_; + my $i = Lufi::DB::File->new(app => $c->app); + + push @files, $i->_slurp($e); + } + ); + + return c(@files); +} + =head2 get_expired =over 1 @@ -258,6 +350,27 @@ sub delete { =back +=cut + +sub get_expired { + my $c = shift; + my $time = shift; + + my @files; + ## Select only files expired since two days, to be sure that nobody is still downloading it + my $records = $c->app->dbi->db->query('SELECT * FROM files WHERE deleted = ? AND ((delete_at_day + 2) * 86400) < (? - created_at) AND delete_at_day != 0', 0, $time)->hashes; + $records->each( + sub { + my ($e, $num) = @_; + my $i = Lufi::DB::File->new(app => $c->app); + + push @files, $i->_slurp($e); + } + ); + + return c(@files); +} + =head2 get_no_longer_viewed =over 1 @@ -272,6 +385,26 @@ sub delete { =back +=cut + +sub get_no_longer_viewed { + my $c = shift; + my $time = shift; + + my @files; + my $records = $c->app->dbi->db->query('SELECT * FROM files WHERE deleted = ? AND last_access_at < ?', 0, $time)->hashes; + $records->each( + sub { + my ($e, $num) = @_; + my $i = Lufi::DB::File->new(app => $c->app); + + push @files, $i->_slurp($e); + } + ); + + return c(@files); +} + =head2 delete_creator_before =over 1 @@ -288,4 +421,67 @@ sub delete { =cut +sub delete_creator_before { + my $c = shift; + my $separation = shift; + + $c->app->dbi->db->query('UPDATE files SET created_by = NULL WHERE created_by IS NOT NULL AND created_at < ?', $separation); +} + +=head2 _slurp + +=over 1 + +=item B : C<$c-E_slurp> + +=item B : none + +=item B : put a database record's columns into the Lufi::DB::File object's attributes + +=item B : the Lufi::DB::File object + +=back + +=cut + +sub _slurp { + my $c = shift; + my $r = shift; + + my $file; + if (defined $r) { + $file = $r; + } else { + my $files = $c->app->dbi->db->query('SELECT * FROM files WHERE short = ?', $c->short)->hashes; + + if ($files->size) { + $file = $files->first; + } + } + + if ($file) { + $c->short($file->{short}); + $c->deleted($file->{deleted}); + $c->mediatype($file->{mediatype}); + $c->filename($file->{filename}); + $c->filesize($file->{filesize}); + $c->counter($file->{counter}); + $c->delete_at_first_view($file->{delete_at_first_view}); + $c->delete_at_day($file->{delete_at_day}); + $c->created_at($file->{created_at}); + $c->created_by($file->{created_by}); + $c->last_access_at($file->{last_access_at}); + $c->mod_token($file->{mod_token}); + $c->nbslices($file->{nbslices}); + $c->complete($file->{complete}); + $c->passwd($file->{passwd}); + + $c->record(1) unless $c->record; + } + + $c->slices(Lufi::DB::Slice->new(app => $c->app)->get_slices_of_file($c->short)); + + return $c; +} + 1; diff --git a/lib/Lufi/DB/File/Pg.pm b/lib/Lufi/DB/File/Pg.pm index 62967f7..925c9e2 100644 --- a/lib/Lufi/DB/File/Pg.pm +++ b/lib/Lufi/DB/File/Pg.pm @@ -1,11 +1,6 @@ # vim:set sw=4 ts=4 sts=4 ft=perl expandtab: package Lufi::DB::File::Pg; use Mojo::Base 'Lufi::DB::File'; -use Mojo::File; -use Mojo::Collection 'c'; -use Lufi::DB::Slice; - -has 'record' => 0; sub new { my $c = shift; @@ -15,163 +10,4 @@ sub new { return $c; } -sub write { - my $c = shift; - - if ($c->record) { - $c->app->pg->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); - } else { - $c->app->pg->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->record(1); - } - - return $c; -} - -sub count_empty { - my $c = shift; - - return $c->app->pg->db->query('SELECT count(short) FROM files WHERE created_at IS NULL')->hashes->first->{count}; -} - -sub already_exists { - my $c = shift; - my $short = shift; - - return $c->app->pg->db->query('SELECT count(short) FROM files WHERE short = ?', $short)->hashes->first->{count}; -} - -sub get_empty { - my $c = shift; - - my $r = $c->app->pg->db->query('SELECT * FROM files WHERE created_at IS NULL')->hashes->shuffle->first; - - return $c->_slurp($r)->created_at(time)->write; -} - -sub get_stats { - my $c = shift; - - my $files = $c->app->pg->db->query('SELECT count(short) FROM files WHERE created_at IS NOT null AND deleted = false')->hashes->first->{count}; - my $deleted = $c->app->pg->db->query('SELECT count(short) FROM files WHERE created_at IS NOT null AND deleted = true')->hashes->first->{count}; - my $empty = $c->app->pg->db->query('SELECT count(short) FROM files WHERE created_at IS null')->hashes->first->{count}; - - return { files => $files, deleted => $deleted, empty => $empty }; -} - -sub from_short { - my $c = shift; - my $short = shift; - - my $r = $c->app->pg->db->query('SELECT * FROM files WHERE short = ?', $short)->hashes; - - if ($r->size) { - return $c->_slurp($r->first)->record(1); - } else { - return undef; - } -} - -sub get_oldest_undeleted_files { - my $c = shift; - my $num = shift; - - my @files; - my $records = $c->app->pg->db->query('SELECT * FROM files WHERE deleted = false ORDER BY created_at ASC LIMIT ?', $num)->hashes; - $records->each( - sub { - my ($e, $num) = @_; - my $i = Lufi::DB::File->new(app => $c->app); - - push @files, $i->_slurp($e); - } - ); - - return c(@files); -} - -sub get_expired { - my $c = shift; - my $time = shift; - - my @files; - ## Select only files expired since two days, to be sure that nobody is still downloading it - my $records = $c->app->pg->db->query('SELECT * FROM files WHERE deleted = false AND ((delete_at_day + 2) * 86400) < (? - created_at) AND delete_at_day != 0', $time)->hashes; - $records->each( - sub { - my ($e, $num) = @_; - my $i = Lufi::DB::File->new(app => $c->app); - - push @files, $i->_slurp($e); - } - ); - - return c(@files); -} - -sub get_no_longer_viewed { - my $c = shift; - my $time = shift; - - my @files; - my $records = $c->app->pg->db->query('SELECT * FROM files WHERE deleted = false AND last_access_at < ?', $time)->hashes; - $records->each( - sub { - my ($e, $num) = @_; - my $i = Lufi::DB::File->new(app => $c->app); - - push @files, $i->_slurp($e); - } - ); - - return c(@files); -} - -sub delete_creator_before { - my $c = shift; - my $separation = shift; - - $c->app->pg->db->query('UPDATE files SET created_by = NULL WHERE created_by IS NOT NULL AND created_at < ?', $separation); -} - -sub _slurp { - my $c = shift; - my $r = shift; - - my $file; - if (defined $r) { - $file = $r; - } else { - my $files = $c->app->pg->db->query('SELECT * FROM files WHERE short = ?', $c->short)->hashes; - - if ($files->size) { - $file = $files->first; - } - } - - if ($file) { - $c->short($file->{short}); - $c->deleted($file->{deleted}); - $c->mediatype($file->{mediatype}); - $c->filename($file->{filename}); - $c->filesize($file->{filesize}); - $c->counter($file->{counter}); - $c->delete_at_first_view($file->{delete_at_first_view}); - $c->delete_at_day($file->{delete_at_day}); - $c->created_at($file->{created_at}); - $c->created_by($file->{created_by}); - $c->last_access_at($file->{last_access_at}); - $c->mod_token($file->{mod_token}); - $c->nbslices($file->{nbslices}); - $c->complete($file->{complete}); - $c->passwd($file->{passwd}); - - $c->record(1) unless $c->record; - } - - $c->slices(Lufi::DB::Slice->new(app => $c->app)->get_slices_of_file($c->short)); - - return $c; -} - 1; diff --git a/lib/Lufi/DB/File/SQLite.pm b/lib/Lufi/DB/File/SQLite.pm index 47eface..4a896a8 100644 --- a/lib/Lufi/DB/File/SQLite.pm +++ b/lib/Lufi/DB/File/SQLite.pm @@ -1,12 +1,7 @@ # 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; @@ -17,172 +12,4 @@ sub new { 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'); - - return $c->record($records[0])->_slurp->created_at(time)->write; -} - -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 = Lufi::DB::SQLite::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 = Lufi::DB::SQLite::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; diff --git a/lib/Lufi/DB/SQLite.pm b/lib/Lufi/DB/SQLite.pm deleted file mode 100644 index 4553f56..0000000 --- a/lib/Lufi/DB/SQLite.pm +++ /dev/null @@ -1,64 +0,0 @@ -# vim:set sw=4 ts=4 sts=4 ft=perl expandtab: -package Lufi::DB::SQLite; -use Mojolicious; -use Mojo::File; -use FindBin qw($Bin); - -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 => $cfile->to_abs->to_string, - default => { - db_path => 'lufi.db' - } - } - ); -} - -# Create database -use ORLite { - file => $config->{db_path}, - unicode => 1, - create => sub { - my $dbh = shift; - $dbh->do( - 'CREATE TABLE files ( - short TEXT PRIMARY KEY, - deleted INTEGER, - mediatype TEXT, - filename TEXT, - filesize INTEGER, - counter INTEGER, - delete_at_first_view INTEGER, - delete_at_day INTEGER, - created_at INTEGER, - created_by TEXT, - last_access_at INTEGER, - mod_token TEXT, - nbslices INTEGER, - complete INTEGER, - passwd TEXT)' - ); - $dbh->do( - 'CREATE TABLE slices ( - short TEXT, - j INTEGER, - path TEXT, - FOREIGN KEY (short) REFERENCES files(short))' - ); - $dbh->do( - 'CREATE INDEX slices_idx ON slices(short)' - ); - return 1; - } -}; - -1; diff --git a/lib/Lufi/DB/Slice.pm b/lib/Lufi/DB/Slice.pm index b350071..cf3d136 100644 --- a/lib/Lufi/DB/Slice.pm +++ b/lib/Lufi/DB/Slice.pm @@ -1,10 +1,12 @@ # vim:set sw=4 ts=4 sts=4 ft=perl expandtab: package Lufi::DB::Slice; use Mojo::Base -base; +use Mojo::Collection 'c'; has 'short'; has 'j'; has 'path'; +has 'record' => 0; has 'app'; =head1 NAME @@ -85,6 +87,21 @@ sub new { =back +=cut + +sub write { + my $c = shift; + + if ($c->record) { + $c->app->dbi->db->query('UPDATE slices SET short = ?, j = ?, path = ? WHERE short = ? AND j = ?', $c->short, $c->j, $c->path, $c->short, $c->j); + } else { + $c->app->dbi->db->query('INSERT INTO slices (short, j, path) VALUES (?, ?, ?)', $c->short, $c->j, $c->path); + $c->record(1); + } + + return $c; +} + =head2 get_slices_of_file =over 1 @@ -101,4 +118,64 @@ sub new { =cut +sub get_slices_of_file { + my $c = shift; + my $short = shift; + + my @slices; + my $records = $c->app->dbi->db->query('SELECT * FROM slices WHERE short = ? ORDER BY j ASC', $short)->hashes; + $records->each( + sub { + my ($e, $num) = @_; + my $i = Lufi::DB::Slice->new(app => $c->app); + + push @slices, $i->_slurp($e); + } + ); + + return c(@slices); +} + +=head2 _slurp + +=over 1 + +=item B : C<$c-E_slurp> + +=item B : none + +=item B : put a database record's columns into the Lufi::DB::Slice object's attributes + +=item B : the Lufi::DB::Slice object + +=back + +=cut + +sub _slurp { + my $c = shift; + my $r = shift; + + my $slice; + if (defined $r) { + $slice = $r; + } else { + my $slices = $c->app->dbi->db->query('SELECT * FROM slices WHERE short = ? AND j = ?', $c->short, $c->j)->hashes; + + if ($slices->size) { + $slice = $slices->first; + } + } + + if ($slice) { + $c->short($slice->{short}); + $c->j($slice->{j}); + $c->path($slice->{path}); + + $c->record(1); + } + + return $c; +} + 1; diff --git a/lib/Lufi/DB/Slice/Pg.pm b/lib/Lufi/DB/Slice/Pg.pm index 5744b49..defdf27 100644 --- a/lib/Lufi/DB/Slice/Pg.pm +++ b/lib/Lufi/DB/Slice/Pg.pm @@ -1,9 +1,6 @@ # vim:set sw=4 ts=4 sts=4 ft=perl expandtab: package Lufi::DB::Slice::Pg; use Mojo::Base 'Lufi::DB::Slice'; -use Mojo::Collection 'c'; - -has 'record' => 0; sub new { my $c = shift; @@ -13,61 +10,4 @@ sub new { return $c; } -sub write { - my $c = shift; - - if ($c->record) { - $c->app->pg->db->query('UPDATE slices SET short = ?, j = ?, path = ? WHERE short = ? AND j = ?', $c->short, $c->j, $c->path, $c->short, $c->j); - } else { - $c->app->pg->db->query('INSERT INTO slices (short, j, path) VALUES (?, ?, ?)', $c->short, $c->j, $c->path); - $c->record(1); - } - - return $c; -} - -sub get_slices_of_file { - my $c = shift; - my $short = shift; - - my @slices; - my $records = $c->app->pg->db->query('SELECT * FROM slices WHERE short = ? ORDER BY j ASC', $short)->hashes; - $records->each( - sub { - my ($e, $num) = @_; - my $i = Lufi::DB::Slice->new(app => $c->app); - - push @slices, $i->_slurp($e); - } - ); - - return c(@slices); -} - -sub _slurp { - my $c = shift; - my $r = shift; - - my $slice; - if (defined $r) { - $slice = $r; - } else { - my $slices = $c->app->pg->db->query('SELECT * FROM slices WHERE short = ? AND j = ?', $c->short, $c->j)->hashes; - - if ($slices->size) { - $slice = $slices->first; - } - } - - if ($slice) { - $c->short($slice->{short}); - $c->j($slice->{j}); - $c->path($slice->{path}); - - $c->record(1); - } - - return $c; -} - 1; diff --git a/lib/Lufi/DB/Slice/SQLite.pm b/lib/Lufi/DB/Slice/SQLite.pm index 5927f9b..d65ed26 100644 --- a/lib/Lufi/DB/Slice/SQLite.pm +++ b/lib/Lufi/DB/Slice/SQLite.pm @@ -1,10 +1,6 @@ # vim:set sw=4 ts=4 sts=4 ft=perl expandtab: package Lufi::DB::Slice::SQLite; use Mojo::Base 'Lufi::DB::Slice'; -use Lufi::DB::SQLite; -use Mojo::Collection 'c'; - -has 'record'; sub new { my $c = shift; @@ -16,44 +12,4 @@ sub new { return $c; } -sub write { - my $c = shift; - - if (defined $c->record) { - $c->record->update( - short => $c->short, - j => $c->j, - path => $c->path - ); - } else { - my $record = Lufi::DB::SQLite::Slices->create( - short => $c->short, - j => $c->j, - path => $c->path - ); - $c->record($record); - } - - 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; - - $c->short($c->record->short) if defined $c->record->short; - $c->j($c->record->j) if defined $c->record->j; - $c->path($c->record->path) if defined $c->record->path; - - return $c; -} - 1; diff --git a/lib/Lufi/Plugin/Helpers.pm b/lib/Lufi/Plugin/Helpers.pm index 518f3fe..55ebcdf 100644 --- a/lib/Lufi/Plugin/Helpers.pm +++ b/lib/Lufi/Plugin/Helpers.pm @@ -7,49 +7,66 @@ use Data::Entropy qw(entropy_source); sub register { my ($self, $app) = @_; - $app->plugin('PgURLHelper'); + # PgURL helper + if ($app->config('dbtype') eq 'postgresql' || $app->config('dbtype') eq 'mysql') { + $app->plugin('PgURLHelper'); + } + if ($app->config('dbtype') eq 'postgresql') { - use Mojo::Pg; - $app->helper(pg => \&_pg); + require Mojo::Pg; + $app->helper(dbi => \&_pg); # Database migration - my $migrations = Mojo::Pg::Migrations->new(pg => $app->pg); + 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(1); } else { - $migrations->from_file('utilities/migrations_pg.sql')->migrate(1); + $migrations->from_file('utilities/migrations/pg.sql')->migrate(1); } } elsif ($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'; + require Mojo::SQLite; + $app->helper(dbi => \&_sqlite); + + # Database migration + # Have to create $sql before using its migrations attribute, otherwise, it won't work + 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); + } else { + $migrations->from_file('utilities/migrations/sqlite.sql')->migrate(1); } - unless ($pwd_col) { - Lufi::DB::SQLite->do('ALTER TABLE files ADD COLUMN passwd TEXT;'); + 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'); } } - $app->helper(provisioning => \&_provisioning); - $app->helper(get_empty => \&_get_empty); - $app->helper(shortener => \&_shortener); - $app->helper(ip => \&_ip); + $app->helper(provisioning => \&_provisioning); + $app->helper(get_empty => \&_get_empty); + $app->helper(shortener => \&_shortener); + $app->helper(ip => \&_ip); $app->helper(default_delay => \&_default_delay); - $app->helper(max_delay => \&_max_delay); - $app->helper(is_selected => \&_is_selected); - $app->helper(stop_upload => \&_stop_upload); + $app->helper(max_delay => \&_max_delay); + $app->helper(is_selected => \&_is_selected); + $app->helper(stop_upload => \&_stop_upload); } sub _pg { - my $c = shift; + my $c = shift; state $pg = Mojo::Pg->new($c->app->pg_url($c->app->config('pgdb'))); return $pg; } +sub _sqlite { + my $c = shift; + + state $sqlite = Mojo::SQLite->new('sqlite:'.$c->app->config('db_path')); + return $sqlite; +} + sub _provisioning { my $c = shift; diff --git a/lib/Mounter.pm b/lib/Mounter.pm index dce85a0..7b172ec 100644 --- a/lib/Mounter.pm +++ b/lib/Mounter.pm @@ -23,6 +23,24 @@ sub startup { prefix => '/', theme => 'default', dbtype => 'sqlite', + prefix => '/', + provisioning => 100, + provis_step => 5, + length => 10, + token_length => 32, + secrets => ['hfudsifdsih'], + default_delay => 0, + max_delay => 0, + mail => { + how => 'sendmail' + }, + mail_sender => 'no-reply@lufi.io', + theme => 'default', + upload_dir => 'files', + session_duration => 3600, + allow_pwd_on_files => 0, + dbtype => 'sqlite', + db_path => 'lufi.db', } } ); diff --git a/lufi.conf.template b/lufi.conf.template index 64df2be..86a779a 100644 --- a/lufi.conf.template +++ b/lufi.conf.template @@ -7,7 +7,7 @@ hypnotoad => { # array of IP addresses and ports you want to listen to listen => ['http://127.0.0.1:8081'], - # if you use Lufi behind a reverse proxy like Nginx, you want ro set proxy to 1 + # if you use Lufi behind a reverse proxy like Nginx, you want to set proxy to 1 # if you use Lufi directly, let it commented #proxy => 1, diff --git a/themes/default/lib/Lufi/I18N/ca.po b/themes/default/lib/Lufi/I18N/ca.po index 4e45272..a90ace2 100644 --- a/themes/default/lib/Lufi/I18N/ca.po +++ b/themes/default/lib/Lufi/I18N/ca.po @@ -304,7 +304,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:199 +#: lib/Lufi.pm:200 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -345,7 +345,7 @@ msgstr "Compartiu fitxers amb total privacitat a %1" msgid "Signin" msgstr "Autenticació" -#: lib/Lufi.pm:202 +#: lib/Lufi.pm:203 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 "" diff --git a/themes/default/lib/Lufi/I18N/en.po b/themes/default/lib/Lufi/I18N/en.po index 92915a0..faaaf12 100644 --- a/themes/default/lib/Lufi/I18N/en.po +++ b/themes/default/lib/Lufi/I18N/en.po @@ -300,7 +300,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:199 +#: lib/Lufi.pm:200 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -341,7 +341,7 @@ msgstr "" msgid "Signin" msgstr "" -#: lib/Lufi.pm:202 +#: lib/Lufi.pm:203 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 "" diff --git a/themes/default/lib/Lufi/I18N/fr.po b/themes/default/lib/Lufi/I18N/fr.po index d2c24d2..63c74db 100644 --- a/themes/default/lib/Lufi/I18N/fr.po +++ b/themes/default/lib/Lufi/I18N/fr.po @@ -302,7 +302,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:199 +#: lib/Lufi.pm:200 msgid "Please, check your credentials: unable to authenticate." msgstr "Veuillez vérifier vos identifiants : impossible de vous authentifier." @@ -343,7 +343,7 @@ msgstr "Partagez vos fichiers en toute confidentialité sur %1" msgid "Signin" msgstr "Connexion" -#: lib/Lufi.pm:202 +#: lib/Lufi.pm:203 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." diff --git a/themes/default/lib/Lufi/I18N/it.po b/themes/default/lib/Lufi/I18N/it.po index 6030a39..1eec9b8 100644 --- a/themes/default/lib/Lufi/I18N/it.po +++ b/themes/default/lib/Lufi/I18N/it.po @@ -302,7 +302,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:199 +#: lib/Lufi.pm:200 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -347,7 +347,7 @@ msgstr "Condividi tutti i file in totale riservatezza su %1" msgid "Signin" msgstr "Autenticazione" -#: lib/Lufi.pm:202 +#: lib/Lufi.pm:203 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 "" diff --git a/themes/default/lib/Lufi/I18N/nl.po b/themes/default/lib/Lufi/I18N/nl.po index d3099da..c00216f 100644 --- a/themes/default/lib/Lufi/I18N/nl.po +++ b/themes/default/lib/Lufi/I18N/nl.po @@ -289,7 +289,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:199 +#: lib/Lufi.pm:200 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -334,7 +334,7 @@ msgstr "Deel je bestanden met volledige privacy op %1" msgid "Signin" msgstr "Inloggen" -#: lib/Lufi.pm:202 +#: lib/Lufi.pm:203 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 "" diff --git a/themes/default/lib/Lufi/I18N/oc.po b/themes/default/lib/Lufi/I18N/oc.po index aa6867c..18394d7 100644 --- a/themes/default/lib/Lufi/I18N/oc.po +++ b/themes/default/lib/Lufi/I18N/oc.po @@ -302,7 +302,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:199 +#: lib/Lufi.pm:200 msgid "Please, check your credentials: unable to authenticate." msgstr "Mercés de verificar vòstres identificants : impossible de vos autentificar." @@ -343,7 +343,7 @@ msgstr "Partejatz vòstres fichièrs en tota confidencialitat sus %1" msgid "Signin" msgstr "Connexion" -#: lib/Lufi.pm:202 +#: lib/Lufi.pm:203 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 "O planhèm collèga, sètz pas autorizat a utilizar aqueste servici. Contactatz vòstre administrator sistèma se pensatz que i a un problèma." diff --git a/themes/default/lib/Lufi/I18N/pt.po b/themes/default/lib/Lufi/I18N/pt.po index c87e965..ce69143 100644 --- a/themes/default/lib/Lufi/I18N/pt.po +++ b/themes/default/lib/Lufi/I18N/pt.po @@ -311,7 +311,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:199 +#: lib/Lufi.pm:200 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -352,7 +352,7 @@ msgstr "Partilhe os seus ficheiros com toda a privacidade em %1" msgid "Signin" msgstr "Conexão" -#: lib/Lufi.pm:202 +#: lib/Lufi.pm:203 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 "" diff --git a/utilities/migrations/pg.sql b/utilities/migrations/pg.sql new file mode 100644 index 0000000..5406a18 --- /dev/null +++ b/utilities/migrations/pg.sql @@ -0,0 +1,28 @@ +-- 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 NOT NULL REFERENCES files(short) ON DELETE CASCADE, + j integer NOT NULL, + path text unique NOT NULL, + constraint slice_short_j UNIQUE (short, j) +); +-- 1 down +DROP TABLE slices; +DROP TABLE files; diff --git a/utilities/migrations/sqlite.sql b/utilities/migrations/sqlite.sql new file mode 100644 index 0000000..90584f1 --- /dev/null +++ b/utilities/migrations/sqlite.sql @@ -0,0 +1,28 @@ +-- 1 up +CREATE TABLE IF NOT EXISTS files ( + short TEXT PRIMARY KEY, + deleted INTEGER, + mediatype TEXT, + filename TEXT, + filesize INTEGER, + counter INTEGER, + delete_at_first_view INTEGER, + delete_at_day INTEGER, + created_at INTEGER, + created_by TEXT, + last_access_at INTEGER, + mod_token TEXT, + nbslices INTEGER, + complete INTEGER +); +CREATE TABLE IF NOT EXISTS slices ( + short TEXT, + j INTEGER, + path TEXT, + FOREIGN KEY (short) REFERENCES files(short) +); +CREATE INDEX IF NOT EXISTS slices_idx ON slices(short); +-- 1 down +DROP INDEX slices_idx ON slices(short); +DROP TABLE slices; +DROP TABLE files; diff --git a/utilities/migrations_pg.sql b/utilities/migrations_pg.sql deleted file mode 100644 index 3ceeef9..0000000 --- a/utilities/migrations_pg.sql +++ /dev/null @@ -1,28 +0,0 @@ --- 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 NOT NULL REFERENCES files(short) ON DELETE CASCADE, - j integer NOT NULL, - path text unique NOT NULL, - constraint slice_short_j UNIQUE (short, j) -); --- 1 down -DROP TABLE slices; -DROP TABLE files; From 13e8553cf421bc31ef03c11216b8276f5687f743 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 21 Oct 2018 12:48:39 +0200 Subject: [PATCH 09/49] Use FiatTux plugins WARNING! LDAP configuration has changed! Check lufi.conf.template --- CHANGELOG | 1 + cpanfile | 2 + lib/Lufi.pm | 74 ++---------------------------- lufi.conf.template | 12 ++--- themes/default/lib/Lufi/I18N/ca.po | 4 +- themes/default/lib/Lufi/I18N/en.po | 4 +- themes/default/lib/Lufi/I18N/fr.po | 4 +- themes/default/lib/Lufi/I18N/it.po | 4 +- themes/default/lib/Lufi/I18N/nl.po | 4 +- themes/default/lib/Lufi/I18N/oc.po | 4 +- themes/default/lib/Lufi/I18N/pt.po | 4 +- 11 files changed, 28 insertions(+), 89 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index acebc26..089cf3b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ Revision history for Lufi 0.03 2018-??-?? - Use Mojo::SQLite instead of ORLite + - Use FiatTux plugins 0.02.2 2017-09-18 - Fix cron tasks bug diff --git a/cpanfile b/cpanfile index 3ab3ad7..18ed30a 100644 --- a/cpanfile +++ b/cpanfile @@ -3,6 +3,8 @@ requires 'Mojolicious', '>= 7.31'; requires 'Mojolicious::Plugin::DebugDumperHelper'; requires 'Mojolicious::Plugin::I18N'; requires 'Mojolicious::Plugin::Mail'; +requires 'Mojolicious::Plugin::FiatTux::Helpers', '== 0.01', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-helpers/-/archive/0.01/mojolicious-plugin-fiattux-helpers-0.01.tar.gz'; +requires 'Mojolicious::Plugin::FiatTux::GrantAccess', '== 0.01', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-grantaccess/-/archive/0.01/mojolicious-plugin-fiattux-grantaccess-0.01.tar.gz'; requires 'EV'; requires 'Filesys::DiskUsage'; requires 'Switch'; diff --git a/lib/Lufi.pm b/lib/Lufi.pm index bb7103e..6c70d21 100644 --- a/lib/Lufi.pm +++ b/lib/Lufi.pm @@ -66,82 +66,18 @@ sub startup { # Debug $self->plugin('DebugDumperHelper'); - # Check htpasswd file existence - die 'Unable to read '.$self->config('htpasswd') if (defined($self->config('htpasswd')) && !-r $self->config('htpasswd')); + # Fiat Tux helpers + $self->plugin('FiatTux::Helpers'); - # Authentication (if configured) - $self->plugin('authentication' => - { - autoload_user => 1, - session_key => 'Dolomon', - load_user => sub { - my ($c, $username) = @_; - - return $username; - }, - validate_user => sub { - my ($c, $username, $password, $extradata) = @_; - - if (defined($c->config('ldap'))) { - my $ldap = Net::LDAP->new($c->config->{ldap}->{uri}); - my $mesg = $ldap->bind($c->config->{ldap}->{bind_user}.$c->config->{ldap}->{bind_dn}, - password => $c->config->{ldap}->{bind_pwd} - ); - - $mesg->code && die $mesg->error; - - $mesg = $ldap->search( - base => $c->config->{ldap}->{user_tree}, - filter => "(&(uid=$username)".$c->config->{ldap}->{user_filter}.")" - ); - - if ($mesg->code) { - $c->app->log->error($mesg->error); - return undef; - } - - # we filtered out, but did we actually get a non-empty result? - $entry = $mesg->shift_entry; - if (!defined $entry) { - $c->app->log->info("[LDAP authentication failed] - User $username filtered out, IP: ".$c->ip); - return undef; - } - - # Now we know that the user exists, and that he is authorized by the filter - $mesg = $ldap->bind('uid='.$username.$c->config->{ldap}->{bind_dn}, - password => $password - ); - - if ($mesg->code) { - $c->app->log->info("[LDAP authentication failed] login: $username, IP: ".$c->ip); - $c->app->log->error("[LDAP authentication failed] ".$mesg->error); - return undef; - } - - $c->app->log->info("[LDAP authentication successful] login: $username, IP: ".$c->ip); - } elsif (defined($c->config('htpasswd'))) { - my $htpasswd = new Apache::Htpasswd({passwdFile => $c->config->{htpasswd}, - ReadOnly => 1} - ); - if (!$htpasswd->htCheckPassword($username, $password)) { - return undef; - } - $c->app->log->info("[Simple authentication successful] login: $username, IP: ".$c->ip); - } - - return $username; - } - } - ); - if (defined($self->config('ldap')) || defined($self->config('htpasswd'))) { - $self->app->sessions->default_expiration($self->config('session_duration')); - } + # Authentication + $self->plugin('FiatTux::GrantAccess'); # Secrets $self->secrets($self->config('secrets')); # Helpers $self->plugin('Lufi::Plugin::Helpers'); + # Hooks $self->hook( after_dispatch => sub { diff --git a/lufi.conf.template b/lufi.conf.template index 86a779a..a7c6fbc 100644 --- a/lufi.conf.template +++ b/lufi.conf.template @@ -140,12 +140,12 @@ # please note that everybody can still download files # optional, no default #ldap => { - # uri => 'ldaps://ldap.example.org', - # user_tree => 'ou=users,dc=example,dc=org', - # bind_dn => ',ou=users,dc=example,dc=org', - # bind_user => 'uid=ldap_user', - # bind_pwd => 'secr3t', - # user_filter => '!(uid=ldap_user)' + # uri => 'ldaps://ldap.example.org', # server URI + # user_tree => 'ou=users,dc=example,dc=org', # search base DN + # bind_dn => 'uid=ldap_user,ou=users,dc=example,dc=org', # search bind DN + # bind_pwd => 'secr3t', # search bind password + # user_attr => 'uid', # user attribute (uid, mail, sAMAccountName, etc.) + # user_filter => '(!(uid=ldap_user))', # user filter (to exclude some users, etc.) #}, # set `htpasswd` if you want to use an htpasswd file instead of ldap diff --git a/themes/default/lib/Lufi/I18N/ca.po b/themes/default/lib/Lufi/I18N/ca.po index a90ace2..6be53a7 100644 --- a/themes/default/lib/Lufi/I18N/ca.po +++ b/themes/default/lib/Lufi/I18N/ca.po @@ -304,7 +304,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:200 +#: lib/Lufi.pm:136 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -345,7 +345,7 @@ msgstr "Compartiu fitxers amb total privacitat a %1" msgid "Signin" msgstr "Autenticació" -#: lib/Lufi.pm:203 +#: lib/Lufi.pm:139 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 "" diff --git a/themes/default/lib/Lufi/I18N/en.po b/themes/default/lib/Lufi/I18N/en.po index faaaf12..11559b9 100644 --- a/themes/default/lib/Lufi/I18N/en.po +++ b/themes/default/lib/Lufi/I18N/en.po @@ -300,7 +300,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:200 +#: lib/Lufi.pm:136 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -341,7 +341,7 @@ msgstr "" msgid "Signin" msgstr "" -#: lib/Lufi.pm:203 +#: lib/Lufi.pm:139 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 "" diff --git a/themes/default/lib/Lufi/I18N/fr.po b/themes/default/lib/Lufi/I18N/fr.po index 63c74db..5e21644 100644 --- a/themes/default/lib/Lufi/I18N/fr.po +++ b/themes/default/lib/Lufi/I18N/fr.po @@ -302,7 +302,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:200 +#: lib/Lufi.pm:136 msgid "Please, check your credentials: unable to authenticate." msgstr "Veuillez vérifier vos identifiants : impossible de vous authentifier." @@ -343,7 +343,7 @@ msgstr "Partagez vos fichiers en toute confidentialité sur %1" msgid "Signin" msgstr "Connexion" -#: lib/Lufi.pm:203 +#: lib/Lufi.pm:139 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." diff --git a/themes/default/lib/Lufi/I18N/it.po b/themes/default/lib/Lufi/I18N/it.po index 1eec9b8..5833ef0 100644 --- a/themes/default/lib/Lufi/I18N/it.po +++ b/themes/default/lib/Lufi/I18N/it.po @@ -302,7 +302,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:200 +#: lib/Lufi.pm:136 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -347,7 +347,7 @@ msgstr "Condividi tutti i file in totale riservatezza su %1" msgid "Signin" msgstr "Autenticazione" -#: lib/Lufi.pm:203 +#: lib/Lufi.pm:139 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 "" diff --git a/themes/default/lib/Lufi/I18N/nl.po b/themes/default/lib/Lufi/I18N/nl.po index c00216f..290516b 100644 --- a/themes/default/lib/Lufi/I18N/nl.po +++ b/themes/default/lib/Lufi/I18N/nl.po @@ -289,7 +289,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:200 +#: lib/Lufi.pm:136 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -334,7 +334,7 @@ msgstr "Deel je bestanden met volledige privacy op %1" msgid "Signin" msgstr "Inloggen" -#: lib/Lufi.pm:203 +#: lib/Lufi.pm:139 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 "" diff --git a/themes/default/lib/Lufi/I18N/oc.po b/themes/default/lib/Lufi/I18N/oc.po index 18394d7..333a33a 100644 --- a/themes/default/lib/Lufi/I18N/oc.po +++ b/themes/default/lib/Lufi/I18N/oc.po @@ -302,7 +302,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:200 +#: lib/Lufi.pm:136 msgid "Please, check your credentials: unable to authenticate." msgstr "Mercés de verificar vòstres identificants : impossible de vos autentificar." @@ -343,7 +343,7 @@ msgstr "Partejatz vòstres fichièrs en tota confidencialitat sus %1" msgid "Signin" msgstr "Connexion" -#: lib/Lufi.pm:203 +#: lib/Lufi.pm:139 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 "O planhèm collèga, sètz pas autorizat a utilizar aqueste servici. Contactatz vòstre administrator sistèma se pensatz que i a un problèma." diff --git a/themes/default/lib/Lufi/I18N/pt.po b/themes/default/lib/Lufi/I18N/pt.po index ce69143..36a7951 100644 --- a/themes/default/lib/Lufi/I18N/pt.po +++ b/themes/default/lib/Lufi/I18N/pt.po @@ -311,7 +311,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:200 +#: lib/Lufi.pm:136 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -352,7 +352,7 @@ msgstr "Partilhe os seus ficheiros com toda a privacidade em %1" msgid "Signin" msgstr "Conexão" -#: lib/Lufi.pm:203 +#: lib/Lufi.pm:139 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 "" From c2e9268cc731775a104620d66705fea180d9e8f8 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 21 Oct 2018 14:20:51 +0200 Subject: [PATCH 10/49] Fix #123 - Option to force "Burn after reading" for each uploaded file --- CHANGELOG | 1 + cpanfile | 2 +- cpanfile.snapshot | 2 +- lib/Lufi.pm | 43 ++++--- lib/Lufi/Controller/Files.pm | 4 +- lib/Mounter.pm | 39 +++--- lufi.conf.template | 6 +- themes/default/lib/Lufi/I18N/ca.po | 114 +++++++++--------- themes/default/lib/Lufi/I18N/en.po | 114 +++++++++--------- themes/default/lib/Lufi/I18N/fr.po | 114 +++++++++--------- themes/default/lib/Lufi/I18N/it.po | 114 +++++++++--------- themes/default/lib/Lufi/I18N/nl.po | 114 +++++++++--------- themes/default/lib/Lufi/I18N/oc.po | 114 +++++++++--------- themes/default/lib/Lufi/I18N/pt.po | 114 +++++++++--------- themes/default/public/css/lufi.css | 4 + themes/default/public/js/ie-detection.js | 29 +++++ themes/default/public/js/sidenav.js | 3 + themes/default/templates/files.html.ep | 17 +-- themes/default/templates/index.html.ep | 46 ++----- .../default/templates/layouts/default.html.ep | 38 +----- themes/default/templates/mail.html.ep | 60 +-------- themes/default/templates/partial/files.js.ep | 16 +++ themes/default/templates/partial/index.js.ep | 30 +++++ themes/default/templates/partial/mail.js.ep | 58 +++++++++ themes/default/templates/partial/render.js.ep | 11 ++ themes/default/templates/render.html.ep | 13 +- 26 files changed, 640 insertions(+), 580 deletions(-) create mode 100644 themes/default/public/js/ie-detection.js create mode 100644 themes/default/public/js/sidenav.js create mode 100644 themes/default/templates/partial/files.js.ep create mode 100644 themes/default/templates/partial/index.js.ep create mode 100644 themes/default/templates/partial/mail.js.ep create mode 100644 themes/default/templates/partial/render.js.ep diff --git a/CHANGELOG b/CHANGELOG index 089cf3b..328fea3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ Revision history for Lufi 0.03 2018-??-?? - Use Mojo::SQLite instead of ORLite - Use FiatTux plugins + - Option to force "Burn after reading" for each uploaded file 0.02.2 2017-09-18 - Fix cron tasks bug diff --git a/cpanfile b/cpanfile index 18ed30a..4659f35 100644 --- a/cpanfile +++ b/cpanfile @@ -4,7 +4,7 @@ requires 'Mojolicious::Plugin::DebugDumperHelper'; requires 'Mojolicious::Plugin::I18N'; requires 'Mojolicious::Plugin::Mail'; requires 'Mojolicious::Plugin::FiatTux::Helpers', '== 0.01', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-helpers/-/archive/0.01/mojolicious-plugin-fiattux-helpers-0.01.tar.gz'; -requires 'Mojolicious::Plugin::FiatTux::GrantAccess', '== 0.01', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-grantaccess/-/archive/0.01/mojolicious-plugin-fiattux-grantaccess-0.01.tar.gz'; +requires 'Mojolicious::Plugin::FiatTux::GrantAccess', '== 0.03', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-grantaccess/-/archive/0.03/mojolicious-plugin-fiattux-grantaccess-0.03.tar.gz'; requires 'EV'; requires 'Filesys::DiskUsage'; requires 'Switch'; diff --git a/cpanfile.snapshot b/cpanfile.snapshot index 423a1de..7c983f9 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -986,7 +986,6 @@ DISTRIBUTIONS Mojolicious::Lite undef Mojolicious::Plugin undef Mojolicious::Plugin::Config undef - Mojolicious::Plugin::Config::Sandbox undef Mojolicious::Plugin::DefaultHelpers undef Mojolicious::Plugin::EPLRenderer undef Mojolicious::Plugin::EPRenderer undef @@ -1690,6 +1689,7 @@ DISTRIBUTIONS requirements: Authen::SASL 2.00 Convert::ASN1 0.2 + Digest::HMAC_MD5 0 Digest::MD5 0 ExtUtils::MakeMaker 6.42 File::Basename 0 diff --git a/lib/Lufi.pm b/lib/Lufi.pm index 6c70d21..1cf7437 100644 --- a/lib/Lufi.pm +++ b/lib/Lufi.pm @@ -14,24 +14,25 @@ sub startup { my $config = $self->plugin('Config' => { default => { - prefix => '/', - provisioning => 100, - provis_step => 5, - length => 10, - token_length => 32, - secrets => ['hfudsifdsih'], - default_delay => 0, - max_delay => 0, - mail => { + prefix => '/', + provisioning => 100, + provis_step => 5, + length => 10, + token_length => 32, + secrets => ['hfudsifdsih'], + default_delay => 0, + max_delay => 0, + mail => { how => 'sendmail' }, - mail_sender => 'no-reply@lufi.io', - theme => 'default', - upload_dir => 'files', - session_duration => 3600, - allow_pwd_on_files => 0, - dbtype => 'sqlite', - db_path => 'lufi.db', + mail_sender => 'no-reply@lufi.io', + theme => 'default', + upload_dir => 'files', + session_duration => 3600, + allow_pwd_on_files => 0, + dbtype => 'sqlite', + db_path => 'lufi.db', + force_burn_after_reading => 0, } }); @@ -155,6 +156,16 @@ sub startup { shift->render(template => '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'); + # Get instance stats $r->get('/fullstats') ->to('Misc#fullstats') diff --git a/lib/Lufi/Controller/Files.pm b/lib/Lufi/Controller/Files.pm index 7841268..d4ed027 100644 --- a/lib/Lufi/Controller/Files.pm +++ b/lib/Lufi/Controller/Files.pm @@ -111,9 +111,11 @@ sub upload { if (defined($c->config('ldap')) || defined($c->config('htpasswd'))) { $creator = 'User: '.$c->current_user.', IP: '.$creator; } + my $delete_at_first_view = ($json->{del_at_first_view}) ? 1 : 0; + $delete_at_first_view = 1 if $c->app->config('force_burn_after_reading'); $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_first_view($delete_at_first_view) ->delete_at_day($delay) ->mediatype($json->{type}) ->filename($json->{name}) diff --git a/lib/Mounter.pm b/lib/Mounter.pm index 7b172ec..ab5b097 100644 --- a/lib/Mounter.pm +++ b/lib/Mounter.pm @@ -20,27 +20,28 @@ sub startup { { file => $cfile, default => { - prefix => '/', - theme => 'default', - dbtype => 'sqlite', - prefix => '/', - provisioning => 100, - provis_step => 5, - length => 10, - token_length => 32, - secrets => ['hfudsifdsih'], - default_delay => 0, - max_delay => 0, - mail => { + prefix => '/', + theme => 'default', + dbtype => 'sqlite', + prefix => '/', + provisioning => 100, + provis_step => 5, + length => 10, + token_length => 32, + secrets => ['hfudsifdsih'], + default_delay => 0, + max_delay => 0, + mail => { how => 'sendmail' }, - mail_sender => 'no-reply@lufi.io', - theme => 'default', - upload_dir => 'files', - session_duration => 3600, - allow_pwd_on_files => 0, - dbtype => 'sqlite', - db_path => 'lufi.db', + mail_sender => 'no-reply@lufi.io', + theme => 'default', + upload_dir => 'files', + session_duration => 3600, + allow_pwd_on_files => 0, + dbtype => 'sqlite', + db_path => 'lufi.db', + force_burn_after_reading => 0, } } ); diff --git a/lufi.conf.template b/lufi.conf.template index a7c6fbc..22649d0 100644 --- a/lufi.conf.template +++ b/lufi.conf.template @@ -158,9 +158,13 @@ #session_duration => 3600, # allow to add a password on files, asked before allowing to download files - # optional, default to 0 + # optional, default is 0 #allow_pwd_on_files => 0, + # force all files to be in "Burn after reading mode" + # optional, default is 0 + #force_burn_after_reading => 0, + # if set, the files' URLs will always use this domain # optional #fixed_domain => 'example.org', diff --git a/themes/default/lib/Lufi/I18N/ca.po b/themes/default/lib/Lufi/I18N/ca.po index 6be53a7..17b72ae 100644 --- a/themes/default/lib/Lufi/I18N/ca.po +++ b/themes/default/lib/Lufi/I18N/ca.po @@ -32,7 +32,7 @@ msgstr "1 any" msgid "24 hours" msgstr "24 hores" -#: themes/default/templates/mail.html.ep:83 +#: themes/default/templates/partial/mail.js.ep:35 msgid ":" msgstr ":" @@ -44,11 +44,11 @@ msgstr "Un agraïment amb la foto d'un gatet a AGPLv3, el podeu instal·lar al vostre propi servidor. Pel que fa a com fer-ho, feu un cop d'ull al Wiki." #. (stash('f') -#: themes/default/templates/render.html.ep:52 +#: 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" @@ -69,11 +69,11 @@ msgstr "Retorna a la pàgina d'inici" msgid "Bad CSRF token!" msgstr "Mal testimoni CSRF!" -#: themes/default/templates/render.html.ep:48 +#: themes/default/templates/partial/render.js.ep:5 msgid "Click here to refresh the page and restart the download." msgstr "Premeu aquí per tal de refrescar la pàgina i reiniciar la descàrrega" -#: themes/default/templates/index.html.ep:80 +#: themes/default/templates/index.html.ep:90 msgid "Click to open the file browser" msgstr "Premeu per obrir la selecció de fitxer." @@ -85,23 +85,23 @@ msgstr "Tanca" msgid "Comma-separated email addresses" msgstr "Adreces de correu electrònic separades per comes" -#: themes/default/templates/index.html.ep:105 +#: themes/default/templates/partial/index.js.ep:15 msgid "Copy all links to clipboard" msgstr "Copia tots els enllaços al porta-retalls" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/partial/index.js.ep:18 msgid "Copy to clipboard" msgstr "Copia al porta-retalls" -#: lib/Lufi/Controller/Files.pm:429 +#: lib/Lufi/Controller/Files.pm:431 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:411 +#: lib/Lufi/Controller/Files.pm:413 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:322 +#: lib/Lufi/Controller/Files.pm:324 msgid "Could not find the file. Are you sure of the URL?" msgstr "No trobo el fitxer. Esteu segurs de la URL?" @@ -109,7 +109,7 @@ msgstr "No trobo el fitxer. Esteu segurs de la URL?" msgid "Counter" msgstr "Comptador" -#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:64 +#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:74 msgid "Delete at first download?" msgstr "Eliminar-lo a la primera descàrrega?" @@ -117,7 +117,7 @@ msgstr "Eliminar-lo a la primera descàrrega?" msgid "Delete selected files" msgstr "" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 +#: themes/default/templates/files.html.ep:32 themes/default/templates/partial/index.js.ep:19 msgid "Deletion link" msgstr "Enllaç per a eliminació" @@ -125,15 +125,15 @@ msgstr "Enllaç per a eliminació" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "No patiu per si un usuari comença a descarregar el fitxer abans de l'expiració i la descàrrega acaba després de l'expiració, encara podrà obtenir el fitxer." -#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 +#: themes/default/templates/partial/index.js.ep:21 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Descàrrega" -#: themes/default/templates/render.html.ep:47 +#: themes/default/templates/partial/render.js.ep:4 msgid "Download aborted." msgstr "Descàrrega avortada." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 +#: themes/default/templates/files.html.ep:27 themes/default/templates/partial/index.js.ep:20 msgid "Download link" msgstr "Enllaç per a descàrrega" @@ -141,7 +141,7 @@ msgstr "Enllaç per a descàrrega" msgid "Drag and drop files in the appropriate area or use the traditional way to send files and the files will be chunked, encrypted and sent to the server. You will get two links per file: a download link, that you give to the people you want to share the file with and a deletion link, allowing you to delete the file whenever you want." msgstr "Arrossegueu i deixeu anar fitxers a l'àrea apropiada o useu el sistema tradicional per enviar fitxers, i seran trossejats, xifrats i enviats al servidor. Obtindreu dos enllaços per a cada fitxer: un enllaç per a la descàrrega, que doneu a la gent amb qui voleu compartir el fitxer, i un enllaç per a l'eliminació, que us permet eliminar el fitxer del servidor quan vulgueu. " -#: themes/default/templates/index.html.ep:77 +#: themes/default/templates/index.html.ep:87 msgid "Drop files here" msgstr "Deixeu anar aquí fitxers." @@ -157,23 +157,23 @@ msgstr "Assumpte del correu electrònic" msgid "Emails" msgstr "correus electrònics" -#: themes/default/templates/index.html.ep:112 +#: themes/default/templates/partial/index.js.ep:22 msgid "Encrypting part XX1 of XX2" msgstr "S'està xifrant la part XX1 de XX2" -#: lib/Lufi/Controller/Files.pm:225 +#: lib/Lufi/Controller/Files.pm:227 msgid "Error: the file existed but was deleted." msgstr "Error: el fitxer existia però va ser eliminat." -#: lib/Lufi/Controller/Files.pm:291 +#: lib/Lufi/Controller/Files.pm:293 msgid "Error: the file has not been sent entirely." msgstr "Error: el fitxer no s'ha enviat del tot." -#: lib/Lufi/Controller/Files.pm:301 +#: lib/Lufi/Controller/Files.pm:303 msgid "Error: unable to find the file. Are you sure of your URL?" msgstr "Error: no trobo el fitxer. Esteu segur de la URL ?" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/partial/index.js.ep:23 msgid "Expiration:" msgstr "Expiració:" @@ -185,7 +185,7 @@ msgstr "Expira el" msgid "Export localStorage data" msgstr "Exporta dades a l'emmagatzematge local" -#: lib/Lufi/Controller/Files.pm:393 +#: lib/Lufi/Controller/Files.pm:395 msgid "File deleted" msgstr "Fitxer eliminat" @@ -193,7 +193,11 @@ msgstr "Fitxer eliminat" msgid "File name" msgstr "Nom de fitxer" -#: themes/default/templates/render.html.ep:51 +#: themes/default/templates/index.html.ep:64 +msgid "Files deleted at first download" +msgstr "" + +#: themes/default/templates/partial/render.js.ep:8 msgid "Get the file" msgstr "Obté el fitxer" @@ -201,7 +205,7 @@ msgstr "Obté el fitxer" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Obteniu el codi font al repositori oficial o a la seva rèplica a Github" -#: themes/default/templates/mail.html.ep:78 +#: themes/default/templates/partial/mail.js.ep:30 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Hola,\\n\\nVe't aquí uns fitxers que vull compartir amb tu:" @@ -209,11 +213,11 @@ msgstr "Hola,\\n\\nVe't aquí uns fitxers que vull compartir amb tu:" msgid "Here's some files" msgstr "Ve't aquí uns fitxers" -#: themes/default/templates/index.html.ep:115 +#: themes/default/templates/partial/index.js.ep:25 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Prem Retorn, i després Ctrl+C per copiar tots els enllaços de descàrrega" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/partial/index.js.ep:24 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Prem Retorn, i després Ctrl+C per copiar l'enllaç de descàrrega" @@ -250,7 +254,7 @@ msgstr "Importat: més informació sobre moratòries" msgid "Information about delays" msgstr "Informació sobre moratòries" -#: themes/default/templates/render.html.ep:49 +#: themes/default/templates/partial/render.js.ep:6 msgid "It seems that the key in your URL is incorrect. Please, verify your URL." msgstr "Sembla que la clau a l'URL és incorrecta. Si us plau, verifiqueu l'URL." @@ -262,7 +266,7 @@ msgstr "Teniu el javascript deactivat. No podreu usar Lufi." msgid "Login" msgstr "Entrada" -#: themes/default/templates/layouts/default.html.ep:67 themes/default/templates/layouts/default.html.ep:79 +#: themes/default/templates/layouts/default.html.ep:37 themes/default/templates/layouts/default.html.ep:49 msgid "Logout" msgstr "Sortida" @@ -274,7 +278,7 @@ msgstr "Lufi és programari lliure d'allotjament de fitxers." msgid "Mail" msgstr "" -#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:61 themes/default/templates/layouts/default.html.ep:73 +#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:31 themes/default/templates/layouts/default.html.ep:43 msgid "My files" msgstr "Els meus fitxers" @@ -283,7 +287,7 @@ msgstr "Els meus fitxers" 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)" -#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 +#: themes/default/templates/partial/files.js.ep:10 themes/default/templates/partial/index.js.ep:27 msgid "No expiration delay" msgstr "Sense moratòria d'expiració" @@ -291,7 +295,7 @@ msgstr "Sense moratòria d'expiració" msgid "Only the files sent with this browser will be listed here. This list is stored in localStorage: if you delete your localStorage data, you'll lose this list." msgstr "Aquí només apareixen els fitxers enviats amb aquest navegador. La llista es desa en emmagatzematge local: si netegeu l'emmagatzematge local perdreu aquesta llista." -#: themes/default/templates/index.html.ep:70 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 +#: themes/default/templates/index.html.ep:80 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 msgid "Password" msgstr "Contrasenya" @@ -304,7 +308,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:136 +#: lib/Lufi.pm:137 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -320,7 +324,7 @@ msgstr "Netegeu els fitxers expirats de l'emmagatzematge local." msgid "Rows in red mean that the files have expired and are no longer available." msgstr "Les files en vermell indiquen que els fitxers han expirat i ja no són disponibles." -#: themes/default/templates/index.html.ep:116 +#: themes/default/templates/partial/index.js.ep:26 msgid "Send all links by email" msgstr "Envia tots els enllaços per correu electrònic" @@ -332,20 +336,20 @@ msgstr "Envia amb aquest servidor" msgid "Send with your own mail software" msgstr "Envia amb el vostre propi programa de correu" -#: themes/default/templates/index.html.ep:118 +#: themes/default/templates/partial/index.js.ep:28 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "S'està enviant el tros XX1 de XX2. Si us plau, paciència; la barra de progrés pot trigar una mica a bellugar-se. " #. (url_for('/') -#: themes/default/templates/mail.html.ep:91 +#: themes/default/templates/partial/mail.js.ep:43 msgid "Share your files in total privacy on %1" msgstr "Compartiu fitxers amb total privacitat a %1" -#: themes/default/templates/layouts/default.html.ep:63 themes/default/templates/layouts/default.html.ep:75 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 +#: themes/default/templates/layouts/default.html.ep:33 themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 msgid "Signin" msgstr "Autenticació" -#: lib/Lufi.pm:139 +#: lib/Lufi.pm:140 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 "" @@ -363,7 +367,7 @@ msgstr "" "L'administrador només pot veure el nom del fitxer, la seva mida i el seu\n" "mimetype (quina mena de fitxer és: vídeo, text, etc.)" -#: themes/default/templates/files.html.ep:51 +#: themes/default/templates/partial/files.js.ep:11 msgid "The data has been successfully imported." msgstr "La importació de les dades ha reeixit." @@ -375,7 +379,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:390 +#: lib/Lufi/Controller/Files.pm:392 msgid "The file has already been deleted" msgstr "El fitxer ja ha estat esborrat" @@ -388,7 +392,7 @@ msgstr "Els fitxers que es pugen a una instaŀlació de Lufi són xifrats abans msgid "The following email addresses are not valid: %1" msgstr "Les següents adreces de correu electrònic no són vàlides: %1" -#: themes/default/templates/index.html.ep:106 +#: themes/default/templates/partial/index.js.ep:16 msgid "The link(s) has been copied to your clipboard" msgstr "L'enllaç/ els enllaços ja estan copiats al portaretalls" @@ -400,7 +404,7 @@ msgstr "El correu ja està enviat." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "L'autor original (i per ara l'únic) és Luc Didry. Si voleu fer una contribució podeu fer-ho via Tipeee o via Liberapay." -#: lib/Lufi/Controller/Files.pm:179 +#: lib/Lufi/Controller/Files.pm:181 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." @@ -408,26 +412,26 @@ msgstr "El servidor no ha pogut trobar el registre del fitxer per afegir-hi el t 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:" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/partial/index.js.ep: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:361 +#: lib/Lufi/Controller/Files.pm:363 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:351 +#: lib/Lufi/Controller/Files.pm:353 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:371 +#: lib/Lufi/Controller/Files.pm:373 msgid "Unable to get counter for %1. You are not authenticated." msgstr "No he pogut obtenir el comptador de %1. No esteu autenticat." -#: themes/default/templates/layouts/default.html.ep:60 themes/default/templates/layouts/default.html.ep:72 +#: themes/default/templates/layouts/default.html.ep:30 themes/default/templates/layouts/default.html.ep:42 msgid "Upload files" msgstr "Pujar fitxers" @@ -435,11 +439,11 @@ msgstr "Pujar fitxers" msgid "Uploaded at" msgstr "Pujat a les" -#: themes/default/templates/index.html.ep:85 +#: themes/default/templates/index.html.ep:95 msgid "Uploaded files" msgstr "Fitxers pujats" -#: themes/default/templates/index.html.ep:119 +#: themes/default/templates/partial/index.js.ep:29 msgid "Websocket communication error" msgstr "Error de comunicacions del websocket" @@ -459,15 +463,15 @@ msgstr "Podeu veure la llista dels vostres fitxers amb a l'enllaç \"Els meus fi msgid "You don't need to register yourself to upload files but be aware that, for legal reasons, your IP address will be stored when you send a file. Don't panic, this is normally the case for all sites on which you send files." msgstr "No cal que us inscriviu per a pujar fitxers però tingueu en compte, que per raons legals, s'enregistrarà la vostra adreça IP quan envieu un fitxer. No us espanteu, això és el que normalment passa a tots els webs on pugeu fitxers." -#: themes/default/templates/render.html.ep:53 +#: themes/default/templates/partial/render.js.ep:10 msgid "You don't seem to have a key in your URL. You won't be able to decrypt the file. Download canceled." msgstr "No sembla que hi hagi una clau a la URL. No podreu desxifrar el fitxer. Descàrrega canceŀlada." -#: themes/default/templates/render.html.ep:50 +#: themes/default/templates/partial/render.js.ep:7 msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Heu intentat deixar aquesta pàgina. Es canceŀlarà la descàrrega. N'esteu segur?" -#: themes/default/templates/index.html.ep:104 +#: themes/default/templates/partial/index.js.ep:14 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Heu intentat deixar aquesta pàgina. Es canceŀlarà la pujada. N'esteu segur?" @@ -484,7 +488,7 @@ msgstr "Heu de donar l'adreça de correu electrònic." 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:273 +#: lib/Lufi/Controller/Files.pm:275 msgid "Your password is not valid. Please refresh the page to retry." msgstr "" @@ -498,7 +502,7 @@ msgstr "entre %1 i %2, el fitxer es mantindrà %3 dia/es al servidor." msgid "between %1 and %2, the file will be kept forever." msgstr "entre %1 i %2, el fitxer es mantindrà per sempre al servidor." -#: themes/default/templates/mail.html.ep:85 +#: themes/default/templates/partial/mail.js.ep:37 msgid "deadline: " msgstr "termini:" @@ -516,6 +520,6 @@ msgstr "a partir de %1, el fitxer es mantindrà per sempre al servidor." msgid "no time limit" msgstr "no hi ha límit de temps" -#: themes/default/templates/index.html.ep:78 +#: themes/default/templates/index.html.ep:88 msgid "or" msgstr "o" diff --git a/themes/default/lib/Lufi/I18N/en.po b/themes/default/lib/Lufi/I18N/en.po index 11559b9..d9f5822 100644 --- a/themes/default/lib/Lufi/I18N/en.po +++ b/themes/default/lib/Lufi/I18N/en.po @@ -29,7 +29,7 @@ msgstr "" msgid "24 hours" msgstr "" -#: themes/default/templates/mail.html.ep:83 +#: themes/default/templates/partial/mail.js.ep:35 msgid ":" msgstr "" @@ -41,11 +41,11 @@ msgstr "" msgid "Abort" msgstr "" -#: themes/default/templates/layouts/default.html.ep:65 themes/default/templates/layouts/default.html.ep:77 +#: themes/default/templates/layouts/default.html.ep:35 themes/default/templates/layouts/default.html.ep:47 msgid "About" msgstr "" -#: themes/default/templates/index.html.ep:71 +#: themes/default/templates/index.html.ep:81 msgid "Add a password to file(s)" msgstr "" @@ -54,7 +54,7 @@ msgid "As Lufi is a free software licensed under of the terms of the the official repository or on its Github mirror" msgstr "" -#: themes/default/templates/mail.html.ep:78 +#: themes/default/templates/partial/mail.js.ep:30 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "" @@ -206,11 +210,11 @@ msgstr "" msgid "Here's some files" msgstr "" -#: themes/default/templates/index.html.ep:115 +#: themes/default/templates/partial/index.js.ep:25 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/partial/index.js.ep:24 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "" @@ -246,7 +250,7 @@ msgstr "" msgid "Information about delays" msgstr "" -#: themes/default/templates/render.html.ep:49 +#: themes/default/templates/partial/render.js.ep:6 msgid "It seems that the key in your URL is incorrect. Please, verify your URL." msgstr "" @@ -258,7 +262,7 @@ msgstr "" msgid "Login" msgstr "" -#: themes/default/templates/layouts/default.html.ep:67 themes/default/templates/layouts/default.html.ep:79 +#: themes/default/templates/layouts/default.html.ep:37 themes/default/templates/layouts/default.html.ep:49 msgid "Logout" msgstr "" @@ -270,7 +274,7 @@ msgstr "" msgid "Mail" msgstr "" -#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:61 themes/default/templates/layouts/default.html.ep:73 +#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:31 themes/default/templates/layouts/default.html.ep:43 msgid "My files" msgstr "" @@ -279,7 +283,7 @@ msgstr "" msgid "No enough space available on the server for this file (size: %1)." msgstr "" -#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 +#: themes/default/templates/partial/files.js.ep:10 themes/default/templates/partial/index.js.ep:27 msgid "No expiration delay" msgstr "" @@ -287,7 +291,7 @@ msgstr "" msgid "Only the files sent with this browser will be listed here. This list is stored in localStorage: if you delete your localStorage data, you'll lose this list." msgstr "" -#: themes/default/templates/index.html.ep:70 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 +#: themes/default/templates/index.html.ep:80 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 msgid "Password" msgstr "" @@ -300,7 +304,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:136 +#: lib/Lufi.pm:137 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -316,7 +320,7 @@ msgstr "" msgid "Rows in red mean that the files have expired and are no longer available." msgstr "" -#: themes/default/templates/index.html.ep:116 +#: themes/default/templates/partial/index.js.ep:26 msgid "Send all links by email" msgstr "" @@ -328,20 +332,20 @@ msgstr "" msgid "Send with your own mail software" msgstr "" -#: themes/default/templates/index.html.ep:118 +#: themes/default/templates/partial/index.js.ep:28 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "" #. (url_for('/') -#: themes/default/templates/mail.html.ep:91 +#: themes/default/templates/partial/mail.js.ep:43 msgid "Share your files in total privacy on %1" msgstr "" -#: themes/default/templates/layouts/default.html.ep:63 themes/default/templates/layouts/default.html.ep:75 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 +#: themes/default/templates/layouts/default.html.ep:33 themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 msgid "Signin" msgstr "" -#: lib/Lufi.pm:139 +#: lib/Lufi.pm:140 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 "" @@ -357,7 +361,7 @@ msgstr "" msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "" -#: themes/default/templates/files.html.ep:51 +#: themes/default/templates/partial/files.js.ep:11 msgid "The data has been successfully imported." msgstr "" @@ -369,7 +373,7 @@ msgstr "" msgid "The email subject can't be empty." msgstr "" -#: lib/Lufi/Controller/Files.pm:390 +#: lib/Lufi/Controller/Files.pm:392 msgid "The file has already been deleted" msgstr "" @@ -382,7 +386,7 @@ msgstr "" msgid "The following email addresses are not valid: %1" msgstr "" -#: themes/default/templates/index.html.ep:106 +#: themes/default/templates/partial/index.js.ep:16 msgid "The link(s) has been copied to your clipboard" msgstr "" @@ -394,7 +398,7 @@ msgstr "" msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "" -#: lib/Lufi/Controller/Files.pm:179 +#: lib/Lufi/Controller/Files.pm:181 msgid "The server was unable to find the file record to add your file part to. Please, contact the administrator." msgstr "" @@ -402,26 +406,26 @@ msgstr "" 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 "" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/partial/index.js.ep:17 msgid "Unable to copy the link(s) to your clipboard" msgstr "" #. ($short) -#: lib/Lufi/Controller/Files.pm:361 +#: lib/Lufi/Controller/Files.pm:363 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:351 +#: lib/Lufi/Controller/Files.pm:353 msgid "Unable to get counter for %1. The token is invalid." msgstr "" #. ($short) -#: lib/Lufi/Controller/Files.pm:371 +#: lib/Lufi/Controller/Files.pm:373 msgid "Unable to get counter for %1. You are not authenticated." msgstr "" -#: themes/default/templates/layouts/default.html.ep:60 themes/default/templates/layouts/default.html.ep:72 +#: themes/default/templates/layouts/default.html.ep:30 themes/default/templates/layouts/default.html.ep:42 msgid "Upload files" msgstr "" @@ -429,11 +433,11 @@ msgstr "" msgid "Uploaded at" msgstr "" -#: themes/default/templates/index.html.ep:85 +#: themes/default/templates/index.html.ep:95 msgid "Uploaded files" msgstr "" -#: themes/default/templates/index.html.ep:119 +#: themes/default/templates/partial/index.js.ep:29 msgid "Websocket communication error" msgstr "" @@ -453,15 +457,15 @@ msgstr "" msgid "You don't need to register yourself to upload files but be aware that, for legal reasons, your IP address will be stored when you send a file. Don't panic, this is normally the case for all sites on which you send files." msgstr "" -#: themes/default/templates/render.html.ep:53 +#: themes/default/templates/partial/render.js.ep:10 msgid "You don't seem to have a key in your URL. You won't be able to decrypt the file. Download canceled." msgstr "" -#: themes/default/templates/render.html.ep:50 +#: themes/default/templates/partial/render.js.ep:7 msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "" -#: themes/default/templates/index.html.ep:104 +#: themes/default/templates/partial/index.js.ep:14 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "" @@ -478,7 +482,7 @@ msgstr "" msgid "Your file is too big: %1 (maximum size allowed: %2)" msgstr "" -#: lib/Lufi/Controller/Files.pm:273 +#: lib/Lufi/Controller/Files.pm:275 msgid "Your password is not valid. Please refresh the page to retry." msgstr "" @@ -492,7 +496,7 @@ msgstr "" msgid "between %1 and %2, the file will be kept forever." msgstr "" -#: themes/default/templates/mail.html.ep:85 +#: themes/default/templates/partial/mail.js.ep:37 msgid "deadline: " msgstr "" @@ -510,6 +514,6 @@ msgstr "" msgid "no time limit" msgstr "" -#: themes/default/templates/index.html.ep:78 +#: themes/default/templates/index.html.ep:88 msgid "or" msgstr "" diff --git a/themes/default/lib/Lufi/I18N/fr.po b/themes/default/lib/Lufi/I18N/fr.po index 5e21644..647312f 100644 --- a/themes/default/lib/Lufi/I18N/fr.po +++ b/themes/default/lib/Lufi/I18N/fr.po @@ -31,7 +31,7 @@ msgstr "1 an" msgid "24 hours" msgstr "24 heures" -#: themes/default/templates/mail.html.ep:83 +#: themes/default/templates/partial/mail.js.ep:35 msgid ":" msgstr " :" @@ -43,11 +43,11 @@ msgstr "Un merci avec une photo de chaton sur AGPLv3, vous pouvez l’installer sur votre propre serveur. Veuillez consulter le Wiki pour voir la procédure." #. (stash('f') -#: themes/default/templates/render.html.ep:52 +#: 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" @@ -68,11 +68,11 @@ msgstr "Retour à la page d’accueil" msgid "Bad CSRF token!" msgstr "Mauvais jeton CSRF !" -#: themes/default/templates/render.html.ep:48 +#: themes/default/templates/partial/render.js.ep:5 msgid "Click here to refresh the page and restart the download." msgstr "Cliquez ici pour rafraîchir la page et redémarrer le téléchargement." -#: themes/default/templates/index.html.ep:80 +#: themes/default/templates/index.html.ep:90 msgid "Click to open the file browser" msgstr "Cliquez pour ouvrir le navigateur de fichiers" @@ -84,23 +84,23 @@ msgstr "Fermer" msgid "Comma-separated email addresses" msgstr "Adresses mails séparées par des virgules" -#: themes/default/templates/index.html.ep:105 +#: themes/default/templates/partial/index.js.ep:15 msgid "Copy all links to clipboard" msgstr "Copier tous les liens dans le presse-papier" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/partial/index.js.ep:18 msgid "Copy to clipboard" msgstr "Copier dans le presse-papier" -#: lib/Lufi/Controller/Files.pm:429 +#: lib/Lufi/Controller/Files.pm:431 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:411 +#: lib/Lufi/Controller/Files.pm:413 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:322 +#: lib/Lufi/Controller/Files.pm:324 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 ?" @@ -108,7 +108,7 @@ msgstr "Impossible de retrouver le fichier. Êtes-vous sûr(e) que l’URL est l msgid "Counter" msgstr "Compteur" -#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:64 +#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:74 msgid "Delete at first download?" msgstr "Supprimer après le premier téléchargement ?" @@ -116,7 +116,7 @@ msgstr "Supprimer après le premier téléchargement ?" msgid "Delete selected files" msgstr "Supprimer les fichiers sélectionnés" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 +#: themes/default/templates/files.html.ep:32 themes/default/templates/partial/index.js.ep:19 msgid "Deletion link" msgstr "Lien de suppression" @@ -124,15 +124,15 @@ msgstr "Lien de suppression" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "Ne vous inquiétez pas : si un utilisateur commence à télécharger le fichier avant son expiration et que le téléchargement se termine après l’expiration, l’utilisateur pourra quand même récupérer le fichier." -#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 +#: themes/default/templates/partial/index.js.ep:21 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Télécharger" -#: themes/default/templates/render.html.ep:47 +#: themes/default/templates/partial/render.js.ep:4 msgid "Download aborted." msgstr "Téléchargement abandonné." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 +#: themes/default/templates/files.html.ep:27 themes/default/templates/partial/index.js.ep:20 msgid "Download link" msgstr "Lien de téléchargement" @@ -140,7 +140,7 @@ msgstr "Lien de téléchargement" msgid "Drag and drop files in the appropriate area or use the traditional way to send files and the files will be chunked, encrypted and sent to the server. You will get two links per file: a download link, that you give to the people you want to share the file with and a deletion link, allowing you to delete the file whenever you want." msgstr "Faites glisser des fichiers dans la zone prévue à cet effet ou sélectionnez un fichier de façon classique et les fichiers seront découpés en morceaux, chiffrés et envoyés au serveur. Vous récupérerez deux liens par fichier : un lien de téléchargement et un lien pour supprimer le fichier quand vous le souhaitez." -#: themes/default/templates/index.html.ep:77 +#: themes/default/templates/index.html.ep:87 msgid "Drop files here" msgstr "Glissez vos fichiers ici" @@ -156,23 +156,23 @@ msgstr "Sujet du mail" msgid "Emails" msgstr "Mails" -#: themes/default/templates/index.html.ep:112 +#: themes/default/templates/partial/index.js.ep:22 msgid "Encrypting part XX1 of XX2" msgstr "Chiffrement du fragment XX1 sur XX2" -#: lib/Lufi/Controller/Files.pm:225 +#: lib/Lufi/Controller/Files.pm:227 msgid "Error: the file existed but was deleted." msgstr "Erreur : le fichier existait mais a été supprimé" -#: lib/Lufi/Controller/Files.pm:291 +#: lib/Lufi/Controller/Files.pm:293 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:301 +#: lib/Lufi/Controller/Files.pm:303 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 ?" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/partial/index.js.ep:23 msgid "Expiration:" msgstr "Expiration :" @@ -184,7 +184,7 @@ msgstr "Expire le" msgid "Export localStorage data" msgstr "Exporter les données localStorage" -#: lib/Lufi/Controller/Files.pm:393 +#: lib/Lufi/Controller/Files.pm:395 msgid "File deleted" msgstr "Fichier supprimé" @@ -192,7 +192,11 @@ msgstr "Fichier supprimé" msgid "File name" msgstr "Nom du fichier" -#: themes/default/templates/render.html.ep:51 +#: themes/default/templates/index.html.ep:64 +msgid "Files deleted at first download" +msgstr "Fichiers supprimés au premier téléchargement" + +#: themes/default/templates/partial/render.js.ep:8 msgid "Get the file" msgstr "Récupérer le fichier" @@ -200,7 +204,7 @@ msgstr "Récupérer le fichier" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Récupérez le code source sur le dépôt officiel ou sur son miroir Github." -#: themes/default/templates/mail.html.ep:78 +#: themes/default/templates/partial/mail.js.ep:30 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Bonjour,\\n\\nVoici quelques fichiers que je souhaite partager avec toi :\\n" @@ -208,11 +212,11 @@ msgstr "Bonjour,\\n\\nVoici quelques fichiers que je souhaite partager avec toi msgid "Here's some files" msgstr "Voici quelques fichiers" -#: themes/default/templates/index.html.ep:115 +#: themes/default/templates/partial/index.js.ep:25 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Appuyez sur la touche Entrée puis faites Ctrl+C pour copier tous les liens de téléchargement" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/partial/index.js.ep:24 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Appuyez sur la touche Entrée puis faites Ctrl+C pour copier le lien de téléchargement" @@ -248,7 +252,7 @@ msgstr "Important : plus d’informations sur les délais" msgid "Information about delays" msgstr "Information sur les délais" -#: themes/default/templates/render.html.ep:49 +#: themes/default/templates/partial/render.js.ep:6 msgid "It seems that the key in your URL is incorrect. Please, verify your URL." msgstr "Il semble que la clé dans votre URL soit incorrecte. Veuillez vérifier votre URL." @@ -260,7 +264,7 @@ msgstr "Javascript est désactivé. Lufi ne fonctionnera pas." msgid "Login" msgstr "Identifiant" -#: themes/default/templates/layouts/default.html.ep:67 themes/default/templates/layouts/default.html.ep:79 +#: themes/default/templates/layouts/default.html.ep:37 themes/default/templates/layouts/default.html.ep:49 msgid "Logout" msgstr "Déconnexion" @@ -272,7 +276,7 @@ msgstr "Lufi est un logiciel libre d’hébergement de fichiers." msgid "Mail" msgstr "" -#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:61 themes/default/templates/layouts/default.html.ep:73 +#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:31 themes/default/templates/layouts/default.html.ep:43 msgid "My files" msgstr "Mes fichiers" @@ -281,7 +285,7 @@ msgstr "Mes fichiers" 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)." -#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 +#: themes/default/templates/partial/files.js.ep:10 themes/default/templates/partial/index.js.ep:27 msgid "No expiration delay" msgstr "Pas de délai d’expiration" @@ -289,7 +293,7 @@ msgstr "Pas de délai d’expiration" msgid "Only the files sent with this browser will be listed here. This list is stored in localStorage: if you delete your localStorage data, you'll lose this list." msgstr "Seuls les fichiers envoyés avec ce navigateur web sont listés ici. Les informations sont stockées en localStorage : si vous supprimez vos données localStorage, vous perdrez ces informations." -#: themes/default/templates/index.html.ep:70 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 +#: themes/default/templates/index.html.ep:80 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 msgid "Password" msgstr "Mot de passe" @@ -302,7 +306,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:136 +#: lib/Lufi.pm:137 msgid "Please, check your credentials: unable to authenticate." msgstr "Veuillez vérifier vos identifiants : impossible de vous authentifier." @@ -318,7 +322,7 @@ msgstr "Supprimer du localStorage les fichiers expirés" msgid "Rows in red mean that the files have expired and are no longer available." msgstr "Les lignes en rouge indiquent que le fichier a expiré et n’est plus disponible." -#: themes/default/templates/index.html.ep:116 +#: themes/default/templates/partial/index.js.ep:26 msgid "Send all links by email" msgstr "Envoyer tous les liens par mail" @@ -330,20 +334,20 @@ msgstr "Envoyer avec ce serveur" msgid "Send with your own mail software" msgstr "Envoyer avec votre propre logiciel de mail" -#: themes/default/templates/index.html.ep:118 +#: themes/default/templates/partial/index.js.ep:28 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "Envoi du fragment XX1 sur XX2. Veuillez patienter, la barre de progression peut mettre du temps avant d’avancer." #. (url_for('/') -#: themes/default/templates/mail.html.ep:91 +#: themes/default/templates/partial/mail.js.ep:43 msgid "Share your files in total privacy on %1" msgstr "Partagez vos fichiers en toute confidentialité sur %1" -#: themes/default/templates/layouts/default.html.ep:63 themes/default/templates/layouts/default.html.ep:75 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 +#: themes/default/templates/layouts/default.html.ep:33 themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 msgid "Signin" msgstr "Connexion" -#: lib/Lufi.pm:139 +#: lib/Lufi.pm:140 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." @@ -359,7 +363,7 @@ msgstr "Désolé, l’envoi de fichier est désactivé." msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "L’administrateur ne peut voir que le nom du fichier, sa taille et son type mime (son type de fichier : vidéo, texte, etc.)." -#: themes/default/templates/files.html.ep:51 +#: themes/default/templates/partial/files.js.ep:11 msgid "The data has been successfully imported." msgstr "Les données ont été importées avec succès." @@ -371,7 +375,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:390 +#: lib/Lufi/Controller/Files.pm:392 msgid "The file has already been deleted" msgstr "Le fichier a déjà été supprimé" @@ -384,7 +388,7 @@ msgstr "Les fichiers envoyés sur une instance de Lufi sont chiffrés avant l’ msgid "The following email addresses are not valid: %1" msgstr "Les adresses mail suivantes ne sont pas valides : %1" -#: themes/default/templates/index.html.ep:106 +#: themes/default/templates/partial/index.js.ep:16 msgid "The link(s) has been copied to your clipboard" msgstr "Le(s) lien(s) a/ont été copié dans votre presse-papier" @@ -396,7 +400,7 @@ msgstr "Le mail a été envoyé." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "L’auteur originel (et pour l’instant, le seul) est Luc Didry. Si vous avez envie de le supporter, vous pouvez le faire via Tipeee ou via Liberapay." -#: lib/Lufi/Controller/Files.pm:179 +#: lib/Lufi/Controller/Files.pm:181 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." @@ -404,26 +408,26 @@ msgstr "Le serveur a été incapable de retrouver l’enregistrement du fichier 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 "Ce serveur impose des limitations selon la taille des fichiers. Le délai d’expiration de votre fichier sera le minimum entre ce que vous avez choisi et les limites suivantes :" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/partial/index.js.ep:17 msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossible de copier le(s) lien(s) dans votre presse-papier" #. ($short) -#: lib/Lufi/Controller/Files.pm:361 +#: lib/Lufi/Controller/Files.pm:363 msgid "Unable to get counter for %1. The file does not exists. It will be removed from your localStorage." msgstr "Impossible de récupérer le compteur pour %1. Le fichier n’existe pas. Il va être supprimé de votre localStorage." #. ($short) -#: lib/Lufi/Controller/Files.pm:351 +#: lib/Lufi/Controller/Files.pm:353 msgid "Unable to get counter for %1. The token is invalid." msgstr "Impossible de récupérer le compteur pour %1. Le jeton est invalide." #. ($short) -#: lib/Lufi/Controller/Files.pm:371 +#: lib/Lufi/Controller/Files.pm:373 msgid "Unable to get counter for %1. You are not authenticated." msgstr "Impossible de récupérer le compteur pour %1. Vous n’êtes pas connecté·e." -#: themes/default/templates/layouts/default.html.ep:60 themes/default/templates/layouts/default.html.ep:72 +#: themes/default/templates/layouts/default.html.ep:30 themes/default/templates/layouts/default.html.ep:42 msgid "Upload files" msgstr "Envoyer des fichiers" @@ -431,11 +435,11 @@ msgstr "Envoyer des fichiers" msgid "Uploaded at" msgstr "Envoyé le" -#: themes/default/templates/index.html.ep:85 +#: themes/default/templates/index.html.ep:95 msgid "Uploaded files" msgstr "Fichiers envoyés" -#: themes/default/templates/index.html.ep:119 +#: themes/default/templates/partial/index.js.ep:29 msgid "Websocket communication error" msgstr "Erreur de communication WebSocket" @@ -455,15 +459,15 @@ msgstr "Vous pouvez voir la liste de vos fichiers en cliquant sur le lien « Mes msgid "You don't need to register yourself to upload files but be aware that, for legal reasons, your IP address will be stored when you send a file. Don't panic, this is normally the case for all sites on which you send files." msgstr "Vous n’avez pas besoin de vous enregistrer pour envoyer des fichiers mais notez que, pour des raisons légales, votre adresse IP sera enregistrée quand vous envoyez un fichier. Ne paniquez pas, c’est normalement le cas pour tous les sites où vous envoyez des fichiers." -#: themes/default/templates/render.html.ep:53 +#: themes/default/templates/partial/render.js.ep:10 msgid "You don't seem to have a key in your URL. You won't be able to decrypt the file. Download canceled." msgstr "Il semble que vous n’ayez pas de clé dans votre URL. Vous ne serez pas capable de déchiffrer le fichier. Téléchargement annulé." -#: themes/default/templates/render.html.ep:50 +#: themes/default/templates/partial/render.js.ep:7 msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Vous essayez de quitter la page. Le téléchargement sera annulé. Êtes-vous sûr(e) ?" -#: themes/default/templates/index.html.ep:104 +#: themes/default/templates/partial/index.js.ep:14 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Vous essayez de quitter la page. L’envoi sera annulé. Êtes-vous sûr(e) ?" @@ -480,7 +484,7 @@ msgstr "Vous devez envoyer des adresses mail." 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:273 +#: lib/Lufi/Controller/Files.pm:275 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." @@ -494,7 +498,7 @@ msgstr "entre %1 et %2, le fichier sera conservé %3 jour(s) ;" msgid "between %1 and %2, the file will be kept forever." msgstr "entre %1 et %2, le fichier sera conservé indéfiniment ;" -#: themes/default/templates/mail.html.ep:85 +#: themes/default/templates/partial/mail.js.ep:37 msgid "deadline: " msgstr "dernier délai pour télécharger : " @@ -512,6 +516,6 @@ msgstr "pour %1 et plus, le fichier sera conservé indéfiniment." msgid "no time limit" msgstr "Pas de délai d'expiration" -#: themes/default/templates/index.html.ep:78 +#: themes/default/templates/index.html.ep:88 msgid "or" msgstr "ou" diff --git a/themes/default/lib/Lufi/I18N/it.po b/themes/default/lib/Lufi/I18N/it.po index 5833ef0..7502567 100644 --- a/themes/default/lib/Lufi/I18N/it.po +++ b/themes/default/lib/Lufi/I18N/it.po @@ -31,7 +31,7 @@ msgstr "1 anno" msgid "24 hours" msgstr "24 ore" -#: themes/default/templates/mail.html.ep:83 +#: themes/default/templates/partial/mail.js.ep:35 msgid ":" msgstr "A :" @@ -43,11 +43,11 @@ msgstr "Un grazie con una foto di un gattino sur AGPLv3, potete installarlo sul vostro server. Si consulti Wiki per vedere la procedura." #. (stash('f') -#: themes/default/templates/render.html.ep:52 +#: themes/default/templates/partial/render.js.ep:9 msgid "Asking for file part XX1 of %1" msgstr "Recupero della porzione del file XX1 su %1" @@ -68,11 +68,11 @@ msgstr "Ritorna all'homepage" msgid "Bad CSRF token!" msgstr "Token CSRF errato!" -#: themes/default/templates/render.html.ep:48 +#: themes/default/templates/partial/render.js.ep:5 msgid "Click here to refresh the page and restart the download." msgstr "Click qui per aggiornare la pagina e ricominciare il download." -#: themes/default/templates/index.html.ep:80 +#: themes/default/templates/index.html.ep:90 msgid "Click to open the file browser" msgstr "Click per aprire il file browser" @@ -84,23 +84,23 @@ msgstr "Chiudi" msgid "Comma-separated email addresses" msgstr "Indirizzi email separati da virgole" -#: themes/default/templates/index.html.ep:105 +#: themes/default/templates/partial/index.js.ep:15 msgid "Copy all links to clipboard" msgstr "Copiare tutti i link negli appunti" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/partial/index.js.ep:18 msgid "Copy to clipboard" msgstr "Copiare negli appunti" -#: lib/Lufi/Controller/Files.pm:429 +#: lib/Lufi/Controller/Files.pm:431 msgid "Could not delete the file. You are not authenticated." msgstr "Impossibile cancellare il file. Non siete autenticati." -#: lib/Lufi/Controller/Files.pm:411 +#: lib/Lufi/Controller/Files.pm:413 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:322 +#: lib/Lufi/Controller/Files.pm:324 msgid "Could not find the file. Are you sure of the URL?" msgstr "Impossibile trovare il file. Sei sicuro che l'URL sia corretto?" @@ -108,7 +108,7 @@ msgstr "Impossibile trovare il file. Sei sicuro che l'URL sia corretto?" msgid "Counter" msgstr "Contatore" -#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:64 +#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:74 msgid "Delete at first download?" msgstr "Cancellare al primo download?" @@ -116,7 +116,7 @@ msgstr "Cancellare al primo download?" msgid "Delete selected files" msgstr "" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 +#: themes/default/templates/files.html.ep:32 themes/default/templates/partial/index.js.ep:19 msgid "Deletion link" msgstr "Link per l'eliminazione" @@ -124,15 +124,15 @@ msgstr "Link per l'eliminazione" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "Non preoccuparti: se un utente cominciasse il download del file prima della scadenza ed il download terminasse dopo la scadenza, potrebbe ottenere il file." -#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 +#: themes/default/templates/partial/index.js.ep:21 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Download" -#: themes/default/templates/render.html.ep:47 +#: themes/default/templates/partial/render.js.ep:4 msgid "Download aborted." msgstr "Download annullato." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 +#: themes/default/templates/files.html.ep:27 themes/default/templates/partial/index.js.ep:20 msgid "Download link" msgstr "Link per il download" @@ -140,7 +140,7 @@ msgstr "Link per il download" msgid "Drag and drop files in the appropriate area or use the traditional way to send files and the files will be chunked, encrypted and sent to the server. You will get two links per file: a download link, that you give to the people you want to share the file with and a deletion link, allowing you to delete the file whenever you want." msgstr "Trascinare e lasciare il file nell'are prevista o selezionare i file nel modo classico ed i file saranno divisi,cifrati ed inviati al server. Otterrete 2 link per ogni file : uno per il download ed uno per eliminare il file quando vorrete." -#: themes/default/templates/index.html.ep:77 +#: themes/default/templates/index.html.ep:87 msgid "Drop files here" msgstr "Lasciare i file qui" @@ -156,23 +156,23 @@ msgstr "Oggetto dell'email" msgid "Emails" msgstr "Email" -#: themes/default/templates/index.html.ep:112 +#: themes/default/templates/partial/index.js.ep:22 msgid "Encrypting part XX1 of XX2" msgstr "Cifratura della parte XX1 di XX2" -#: lib/Lufi/Controller/Files.pm:225 +#: lib/Lufi/Controller/Files.pm:227 msgid "Error: the file existed but was deleted." msgstr "Errore: il file esisteva ma è stato eliminato" -#: lib/Lufi/Controller/Files.pm:291 +#: lib/Lufi/Controller/Files.pm:293 msgid "Error: the file has not been sent entirely." msgstr "Errore: il file non è stato inviato completamente" -#: lib/Lufi/Controller/Files.pm:301 +#: lib/Lufi/Controller/Files.pm:303 msgid "Error: unable to find the file. Are you sure of your URL?" msgstr "Errore: impossibile trovare il file. Sei certo dell'URL ?" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/partial/index.js.ep:23 msgid "Expiration:" msgstr "Scadenza:" @@ -184,7 +184,7 @@ msgstr "Scadrà il" msgid "Export localStorage data" msgstr "Esportare i dati del localStorage" -#: lib/Lufi/Controller/Files.pm:393 +#: lib/Lufi/Controller/Files.pm:395 msgid "File deleted" msgstr "File cancellato" @@ -192,7 +192,11 @@ msgstr "File cancellato" msgid "File name" msgstr "Nome del file" -#: themes/default/templates/render.html.ep:51 +#: themes/default/templates/index.html.ep:64 +msgid "Files deleted at first download" +msgstr "" + +#: themes/default/templates/partial/render.js.ep:8 msgid "Get the file" msgstr "Ottenere il file" @@ -200,7 +204,7 @@ msgstr "Ottenere il file" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Ottenere il codice sorgente su le dépôt officiel ou sur son miroir Github." -#: themes/default/templates/mail.html.ep:78 +#: themes/default/templates/partial/mail.js.ep:30 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Buongiorno,\\n\\necco qualche file che vorrei condividere con te:\\n" @@ -208,11 +212,11 @@ msgstr "Buongiorno,\\n\\necco qualche file che vorrei condividere con te:\\n" msgid "Here's some files" msgstr "Ecco qualche file" -#: themes/default/templates/index.html.ep:115 +#: themes/default/templates/partial/index.js.ep:25 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Premere Enter, poi Ctrl+C per copiare tutti i link di download" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/partial/index.js.ep:24 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Premere Enter, poi Ctrl+C per copiare il link di download" @@ -248,7 +252,7 @@ msgstr "Importante : più informazioni sulle scadenze" msgid "Information about delays" msgstr "Informazione sulle scadenze" -#: themes/default/templates/render.html.ep:49 +#: themes/default/templates/partial/render.js.ep:6 msgid "It seems that the key in your URL is incorrect. Please, verify your URL." msgstr "Sembra che la chiave nel tuo URL sia errata. Controllare il tuo URL." @@ -260,7 +264,7 @@ msgstr "Javascript è disattivato. Lufi non può funzionare." msgid "Login" msgstr "Login" -#: themes/default/templates/layouts/default.html.ep:67 themes/default/templates/layouts/default.html.ep:79 +#: themes/default/templates/layouts/default.html.ep:37 themes/default/templates/layouts/default.html.ep:49 msgid "Logout" msgstr "Logout" @@ -272,7 +276,7 @@ msgstr "Lufi è un software libero di file hosting." msgid "Mail" msgstr "" -#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:61 themes/default/templates/layouts/default.html.ep:73 +#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:31 themes/default/templates/layouts/default.html.ep:43 msgid "My files" msgstr "I miei file" @@ -281,7 +285,7 @@ msgstr "I miei file" msgid "No enough space available on the server for this file (size: %1)." msgstr "Spazio disco insufficiente sul server per questo file (dimensione: %1)." -#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 +#: themes/default/templates/partial/files.js.ep:10 themes/default/templates/partial/index.js.ep:27 msgid "No expiration delay" msgstr "Nessun ritardo per la scadenza" @@ -289,7 +293,7 @@ msgstr "Nessun ritardo per la scadenza" msgid "Only the files sent with this browser will be listed here. This list is stored in localStorage: if you delete your localStorage data, you'll lose this list." msgstr "Solo i file inviati con questo browser web sono nella lista. Le informazioni sono memorizzate nel localStorage: se cancellaste i dati dal vostro localStorage, perdereste questa lista." -#: themes/default/templates/index.html.ep:70 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 +#: themes/default/templates/index.html.ep:80 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 msgid "Password" msgstr "Password" @@ -302,7 +306,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:136 +#: lib/Lufi.pm:137 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -322,7 +326,7 @@ msgstr "Le righe in viola indicano che il file è scaduto e non è più disponib msgid "Rows in red mean that the files have expired and are no longer available." msgstr "" -#: themes/default/templates/index.html.ep:116 +#: themes/default/templates/partial/index.js.ep:26 msgid "Send all links by email" msgstr "Inviare tutti i link tramite email" @@ -334,20 +338,20 @@ msgstr "Inviare tramite questo server" msgid "Send with your own mail software" msgstr "Inviare tramite il vostro programma di posta" -#: themes/default/templates/index.html.ep:118 +#: themes/default/templates/partial/index.js.ep:28 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "Invio della parte XX1 su XX2. Prego attendere, la barra di avanzamento può impiegare del tempo prima di colorarsi." #. (url_for('/') -#: themes/default/templates/mail.html.ep:91 +#: themes/default/templates/partial/mail.js.ep:43 msgid "Share your files in total privacy on %1" msgstr "Condividi tutti i file in totale riservatezza su %1" -#: themes/default/templates/layouts/default.html.ep:63 themes/default/templates/layouts/default.html.ep:75 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 +#: themes/default/templates/layouts/default.html.ep:33 themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 msgid "Signin" msgstr "Autenticazione" -#: lib/Lufi.pm:139 +#: lib/Lufi.pm:140 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 "" @@ -367,7 +371,7 @@ msgstr "L'amministratore pu vedere solo il nome del file, la sua dimensione e il msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "" -#: themes/default/templates/files.html.ep:51 +#: themes/default/templates/partial/files.js.ep:11 msgid "The data has been successfully imported." msgstr "I dati sono stati importati correttamente." @@ -379,7 +383,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:390 +#: lib/Lufi/Controller/Files.pm:392 msgid "The file has already been deleted" msgstr "Il file è già stato cancellato" @@ -392,7 +396,7 @@ msgstr "I file inviati su un istanza di Lufi sono cifrati prima dell'invio al se msgid "The following email addresses are not valid: %1" msgstr "I seguenti indirizzi email non sono validi: %1" -#: themes/default/templates/index.html.ep:106 +#: themes/default/templates/partial/index.js.ep:16 msgid "The link(s) has been copied to your clipboard" msgstr "I link sono stati copiati negli appunti" @@ -404,7 +408,7 @@ msgstr "Email inviata." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "L'autore ( e per ora l'unico) è Luc Didry. Se aveste voglia di aiutarlo, potreste farlo tramite Tipeee ou via Liberapay." -#: lib/Lufi/Controller/Files.pm:179 +#: lib/Lufi/Controller/Files.pm:181 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." @@ -412,26 +416,26 @@ msgstr "Il server non è stato in grado di trovare il file record a cui aggiunge 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 "Questo server pone delle limitazioni in base alla dimensione del file.La data di scadenza del tuo file sarà la minore tra quella scelta e queste limitazioni:" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/partial/index.js.ep:17 msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossibile copiare i link negli appunti" #. ($short) -#: lib/Lufi/Controller/Files.pm:361 +#: lib/Lufi/Controller/Files.pm:363 msgid "Unable to get counter for %1. The file does not exists. It will be removed from your localStorage." msgstr "Impossibile recuperare il contatore per %1. Il file non esiste. Il file sarà eliminato dal tuo localStorage." #. ($short) -#: lib/Lufi/Controller/Files.pm:351 +#: lib/Lufi/Controller/Files.pm:353 msgid "Unable to get counter for %1. The token is invalid." msgstr "Impossibile recuperare il contatore per %1. Il token non è valido." #. ($short) -#: lib/Lufi/Controller/Files.pm:371 +#: lib/Lufi/Controller/Files.pm:373 msgid "Unable to get counter for %1. You are not authenticated." msgstr "Impossibile recuperare il contatore per %1. Non sei autenticato." -#: themes/default/templates/layouts/default.html.ep:60 themes/default/templates/layouts/default.html.ep:72 +#: themes/default/templates/layouts/default.html.ep:30 themes/default/templates/layouts/default.html.ep:42 msgid "Upload files" msgstr "Invio dei file" @@ -439,11 +443,11 @@ msgstr "Invio dei file" msgid "Uploaded at" msgstr "Invio il" -#: themes/default/templates/index.html.ep:85 +#: themes/default/templates/index.html.ep:95 msgid "Uploaded files" msgstr "File inviati" -#: themes/default/templates/index.html.ep:119 +#: themes/default/templates/partial/index.js.ep:29 msgid "Websocket communication error" msgstr "Errore di comunicazione WebSocket" @@ -463,15 +467,15 @@ msgstr "Puoi consultare la lista dei vostri file cliccando sul link « I miei fi msgid "You don't need to register yourself to upload files but be aware that, for legal reasons, your IP address will be stored when you send a file. Don't panic, this is normally the case for all sites on which you send files." msgstr "Non hai bisogno di registrarti per inviare i file ma devi essere consapevole che, per motivi legali, il tuo indirizzo IP sarà registrato quando invierai un file. Non ti preoccupare, avviene in tutti i siti su cui invii dei file." -#: themes/default/templates/render.html.ep:53 +#: themes/default/templates/partial/render.js.ep:10 msgid "You don't seem to have a key in your URL. You won't be able to decrypt the file. Download canceled." msgstr "Sembra che non ci sia una chiave nel tuo URL. Non sarai in grado di decifrare il file. Download annullato." -#: themes/default/templates/render.html.ep:50 +#: themes/default/templates/partial/render.js.ep:7 msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Hai cercato di uscire da questa pagina. Il download sarà cancellato. Sei sicuro?" -#: themes/default/templates/index.html.ep:104 +#: themes/default/templates/partial/index.js.ep:14 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Hai cercato di uscire da questa pagina. L'invio sarà cancellato. Sei sicuro?" @@ -488,7 +492,7 @@ msgstr "Devi fornire gli indirizzi email." 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:273 +#: lib/Lufi/Controller/Files.pm:275 msgid "Your password is not valid. Please refresh the page to retry." msgstr "" @@ -502,7 +506,7 @@ msgstr "tra %1 e %2, il file sarà conservato %3 giorno(i);" msgid "between %1 and %2, the file will be kept forever." msgstr "tra %1 e %2, il file sarà conservato per sempre;" -#: themes/default/templates/mail.html.ep:85 +#: themes/default/templates/partial/mail.js.ep:37 msgid "deadline: " msgstr "scadenza: " @@ -520,6 +524,6 @@ msgstr "per %1 e più, il file sarà conservato per sempre." msgid "no time limit" msgstr "nessuna limitazione temporale" -#: themes/default/templates/index.html.ep:78 +#: themes/default/templates/index.html.ep:88 msgid "or" msgstr "o" diff --git a/themes/default/lib/Lufi/I18N/nl.po b/themes/default/lib/Lufi/I18N/nl.po index 290516b..08394a3 100644 --- a/themes/default/lib/Lufi/I18N/nl.po +++ b/themes/default/lib/Lufi/I18N/nl.po @@ -18,7 +18,7 @@ msgstr "1 jaar" msgid "24 hours" msgstr "24 uur" -#: themes/default/templates/mail.html.ep:83 +#: themes/default/templates/partial/mail.js.ep:35 msgid ":" msgstr ":" @@ -30,11 +30,11 @@ msgstr "Een bedankt foto met een katje op AGPLv3, kan je het installeren op je eigen server. Bekijk Wiki voor de procedure." #. (stash('f') -#: themes/default/templates/render.html.ep:52 +#: themes/default/templates/partial/render.js.ep:9 msgid "Asking for file part XX1 of %1" msgstr "Deel XX1 van %1 wordt opgehaald" @@ -55,11 +55,11 @@ msgstr "Terug naar home" msgid "Bad CSRF token!" msgstr "Verkeerde CSRF token!" -#: themes/default/templates/render.html.ep:48 +#: themes/default/templates/partial/render.js.ep:5 msgid "Click here to refresh the page and restart the download." msgstr "Klik hier om de pagina te verversen en opnieuw te downloaden." -#: themes/default/templates/index.html.ep:80 +#: themes/default/templates/index.html.ep:90 msgid "Click to open the file browser" msgstr "Klik voor bestandbrowser" @@ -71,23 +71,23 @@ msgstr "Sluiten" msgid "Comma-separated email addresses" msgstr "Komma gescheiden email adressen" -#: themes/default/templates/index.html.ep:105 +#: themes/default/templates/partial/index.js.ep:15 msgid "Copy all links to clipboard" msgstr "Kopieer alle links naar klembord" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/partial/index.js.ep:18 msgid "Copy to clipboard" msgstr "Kopieer naar klembord" -#: lib/Lufi/Controller/Files.pm:429 +#: lib/Lufi/Controller/Files.pm:431 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:411 +#: lib/Lufi/Controller/Files.pm:413 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:322 +#: lib/Lufi/Controller/Files.pm:324 msgid "Could not find the file. Are you sure of the URL?" msgstr "Kan het bestand niet vinden. Klopt de URL?" @@ -95,7 +95,7 @@ msgstr "Kan het bestand niet vinden. Klopt de URL?" msgid "Counter" msgstr "Teller" -#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:64 +#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:74 msgid "Delete at first download?" msgstr "Verwijder na eerste download?" @@ -103,7 +103,7 @@ msgstr "Verwijder na eerste download?" msgid "Delete selected files" msgstr "" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 +#: themes/default/templates/files.html.ep:32 themes/default/templates/partial/index.js.ep:19 msgid "Deletion link" msgstr "Verwijderingslink" @@ -111,15 +111,15 @@ msgstr "Verwijderingslink" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "Geen zorgen: als een gebruiker de download start voor de vervaldatum, dan zal die het bestand kunnen binnenhalen." -#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 +#: themes/default/templates/partial/index.js.ep:21 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Download" -#: themes/default/templates/render.html.ep:47 +#: themes/default/templates/partial/render.js.ep:4 msgid "Download aborted." msgstr "Download geannuleerd." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 +#: themes/default/templates/files.html.ep:27 themes/default/templates/partial/index.js.ep:20 msgid "Download link" msgstr "Download link" @@ -127,7 +127,7 @@ msgstr "Download link" msgid "Drag and drop files in the appropriate area or use the traditional way to send files and the files will be chunked, encrypted and sent to the server. You will get two links per file: a download link, that you give to the people you want to share the file with and a deletion link, allowing you to delete the file whenever you want." msgstr "Drag and drop bestanden in de daarvoor bestemde locatie of gebruik de traditionele weg om bestanden encrypted op te sturen naar server. Je zal 2 linkjes per bestand krijgen: een download link, die stuur je naar personen waarmee je het bestand wilt delen en een verwijderings link, waarmee je het bestand kan verwijderen wanneer je dat wilt." -#: themes/default/templates/index.html.ep:77 +#: themes/default/templates/index.html.ep:87 msgid "Drop files here" msgstr "Sleep bestand(en) naar dit venster" @@ -143,23 +143,23 @@ msgstr "Onderwerp" msgid "Emails" msgstr "Emails" -#: themes/default/templates/index.html.ep:112 +#: themes/default/templates/partial/index.js.ep:22 msgid "Encrypting part XX1 of XX2" msgstr "Encrypten deel XX1 van XX2 " -#: lib/Lufi/Controller/Files.pm:225 +#: lib/Lufi/Controller/Files.pm:227 msgid "Error: the file existed but was deleted." msgstr "Fout: het bestand bestond wel maar is verwijderd." -#: lib/Lufi/Controller/Files.pm:291 +#: lib/Lufi/Controller/Files.pm:293 msgid "Error: the file has not been sent entirely." msgstr "Fout: het bestand is niet volledig opgestuurd." -#: lib/Lufi/Controller/Files.pm:301 +#: lib/Lufi/Controller/Files.pm:303 msgid "Error: unable to find the file. Are you sure of your URL?" msgstr "Fout: kan het bestand niet vinden. Is de URL juist?" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/partial/index.js.ep:23 msgid "Expiration:" msgstr "Vervaldatum:" @@ -171,7 +171,7 @@ msgstr "Vervalt op" msgid "Export localStorage data" msgstr "Exporteer opgeslagen data" -#: lib/Lufi/Controller/Files.pm:393 +#: lib/Lufi/Controller/Files.pm:395 msgid "File deleted" msgstr "Bestand verwijderd" @@ -179,7 +179,11 @@ msgstr "Bestand verwijderd" msgid "File name" msgstr "Bestandsnaam" -#: themes/default/templates/render.html.ep:51 +#: themes/default/templates/index.html.ep:64 +msgid "Files deleted at first download" +msgstr "" + +#: themes/default/templates/partial/render.js.ep:8 msgid "Get the file" msgstr "Download bestand" @@ -187,7 +191,7 @@ msgstr "Download bestand" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Krijg de broncode op de officiële repository of op Github mirror" -#: themes/default/templates/mail.html.ep:78 +#: themes/default/templates/partial/mail.js.ep:30 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Hallo,\\n\\nHier zijn enkele bestanden die ik met je wil delen:\\n\\n" @@ -195,11 +199,11 @@ msgstr "Hallo,\\n\\nHier zijn enkele bestanden die ik met je wil delen:\\n\\n" msgid "Here's some files" msgstr "Hier zijn enkele bestanden" -#: themes/default/templates/index.html.ep:115 +#: themes/default/templates/partial/index.js.ep:25 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Druk Enter, vervolgens CTRL+C om alle download links te kopieeren" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/partial/index.js.ep:24 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Druk Enter, vervolgens CTRL+C om de download link te kopieeren" @@ -235,7 +239,7 @@ msgstr "Belangrijk: meer informatie over uitstel" msgid "Information about delays" msgstr "Informatie over uitstel" -#: themes/default/templates/render.html.ep:49 +#: themes/default/templates/partial/render.js.ep:6 msgid "It seems that the key in your URL is incorrect. Please, verify your URL." msgstr "Het lijkt er op dat de sleutel in je URL niet klopt. Controleer je URL." @@ -247,7 +251,7 @@ msgstr "Javascript is uitgeschakeld. Je kan geen gebruik maken van Lufi." msgid "Login" msgstr "Login" -#: themes/default/templates/layouts/default.html.ep:67 themes/default/templates/layouts/default.html.ep:79 +#: themes/default/templates/layouts/default.html.ep:37 themes/default/templates/layouts/default.html.ep:49 msgid "Logout" msgstr "Logout" @@ -259,7 +263,7 @@ msgstr "Lufi is een gratis bestand hosting software." msgid "Mail" msgstr "" -#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:61 themes/default/templates/layouts/default.html.ep:73 +#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:31 themes/default/templates/layouts/default.html.ep:43 msgid "My files" msgstr "Mijn bestanden" @@ -268,7 +272,7 @@ msgstr "Mijn bestanden" 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)." -#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 +#: themes/default/templates/partial/files.js.ep:10 themes/default/templates/partial/index.js.ep:27 msgid "No expiration delay" msgstr "Geen verloop uitstel" @@ -276,7 +280,7 @@ msgstr "Geen verloop uitstel" msgid "Only the files sent with this browser will be listed here. This list is stored in localStorage: if you delete your localStorage data, you'll lose this list." msgstr "Alleen bestanden die via deze browser zijn verstuurd zijn hier zichtbaar. Deze lijst is opgeslagen: als je opgeslagen data verwijderd, zal je deze lijst verlizen." -#: themes/default/templates/index.html.ep:70 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 +#: themes/default/templates/index.html.ep:80 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 msgid "Password" msgstr "Wachtwoord" @@ -289,7 +293,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:136 +#: lib/Lufi.pm:137 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -309,7 +313,7 @@ msgstr "Registreer" msgid "Rows in red mean that the files have expired and are no longer available." msgstr "Rode rijen betekenen dat deze bestanden verlopen en verwijderd zijn." -#: themes/default/templates/index.html.ep:116 +#: themes/default/templates/partial/index.js.ep:26 msgid "Send all links by email" msgstr "Verstuur alle links via mail" @@ -321,20 +325,20 @@ msgstr "Verstuur via deze server" msgid "Send with your own mail software" msgstr "Verstuur via eigen mail software" -#: themes/default/templates/index.html.ep:118 +#: themes/default/templates/partial/index.js.ep:28 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "Versturen deel XX1 van XX2. Een ogenblik geduld..." #. (url_for('/') -#: themes/default/templates/mail.html.ep:91 +#: themes/default/templates/partial/mail.js.ep:43 msgid "Share your files in total privacy on %1" msgstr "Deel je bestanden met volledige privacy op %1" -#: themes/default/templates/layouts/default.html.ep:63 themes/default/templates/layouts/default.html.ep:75 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 +#: themes/default/templates/layouts/default.html.ep:33 themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 msgid "Signin" msgstr "Inloggen" -#: lib/Lufi.pm:139 +#: lib/Lufi.pm:140 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 "" @@ -350,7 +354,7 @@ msgstr "SOrry, uploaden is uitgeschakeld." msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "Beheerders zien alleen bestandsnamen, grootte en mimetype (wat voor soort bestand het is: video, tekst etc.)." -#: themes/default/templates/files.html.ep:51 +#: themes/default/templates/partial/files.js.ep:11 msgid "The data has been successfully imported." msgstr "Data is succesvol geimporteerd." @@ -362,7 +366,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:390 +#: lib/Lufi/Controller/Files.pm:392 msgid "The file has already been deleted" msgstr "Bestand is reeds verwijderd" @@ -375,7 +379,7 @@ msgstr "Bestanden die geupload zijn naar Lufi worden voor de upload versleuteld: msgid "The following email addresses are not valid: %1" msgstr "Volgende email adressen zijn niet geldig: %1" -#: themes/default/templates/index.html.ep:106 +#: themes/default/templates/partial/index.js.ep:16 msgid "The link(s) has been copied to your clipboard" msgstr "De link is gekopieerd naar je klembord" @@ -387,7 +391,7 @@ msgstr "Email is verzonden." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "De oorspronkelijke auteur is Luc Didry. Als je hem wilt ondersteunen, dan kan dat via Tipeee of via Liberapay." -#: lib/Lufi/Controller/Files.pm:179 +#: lib/Lufi/Controller/Files.pm:181 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." @@ -395,26 +399,26 @@ msgstr "Server kon een deel van het bestand niet vinden. Neem contact op met beh 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 "Deze server stelt beperkingen vast volgens de bestandsgrootte. De vervaldatum van uw bestand zal het minimum zijn tussen wat u kiest en de volgende beperkingen:" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/partial/index.js.ep:17 msgid "Unable to copy the link(s) to your clipboard" msgstr "Kan de link(s) niet naar je klembord kopieeren" #. ($short) -#: lib/Lufi/Controller/Files.pm:361 +#: lib/Lufi/Controller/Files.pm:363 msgid "Unable to get counter for %1. The file does not exists. It will be removed from your localStorage." msgstr "Kan geen teller verkrijgen voor %1. Bestand bestaat niet. Het zal verwijderd worden van opgeslagen data." #. ($short) -#: lib/Lufi/Controller/Files.pm:351 +#: lib/Lufi/Controller/Files.pm:353 msgid "Unable to get counter for %1. The token is invalid." msgstr "Kan geen teller verkrijgen voor %1. De token is ongeldig." #. ($short) -#: lib/Lufi/Controller/Files.pm:371 +#: lib/Lufi/Controller/Files.pm:373 msgid "Unable to get counter for %1. You are not authenticated." msgstr "Kan geen teller verkrijgen voor %1. Je bent niet geauthenticeerd." -#: themes/default/templates/layouts/default.html.ep:60 themes/default/templates/layouts/default.html.ep:72 +#: themes/default/templates/layouts/default.html.ep:30 themes/default/templates/layouts/default.html.ep:42 msgid "Upload files" msgstr "Upload bestanden" @@ -422,11 +426,11 @@ msgstr "Upload bestanden" msgid "Uploaded at" msgstr "Geupload op" -#: themes/default/templates/index.html.ep:85 +#: themes/default/templates/index.html.ep:95 msgid "Uploaded files" msgstr "Geuploade bestanden" -#: themes/default/templates/index.html.ep:119 +#: themes/default/templates/partial/index.js.ep:29 msgid "Websocket communication error" msgstr "Websocket communicatie fout" @@ -446,15 +450,15 @@ msgstr "Je kan een lijst van je eigen bestanden zien door op \"Mijn bestanden\" msgid "You don't need to register yourself to upload files but be aware that, for legal reasons, your IP address will be stored when you send a file. Don't panic, this is normally the case for all sites on which you send files." msgstr "U hoeft zich niet te registreren om bestanden te uploaden, maar wees ervan bewust dat uw IP-adres om juridische redenen zal worden opgeslagen wanneer u een bestand verzendt. Geen paniek, dit is normaal gesproken het geval voor alle sites waarnaar u bestanden verzendt." -#: themes/default/templates/render.html.ep:53 +#: themes/default/templates/partial/render.js.ep:10 msgid "You don't seem to have a key in your URL. You won't be able to decrypt the file. Download canceled." msgstr "Je hebt geen sleutel in je URL. Je kan het bestand niet decrypten. Download geannuleerd." -#: themes/default/templates/render.html.ep:50 +#: themes/default/templates/partial/render.js.ep:7 msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Je verlaat deze pagina. Download zal geannuleerd worden. Weet je het zeker?" -#: themes/default/templates/index.html.ep:104 +#: themes/default/templates/partial/index.js.ep:14 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Je verlaat deze pagina. Upload zal geannuleerd worden. Weet je het zeker? " @@ -471,7 +475,7 @@ msgstr "Je moet een mail adres opgeven." 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:273 +#: lib/Lufi/Controller/Files.pm:275 msgid "Your password is not valid. Please refresh the page to retry." msgstr "" @@ -517,7 +521,7 @@ msgstr "tussen %1 en %1, bestand zal bewaard worden voor %3 dag(en)." msgid "between %1 and %2, the file will be kept forever." msgstr "tussen %1 en %2, bestand zal voor altijd bewaard worden." -#: themes/default/templates/mail.html.ep:85 +#: themes/default/templates/partial/mail.js.ep:37 msgid "deadline: " msgstr "deadline: " @@ -535,6 +539,6 @@ msgstr "voor %1 en meer, bestand zal voor altijd bewaard worden." msgid "no time limit" msgstr "geen tijdslimiet" -#: themes/default/templates/index.html.ep:78 +#: themes/default/templates/index.html.ep:88 msgid "or" msgstr "of" diff --git a/themes/default/lib/Lufi/I18N/oc.po b/themes/default/lib/Lufi/I18N/oc.po index 333a33a..e6ca54f 100644 --- a/themes/default/lib/Lufi/I18N/oc.po +++ b/themes/default/lib/Lufi/I18N/oc.po @@ -31,7 +31,7 @@ msgstr "1 an" msgid "24 hours" msgstr "24 oras" -#: themes/default/templates/mail.html.ep:83 +#: themes/default/templates/partial/mail.js.ep:35 msgid ":" msgstr " :" @@ -43,11 +43,11 @@ msgstr "Un mercé amb una fotografia de caton sus AGPLv3, podètz l’installar sus vòstre pròpri servidor. Mercés de consultar lo Wiki per veire la procedura." #. (stash('f') -#: themes/default/templates/render.html.ep:52 +#: themes/default/templates/partial/render.js.ep:9 msgid "Asking for file part XX1 of %1" msgstr "Demanda del tròç XX1 sus %1 del fichièr" @@ -68,11 +68,11 @@ msgstr "Retorn a la pagina d’acuèlh" msgid "Bad CSRF token!" msgstr "Marrit geton CSRF !" -#: themes/default/templates/render.html.ep:48 +#: themes/default/templates/partial/render.js.ep:5 msgid "Click here to refresh the page and restart the download." msgstr "Clicatz aquí per actualizar la pagina e tornar començar lo telecargament." -#: themes/default/templates/index.html.ep:80 +#: themes/default/templates/index.html.ep:90 msgid "Click to open the file browser" msgstr "Clicatz per dobrir lo navigator de fichièr" @@ -84,23 +84,23 @@ msgstr "Tampar" msgid "Comma-separated email addresses" msgstr "Adreças de corrièl separadas per de virgulas" -#: themes/default/templates/index.html.ep:105 +#: themes/default/templates/partial/index.js.ep:15 msgid "Copy all links to clipboard" msgstr "Copiar totes los ligams al quicha-papièrs" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/partial/index.js.ep:18 msgid "Copy to clipboard" msgstr "Copiar al quicha-papièrs" -#: lib/Lufi/Controller/Files.pm:429 +#: lib/Lufi/Controller/Files.pm:431 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:411 +#: lib/Lufi/Controller/Files.pm:413 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:322 +#: lib/Lufi/Controller/Files.pm:324 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 ?" @@ -108,7 +108,7 @@ msgstr "Impossible de trobar lo fichièr. Sètz segur-a que l’URL es bona ?" msgid "Counter" msgstr "Comptador" -#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:64 +#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:74 msgid "Delete at first download?" msgstr "Suprimir aprèp lo primièr telecargament ?" @@ -116,7 +116,7 @@ msgstr "Suprimir aprèp lo primièr telecargament ?" msgid "Delete selected files" msgstr "Suprimir los fichièrs seleccionats" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 +#: themes/default/templates/files.html.ep:32 themes/default/templates/partial/index.js.ep:19 msgid "Deletion link" msgstr "Ligam de supression" @@ -124,15 +124,15 @@ msgstr "Ligam de supression" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "Vos copetz pas lo cap : se un utilizaire comença a telecargar lo fichièr abans son expiracion e que lo telecargament s’acaba aprèp l’expiracion, utilizaire poirà recuperar lo fichièr." -#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 +#: themes/default/templates/partial/index.js.ep:21 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Telecargar" -#: themes/default/templates/render.html.ep:47 +#: themes/default/templates/partial/render.js.ep:4 msgid "Download aborted." msgstr "Telecargament abandonat." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 +#: themes/default/templates/files.html.ep:27 themes/default/templates/partial/index.js.ep:20 msgid "Download link" msgstr "Ligam de telecargament" @@ -140,7 +140,7 @@ msgstr "Ligam de telecargament" msgid "Drag and drop files in the appropriate area or use the traditional way to send files and the files will be chunked, encrypted and sent to the server. You will get two links per file: a download link, that you give to the people you want to share the file with and a deletion link, allowing you to delete the file whenever you want." msgstr "Fasètz lisar de fichièrs dins la zòna prevista per aquò far o seleccionatz un fichièr de faiçon classica e los fichièrs seràn descopats a tròces, chifrats e mandats al servidor. Recuperaretz dos ligams per fichièr : un ligam de telecargament e un ligam per suprimir lo fichièr quand o volètz." -#: themes/default/templates/index.html.ep:77 +#: themes/default/templates/index.html.ep:87 msgid "Drop files here" msgstr "Lisatz vòstres fichièrs aquí" @@ -156,23 +156,23 @@ msgstr "Subjècte del corrièl" msgid "Emails" msgstr "Corrièl" -#: themes/default/templates/index.html.ep:112 +#: themes/default/templates/partial/index.js.ep:22 msgid "Encrypting part XX1 of XX2" msgstr "Chiframent del tròç XX1 sus XX2" -#: lib/Lufi/Controller/Files.pm:225 +#: lib/Lufi/Controller/Files.pm:227 msgid "Error: the file existed but was deleted." msgstr "Error : lo fichièr existissiá mas es estat suprimit" -#: lib/Lufi/Controller/Files.pm:291 +#: lib/Lufi/Controller/Files.pm:293 msgid "Error: the file has not been sent entirely." msgstr "Error : lo fichièr es pas estat mandat completament" -#: lib/Lufi/Controller/Files.pm:301 +#: lib/Lufi/Controller/Files.pm:303 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 ?" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/partial/index.js.ep:23 msgid "Expiration:" msgstr "Expiracion :" @@ -184,7 +184,7 @@ msgstr "Expira lo" msgid "Export localStorage data" msgstr "Exportar las donadas localStorage" -#: lib/Lufi/Controller/Files.pm:393 +#: lib/Lufi/Controller/Files.pm:395 msgid "File deleted" msgstr "Fichièr suprimit" @@ -192,7 +192,11 @@ msgstr "Fichièr suprimit" msgid "File name" msgstr "Nom del fichièr" -#: themes/default/templates/render.html.ep:51 +#: themes/default/templates/index.html.ep:64 +msgid "Files deleted at first download" +msgstr "" + +#: themes/default/templates/partial/render.js.ep:8 msgid "Get the file" msgstr "Recuperar lo fichièr" @@ -200,7 +204,7 @@ msgstr "Recuperar lo fichièr" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Recuperatz lo còdi font sul depaus oficial o sus son miralh Github." -#: themes/default/templates/mail.html.ep:78 +#: themes/default/templates/partial/mail.js.ep:30 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Bonjorn,\\n\\nVaquí qualques fichièrs que desiri partejar amb tu :\\n" @@ -208,11 +212,11 @@ msgstr "Bonjorn,\\n\\nVaquí qualques fichièrs que desiri partejar amb tu :\\ msgid "Here's some files" msgstr "Vaquí qualques fichièrs" -#: themes/default/templates/index.html.ep:115 +#: themes/default/templates/partial/index.js.ep:25 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Picatz sus Entrada puèi fasètz Ctrl+C per copiar totes los ligams per telecargar" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/partial/index.js.ep:24 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Picatz sus Entrada puèi fasètz Ctrl+C per copiar lo ligam per telecargar" @@ -248,7 +252,7 @@ msgstr "Important : mai d’informacions suls relambis" msgid "Information about delays" msgstr "Informacion suls relambis" -#: themes/default/templates/render.html.ep:49 +#: themes/default/templates/partial/render.js.ep:6 msgid "It seems that the key in your URL is incorrect. Please, verify your URL." msgstr "Sembla que la clau dins vòstra URL siá incorrècta. Mercés de verificar vòstra URL." @@ -260,7 +264,7 @@ msgstr "Javascript es desactivat. Lufi foncionarà pas." msgid "Login" msgstr "Identificant" -#: themes/default/templates/layouts/default.html.ep:67 themes/default/templates/layouts/default.html.ep:79 +#: themes/default/templates/layouts/default.html.ep:37 themes/default/templates/layouts/default.html.ep:49 msgid "Logout" msgstr "Desconnexion" @@ -272,7 +276,7 @@ msgstr "Lufi es un logicial liure d’albèrgament de fichièrs." msgid "Mail" msgstr "Corrièl" -#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:61 themes/default/templates/layouts/default.html.ep:73 +#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:31 themes/default/templates/layouts/default.html.ep:43 msgid "My files" msgstr "Mos fichièrs" @@ -281,7 +285,7 @@ msgstr "Mos fichièrs" 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)." -#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 +#: themes/default/templates/partial/files.js.ep:10 themes/default/templates/partial/index.js.ep:27 msgid "No expiration delay" msgstr "Pas cap de relambi d’expiracion" @@ -289,7 +293,7 @@ msgstr "Pas cap de relambi d’expiracion" msgid "Only the files sent with this browser will be listed here. This list is stored in localStorage: if you delete your localStorage data, you'll lose this list." msgstr "Sols los fichièrs mandats amb aqueste navigador web son listats aicí. Las informacions son gardadas en localStorage : se suprimissètz vòstras donadas localStorage, perdretz aquelas informacions." -#: themes/default/templates/index.html.ep:70 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 +#: themes/default/templates/index.html.ep:80 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 msgid "Password" msgstr "Senhal" @@ -302,7 +306,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:136 +#: lib/Lufi.pm:137 msgid "Please, check your credentials: unable to authenticate." msgstr "Mercés de verificar vòstres identificants : impossible de vos autentificar." @@ -318,7 +322,7 @@ msgstr "Suprimir del localStorage los fichièrs expirats" msgid "Rows in red mean that the files have expired and are no longer available." msgstr "Las linhas en roge indican que lo fichièr a expirat e es pas mai disponible." -#: themes/default/templates/index.html.ep:116 +#: themes/default/templates/partial/index.js.ep:26 msgid "Send all links by email" msgstr "Mandar totes los ligams per corrièl" @@ -330,20 +334,20 @@ msgstr "Mandar amb aqueste servidor" msgid "Send with your own mail software" msgstr "Mandar amb vòstre pròpri logicial de corrièl" -#: themes/default/templates/index.html.ep:118 +#: themes/default/templates/partial/index.js.ep:28 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "Mandadís del fragment XX1 sus XX2. Pacientatz, la barra de progression pòt metre de temps abans d’avançar." #. (url_for('/') -#: themes/default/templates/mail.html.ep:91 +#: themes/default/templates/partial/mail.js.ep:43 msgid "Share your files in total privacy on %1" msgstr "Partejatz vòstres fichièrs en tota confidencialitat sus %1" -#: themes/default/templates/layouts/default.html.ep:63 themes/default/templates/layouts/default.html.ep:75 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 +#: themes/default/templates/layouts/default.html.ep:33 themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 msgid "Signin" msgstr "Connexion" -#: lib/Lufi.pm:139 +#: lib/Lufi.pm:140 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 "O planhèm collèga, sètz pas autorizat a utilizar aqueste servici. Contactatz vòstre administrator sistèma se pensatz que i a un problèma." @@ -359,7 +363,7 @@ msgstr "O planhèm, la foncion per mandar de fichièr es desactivada." msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "L’administrator pòt pas que veire lo nom del fichièr, sa talha e son mimetype (Quina mena de fichièr es : vidèo, tèxte, etc.)." -#: themes/default/templates/files.html.ep:51 +#: themes/default/templates/partial/files.js.ep:11 msgid "The data has been successfully imported." msgstr "Las donadas son ben estadas importadas." @@ -371,7 +375,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:390 +#: lib/Lufi/Controller/Files.pm:392 msgid "The file has already been deleted" msgstr "Lo fichièr es ja estat suprimit" @@ -384,7 +388,7 @@ msgstr "Los fichièrs mandats amb una instància Lufi son chifrats abans la mand msgid "The following email addresses are not valid: %1" msgstr "Las adreças de corrièl seguentas son pas validas : %1" -#: themes/default/templates/index.html.ep:106 +#: themes/default/templates/partial/index.js.ep:16 msgid "The link(s) has been copied to your clipboard" msgstr "Lo(s) ligam(s) es/son estat(s) copiat(s) dins vòstre quicha-papièrs" @@ -396,7 +400,7 @@ msgstr "Lo corrièl es estat mandat." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "L’autor original (e pel moment, lo sol) es Luc Didry. S’avètz enveja de lo sostenir, podètz o far via Tipeee o via Liberapay." -#: lib/Lufi/Controller/Files.pm:179 +#: lib/Lufi/Controller/Files.pm:181 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." @@ -404,26 +408,26 @@ msgstr "Lo servidor es pas estat capable de retrobar l’enregistrament del fich 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 "Aqueste servidor impausa de limitacions segon la talha dels fichièrs. Lo relambi d’expiracion de vòstre fichièr serà lo minimum entre çò qu’avètz causit e los limits seguents :" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/partial/index.js.ep:17 msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossible de copiar lo(s) ligams(s) dins vòstre quicha-papièrs" #. ($short) -#: lib/Lufi/Controller/Files.pm:361 +#: lib/Lufi/Controller/Files.pm:363 msgid "Unable to get counter for %1. The file does not exists. It will be removed from your localStorage." msgstr "Impossible de recuperar lo comptador per %1. Lo fichièr existís pas. Serà levat de vòstre localStorage." #. ($short) -#: lib/Lufi/Controller/Files.pm:351 +#: lib/Lufi/Controller/Files.pm:353 msgid "Unable to get counter for %1. The token is invalid." msgstr "Impossible de recuperar lo comptador per %1. Lo geton es invalid." #. ($short) -#: lib/Lufi/Controller/Files.pm:371 +#: lib/Lufi/Controller/Files.pm:373 msgid "Unable to get counter for %1. You are not authenticated." msgstr "Impossible de recuperar lo comptador per %1. Sètz pas connectat·ada." -#: themes/default/templates/layouts/default.html.ep:60 themes/default/templates/layouts/default.html.ep:72 +#: themes/default/templates/layouts/default.html.ep:30 themes/default/templates/layouts/default.html.ep:42 msgid "Upload files" msgstr "Mandar de fichièrs" @@ -431,11 +435,11 @@ msgstr "Mandar de fichièrs" msgid "Uploaded at" msgstr "Mandat lo" -#: themes/default/templates/index.html.ep:85 +#: themes/default/templates/index.html.ep:95 msgid "Uploaded files" msgstr "Fichièrs mandats" -#: themes/default/templates/index.html.ep:119 +#: themes/default/templates/partial/index.js.ep:29 msgid "Websocket communication error" msgstr "Error de comunicacion WebSocket" @@ -455,15 +459,15 @@ msgstr "Podètz veire la lista de vòstres fichièrs en clicant sul ligam « Mos msgid "You don't need to register yourself to upload files but be aware that, for legal reasons, your IP address will be stored when you send a file. Don't panic, this is normally the case for all sites on which you send files." msgstr "Avètz pas besonh de vos enregistrar per mandar de fichièrs mas notatz que, per de rasons legalas, vòstra adreça IP serà enregistrada quand mandatz un fichièr. Paniquetz pas, es normalament lo cas per totes los sites ont mandatz de fichièrs." -#: themes/default/templates/render.html.ep:53 +#: themes/default/templates/partial/render.js.ep:10 msgid "You don't seem to have a key in your URL. You won't be able to decrypt the file. Download canceled." msgstr "Sembla qu’avètz pas la bona clau dins l’URL. Poiretz pas deschifrar lo fichièr. Telecargament anullat." -#: themes/default/templates/render.html.ep:50 +#: themes/default/templates/partial/render.js.ep:7 msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Ensajatz de partir de la pagina. Lo telecargament serà anullat. Sètz segur-a ?" -#: themes/default/templates/index.html.ep:104 +#: themes/default/templates/partial/index.js.ep:14 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Ensajatz de partir de la pagina. Lo mandadís serà anullat. Sètz segur-a ?" @@ -480,7 +484,7 @@ msgstr "Vos cal donar d’adreças." 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:273 +#: lib/Lufi/Controller/Files.pm:275 msgid "Your password is not valid. Please refresh the page to retry." msgstr "Lo senhal es pas valid. Mercés d’actualizar la pagina e ensajar tornamai." @@ -494,7 +498,7 @@ msgstr "entre %1 e %2, lo fichièr serà gardat %3 jorn(s) ;" msgid "between %1 and %2, the file will be kept forever." msgstr "entre %1 e %2, lo fichièr serà gardat per totjorn. ;" -#: themes/default/templates/mail.html.ep:85 +#: themes/default/templates/partial/mail.js.ep:37 msgid "deadline: " msgstr "darrièr relambi per telecargar :" @@ -512,6 +516,6 @@ msgstr "per %1 e mai, lo fichièr serà gardat per totjorn." msgid "no time limit" msgstr "Pas cap de relambi d’expiracion" -#: themes/default/templates/index.html.ep:78 +#: themes/default/templates/index.html.ep:88 msgid "or" msgstr "o" diff --git a/themes/default/lib/Lufi/I18N/pt.po b/themes/default/lib/Lufi/I18N/pt.po index 36a7951..26d3663 100644 --- a/themes/default/lib/Lufi/I18N/pt.po +++ b/themes/default/lib/Lufi/I18N/pt.po @@ -32,7 +32,7 @@ msgstr "1 ano" msgid "24 hours" msgstr "24 horas" -#: themes/default/templates/mail.html.ep:83 +#: themes/default/templates/partial/mail.js.ep:35 msgid ":" msgstr " :" @@ -44,11 +44,11 @@ msgstr "Um obrigado com a foto de um gatinho no AGPLv3, pode instalar-lo no seu prórpio servidor. Para saber mais clique aqui Wiki para ver o procedimento." #. (stash('f') -#: themes/default/templates/render.html.ep:52 +#: themes/default/templates/partial/render.js.ep:9 msgid "Asking for file part XX1 of %1" msgstr "Pedido de recuperação de um fragmento do ficheiro XX1 de %1" @@ -69,11 +69,11 @@ msgstr "Voltar à página inicial" msgid "Bad CSRF token!" msgstr "Símbolo errado CSRF !" -#: themes/default/templates/render.html.ep:48 +#: themes/default/templates/partial/render.js.ep:5 msgid "Click here to refresh the page and restart the download." msgstr "Clique aqui para atualizar a página e começar o download." -#: themes/default/templates/index.html.ep:80 +#: themes/default/templates/index.html.ep:90 msgid "Click to open the file browser" msgstr "Clique para abrir o navegador de ficheiros" @@ -85,23 +85,23 @@ msgstr "Fechar" msgid "Comma-separated email addresses" msgstr "Os e-mails devem ser separados por vírgulas" -#: themes/default/templates/index.html.ep:105 +#: themes/default/templates/partial/index.js.ep:15 msgid "Copy all links to clipboard" msgstr "Copiar todos os links para a área de transferência" -#: themes/default/templates/index.html.ep:108 +#: themes/default/templates/partial/index.js.ep:18 msgid "Copy to clipboard" msgstr "Copiar para a área de transferência" -#: lib/Lufi/Controller/Files.pm:429 +#: lib/Lufi/Controller/Files.pm:431 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:411 +#: lib/Lufi/Controller/Files.pm:413 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:322 +#: lib/Lufi/Controller/Files.pm:324 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?" @@ -109,7 +109,7 @@ msgstr "Impossível encontar o ficheiro. Tem a certeza de que o URL está corret msgid "Counter" msgstr "Contador" -#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:64 +#: themes/default/templates/files.html.ep:29 themes/default/templates/index.html.ep:74 msgid "Delete at first download?" msgstr "Apagar após o primeiro download?" @@ -117,7 +117,7 @@ msgstr "Apagar após o primeiro download?" msgid "Delete selected files" msgstr "" -#: themes/default/templates/files.html.ep:32 themes/default/templates/index.html.ep:109 +#: themes/default/templates/files.html.ep:32 themes/default/templates/partial/index.js.ep:19 msgid "Deletion link" msgstr "Eliminar o link" @@ -125,15 +125,15 @@ msgstr "Eliminar o link" msgid "Don't worry: if a user begins to download the file before the expiration and the download ends after the expiration, he will be able to get the file." msgstr "Não se preocupe: se um utilizador começa a descarregar um ficheiro antes a sua expiração e que o descarregamento acaba após a sua expiração, o utilizador pode ainda assim recuperar o ficheiro." -#: themes/default/templates/index.html.ep:111 themes/default/templates/render.html.ep:28 +#: themes/default/templates/partial/index.js.ep:21 themes/default/templates/render.html.ep:28 msgid "Download" msgstr "Download" -#: themes/default/templates/render.html.ep:47 +#: themes/default/templates/partial/render.js.ep:4 msgid "Download aborted." msgstr "Download interrompido." -#: themes/default/templates/files.html.ep:27 themes/default/templates/index.html.ep:110 +#: themes/default/templates/files.html.ep:27 themes/default/templates/partial/index.js.ep:20 msgid "Download link" msgstr "Link para o download" @@ -141,7 +141,7 @@ msgstr "Link para o download" msgid "Drag and drop files in the appropriate area or use the traditional way to send files and the files will be chunked, encrypted and sent to the server. You will get two links per file: a download link, that you give to the people you want to share the file with and a deletion link, allowing you to delete the file whenever you want." msgstr "Deslize os ficheiros na zona própria e esse efeito ou selecione um ficheiro de forma tradicional, e os ficheiros serão fragmentados, codificados e enviados ao servidor. Vai receber dois links por ficheiro: um é de download e o outro para poder apagar o ficheiro quando quiser." -#: themes/default/templates/index.html.ep:77 +#: themes/default/templates/index.html.ep:87 msgid "Drop files here" msgstr "" @@ -161,23 +161,23 @@ msgstr "Assunto do e-mail" msgid "Emails" msgstr "E-mails" -#: themes/default/templates/index.html.ep:112 +#: themes/default/templates/partial/index.js.ep:22 msgid "Encrypting part XX1 of XX2" msgstr "Codificação do fragmento XX1 de XX2" -#: lib/Lufi/Controller/Files.pm:225 +#: lib/Lufi/Controller/Files.pm:227 msgid "Error: the file existed but was deleted." msgstr "Erro: o ficheiro existia mas foi apagado." -#: lib/Lufi/Controller/Files.pm:291 +#: lib/Lufi/Controller/Files.pm:293 msgid "Error: the file has not been sent entirely." msgstr "Erro: o ficheiro não foi enviado na totalidade." -#: lib/Lufi/Controller/Files.pm:301 +#: lib/Lufi/Controller/Files.pm:303 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?" -#: themes/default/templates/index.html.ep:113 +#: themes/default/templates/partial/index.js.ep:23 msgid "Expiration:" msgstr "Expiração:" @@ -189,7 +189,7 @@ msgstr "Expira no" msgid "Export localStorage data" msgstr "Exportar os dados localStorage" -#: lib/Lufi/Controller/Files.pm:393 +#: lib/Lufi/Controller/Files.pm:395 msgid "File deleted" msgstr "Ficheiro apagado" @@ -197,7 +197,11 @@ msgstr "Ficheiro apagado" msgid "File name" msgstr "Nome do ficheiro" -#: themes/default/templates/render.html.ep:51 +#: themes/default/templates/index.html.ep:64 +msgid "Files deleted at first download" +msgstr "" + +#: themes/default/templates/partial/render.js.ep:8 msgid "Get the file" msgstr "Recuperar o ficheiro" @@ -205,7 +209,7 @@ msgstr "Recuperar o ficheiro" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Recupere o código-fonte no o depósito oficial ou então réplicas Github." -#: themes/default/templates/mail.html.ep:78 +#: themes/default/templates/partial/mail.js.ep:30 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Olá,\\n\\nAqui estão alguns ficheiros que gostaria de partilhar contigo:\\n" @@ -213,11 +217,11 @@ msgstr "Olá,\\n\\nAqui estão alguns ficheiros que gostaria de partilhar contig msgid "Here's some files" msgstr "Aqui estão alguns ficheiros" -#: themes/default/templates/index.html.ep:115 +#: themes/default/templates/partial/index.js.ep:25 msgid "Hit Enter, then Ctrl+C to copy all the download links" msgstr "Clique no Enter e depois Ctrl+C para copiar todos os links de download" -#: themes/default/templates/index.html.ep:114 +#: themes/default/templates/partial/index.js.ep:24 msgid "Hit Enter, then Ctrl+C to copy the download link" msgstr "Clique no Enter e depois Ctrl+C para copiar o link de download" @@ -257,7 +261,7 @@ msgstr "Importante: mais informações sobre os prazos" msgid "Information about delays" msgstr "Informação sobre os prazos" -#: themes/default/templates/render.html.ep:49 +#: themes/default/templates/partial/render.js.ep:6 msgid "It seems that the key in your URL is incorrect. Please, verify your URL." msgstr "Parece que a chave do seu URL está incorreta.Por favor, verifique o seu URL." @@ -269,7 +273,7 @@ msgstr "Javascript está desativado. Lufi não funcionará." msgid "Login" msgstr "Utilizador" -#: themes/default/templates/layouts/default.html.ep:67 themes/default/templates/layouts/default.html.ep:79 +#: themes/default/templates/layouts/default.html.ep:37 themes/default/templates/layouts/default.html.ep:49 msgid "Logout" msgstr "Encerrar sessão" @@ -281,7 +285,7 @@ msgstr "Lufi é um programa de reserva gratuita (como na liberdade de expressão msgid "Mail" msgstr "" -#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:61 themes/default/templates/layouts/default.html.ep:73 +#: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:31 themes/default/templates/layouts/default.html.ep:43 msgid "My files" msgstr "Meus ficheiros" @@ -290,7 +294,7 @@ msgstr "Meus ficheiros" 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)." -#: themes/default/templates/files.html.ep:50 themes/default/templates/index.html.ep:117 +#: themes/default/templates/partial/files.js.ep:10 themes/default/templates/partial/index.js.ep:27 msgid "No expiration delay" msgstr "Não tem prazo de expiração" @@ -298,7 +302,7 @@ msgstr "Não tem prazo de expiração" msgid "Only the files sent with this browser will be listed here. This list is stored in localStorage: if you delete your localStorage data, you'll lose this list." msgstr "Apenas os ficheiros enviados com este navegador web estão listados aqui. As informações são armazenadas no localStorage : se apagar os seus dados no LocalStorage, poedrá perder essa informação." -#: themes/default/templates/index.html.ep:70 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 +#: themes/default/templates/index.html.ep:80 themes/default/templates/login.html.ep:21 themes/default/templates/render.html.ep:26 msgid "Password" msgstr "Palavra-passe" @@ -311,7 +315,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:136 +#: lib/Lufi.pm:137 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -327,7 +331,7 @@ msgstr "Apagar do localStorage os ficheiros expirados" msgid "Rows in red mean that the files have expired and are no longer available." msgstr "As linhas a vermelho indicam que o ficheiro expirou e já não está disponível." -#: themes/default/templates/index.html.ep:116 +#: themes/default/templates/partial/index.js.ep:26 msgid "Send all links by email" msgstr "Enviar todos os links por e-mail" @@ -339,20 +343,20 @@ msgstr "Enviar com este servidor" msgid "Send with your own mail software" msgstr "Enviar com o seu e-mail pessoal" -#: themes/default/templates/index.html.ep:118 +#: themes/default/templates/partial/index.js.ep:28 msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move." msgstr "Envio do fragmento XX1 de XX2. Por favor aguarde, a barra de progressão pode levar algum tempo antes de avançar." #. (url_for('/') -#: themes/default/templates/mail.html.ep:91 +#: themes/default/templates/partial/mail.js.ep:43 msgid "Share your files in total privacy on %1" msgstr "Partilhe os seus ficheiros com toda a privacidade em %1" -#: themes/default/templates/layouts/default.html.ep:63 themes/default/templates/layouts/default.html.ep:75 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 +#: themes/default/templates/layouts/default.html.ep:33 themes/default/templates/layouts/default.html.ep:45 themes/default/templates/login.html.ep:26 themes/default/templates/logout.html.ep:8 msgid "Signin" msgstr "Conexão" -#: lib/Lufi.pm:139 +#: lib/Lufi.pm:140 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 "" @@ -368,7 +372,7 @@ msgstr "Desculpe, o envio do ficheiro está desativado." msgid "The administrator can only see the file's name, its size and its mimetype (what kind of file it is: video, text, etc.)." msgstr "O administrador pode apenas ver o nome do ficheiro, o seu tamanho e o tipo de mime (o tipo de ficheiro: texto, vídeo, etc.)." -#: themes/default/templates/files.html.ep:51 +#: themes/default/templates/partial/files.js.ep:11 msgid "The data has been successfully imported." msgstr "Os dados foram importados com sucesso." @@ -380,7 +384,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:390 +#: lib/Lufi/Controller/Files.pm:392 msgid "The file has already been deleted" msgstr "O ficheiro já foi apagado" @@ -393,7 +397,7 @@ msgstr "Os ficheiros enviados no Lufi são codificados antes de serem enviados a msgid "The following email addresses are not valid: %1" msgstr "Os e-mails seguintes não são válidos: %1" -#: themes/default/templates/index.html.ep:106 +#: themes/default/templates/partial/index.js.ep:16 msgid "The link(s) has been copied to your clipboard" msgstr "O(s) link(s) foi/foram copiados para a área de transferência" @@ -405,7 +409,7 @@ msgstr "O e-mail foi enviado." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "O autor original (e por agora, o único) é Luc Didry. Se o desejar apoiar pode fazer-lo via Tipeee ou via Liberapay." -#: lib/Lufi/Controller/Files.pm:179 +#: lib/Lufi/Controller/Files.pm:181 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." @@ -413,26 +417,26 @@ msgstr "O servidor foi incapaz de encontrar o registo do ficheiro no qual devia- 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 "O servidor exige limites segundo o tamanho dos ficheiros. O prazo de expiração dos seu ficheiro sera o minimo entre o que você escolheu e os limites seguintes:" -#: themes/default/templates/index.html.ep:107 +#: themes/default/templates/partial/index.js.ep:17 msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossível copiar o(s) link(s) na sua área de transferência" #. ($short) -#: lib/Lufi/Controller/Files.pm:361 +#: lib/Lufi/Controller/Files.pm:363 msgid "Unable to get counter for %1. The file does not exists. It will be removed from your localStorage." msgstr "Impossível recuperar o contador para %1. O ficheiro não existe. Isso vai apagar a sua localStorage." #. ($short) -#: lib/Lufi/Controller/Files.pm:351 +#: lib/Lufi/Controller/Files.pm:353 msgid "Unable to get counter for %1. The token is invalid." msgstr "Impossível recuperar o contador para %1. O símbolo é inválido." #. ($short) -#: lib/Lufi/Controller/Files.pm:371 +#: lib/Lufi/Controller/Files.pm:373 msgid "Unable to get counter for %1. You are not authenticated." msgstr "Impossível recuperar o contador para %1. Não está conectado." -#: themes/default/templates/layouts/default.html.ep:60 themes/default/templates/layouts/default.html.ep:72 +#: themes/default/templates/layouts/default.html.ep:30 themes/default/templates/layouts/default.html.ep:42 msgid "Upload files" msgstr "Enviar os ficheiros" @@ -440,11 +444,11 @@ msgstr "Enviar os ficheiros" msgid "Uploaded at" msgstr "Enviar a" -#: themes/default/templates/index.html.ep:85 +#: themes/default/templates/index.html.ep:95 msgid "Uploaded files" msgstr "Ficheiros enviados" -#: themes/default/templates/index.html.ep:119 +#: themes/default/templates/partial/index.js.ep:29 msgid "Websocket communication error" msgstr "Erro de comunicação com WebSocket" @@ -468,15 +472,15 @@ msgstr "Pode ver a lista dos seus ficheiros clicando no link « Meus ficheiros msgid "You don't need to register yourself to upload files but be aware that, for legal reasons, your IP address will be stored when you send a file. Don't panic, this is normally the case for all sites on which you send files." msgstr "Não precisa registar-se para enviar ficheiros mas saiba que, por razões legais, o seu endereço IP ficará registrado quando envia um ficheiro. Não entre em pânico, é algo comum a todos os sites onde envia ficheiros." -#: themes/default/templates/render.html.ep:53 +#: themes/default/templates/partial/render.js.ep:10 msgid "You don't seem to have a key in your URL. You won't be able to decrypt the file. Download canceled." msgstr "Parece que não tem a chave no seu URL. Não poderá descodificar o ficheiro. Download anulado." -#: themes/default/templates/render.html.ep:50 +#: themes/default/templates/partial/render.js.ep:7 msgid "You have attempted to leave this page. The download will be canceled. Are you sure?" msgstr "Está a tentar sair da página. O download será anulado. Tem a certeza?" -#: themes/default/templates/index.html.ep:104 +#: themes/default/templates/partial/index.js.ep:14 msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?" msgstr "Está a tentar sair da página. O envio será anulado. Tem a certeza?" @@ -493,7 +497,7 @@ msgstr "Deve escrever os e-mails." 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:273 +#: lib/Lufi/Controller/Files.pm:275 msgid "Your password is not valid. Please refresh the page to retry." msgstr "" @@ -507,7 +511,7 @@ msgstr "entre %1 e %2, o ficheiro será conservado %3 dia(s) ;" msgid "between %1 and %2, the file will be kept forever." msgstr "entre %1 e %2, o ficheiro será conservado por um tempo indeterminado." -#: themes/default/templates/mail.html.ep:85 +#: themes/default/templates/partial/mail.js.ep:37 msgid "deadline: " msgstr "Data-limite: " @@ -525,6 +529,6 @@ msgstr "para %1 e mais, o ficheiro será conservado por um tempo indeterminado." msgid "no time limit" msgstr "Não tem limite de expiração" -#: themes/default/templates/index.html.ep:78 +#: themes/default/templates/index.html.ep:88 msgid "or" msgstr "ou" diff --git a/themes/default/public/css/lufi.css b/themes/default/public/css/lufi.css index 64ebd46..2732e14 100644 --- a/themes/default/public/css/lufi.css +++ b/themes/default/public/css/lufi.css @@ -108,3 +108,7 @@ a.classic:focus { .no_border { border: 0; } +.like-label { + color: #9e9e9e; + font-size: 1.5rem; +} diff --git a/themes/default/public/js/ie-detection.js b/themes/default/public/js/ie-detection.js new file mode 100644 index 0000000..3abc11b --- /dev/null +++ b/themes/default/public/js/ie-detection.js @@ -0,0 +1,29 @@ +function confirmExit() { + console.log(i18n.confirmExit); + return i18n.confirmExit; +} + +// Is the browser IE? +var isIE = /*@cc_on!@*/false || !!document.documentMode; + +// If the browser is IE, add readAsBinaryString function and store the data +if (isIE == true){ + if (FileReader.prototype.readAsBinaryString === undefined) { + FileReader.prototype.readAsBinaryString = function (fileData) { + var binary = ""; + var pt = this; + var reader = new FileReader(); + reader.onload = function (e) { + var bytes = new Uint8Array(reader.result); + var length = bytes.byteLength; + for (var i = 0; i < length; i++) { + binary += String.fromCharCode(bytes[i]); + } + //pt.result - readonly so assign content to another property + pt.content = binary; + $(pt).trigger('onloadend'); + } + reader.readAsArrayBuffer(fileData); + } + } +} diff --git a/themes/default/public/js/sidenav.js b/themes/default/public/js/sidenav.js new file mode 100644 index 0000000..0f5fe1f --- /dev/null +++ b/themes/default/public/js/sidenav.js @@ -0,0 +1,3 @@ +$(document).ready(function() { + $(".button-collapse").sideNav(); +}); diff --git a/themes/default/templates/files.html.ep b/themes/default/templates/files.html.ep index cf1ac15..551b80c 100644 --- a/themes/default/templates/files.html.ep +++ b/themes/default/templates/files.html.ep @@ -38,21 +38,6 @@
-%= javascript begin -% if (defined($self->config('fixed_domain')) && $self->config('fixed_domain')) { -var baseURL = '<%= url_for('/')->host($self->config('fixed_domain'))->to_abs() %>'; -% } else { -var baseURL = '<%= url_for('/')->to_abs() %>'; -% } -var actionURL = '<%= url_for('/')->to_abs() %>'; -var counterURL = '<%== url_for('counter') %>'; -var i18n = { - noExpiration: '<%= l('No expiration delay') %>', - importProcessed: '<%= l('The data has been successfully imported.') %>', -}; -$(document).ready(function() { - populateFilesTable(); -}); -% end +%= javascript '/partial/files.js.ep' %= javascript '/js/lufi-files.js' %= javascript '/js/moment-with-locales.min.js' diff --git a/themes/default/templates/index.html.ep b/themes/default/templates/index.html.ep index 95991e8..7fcb687 100644 --- a/themes/default/templates/index.html.ep +++ b/themes/default/templates/index.html.ep @@ -59,8 +59,18 @@
-

- + % if ($self->config('force_burn_after_reading')) { +

+ % } +

+ config('force_burn_after_reading') %> + >

@@ -88,37 +98,7 @@ %= include 'delays' -%= javascript begin -$(document).ready(function(){ - $('.modal-trigger').leanModal(); - $('select').material_select(); -}); -var ws_url = '<%= url_for('upload')->to_abs() %>'; -% if (defined($self->config('fixed_domain')) && $self->config('fixed_domain')) { -var baseURL = '<%= url_for('/')->host($self->config('fixed_domain'))->to_abs() %>'; -% } else { -var baseURL = '<%= url_for('/')->to_abs() %>'; -% } -var actionURL = '<%= url_for('/')->to_abs() %>'; -var i18n = { - confirmExit: '<%= l('You have attempted to leave this page. The upload will be canceled. Are you sure?') %>', - copyAll: '<%= l('Copy all links to clipboard') %>', - copySuccess: '<%= l('The link(s) has been copied to your clipboard') %>', - copyFail: '<%= l('Unable to copy the link(s) to your clipboard') %>', - cpText: '<%= l('Copy to clipboard') %>', - delText: '<%= l('Deletion link') %>', - dlText: '<%= l('Download link') %>', - download: '<%= l('Download') %>', - encrypting: '<%= l('Encrypting part XX1 of XX2') %>', - expiration: '<%= l('Expiration:') %>', - hit: '<%= l('Hit Enter, then Ctrl+C to copy the download link') %>', - hits: '<%= l('Hit Enter, then Ctrl+C to copy all the download links') %>', - mailTo: '<%= l('Send all links by email') %>', - noLimit: '<%= l('No expiration delay') %>', - sending: '<%= l('Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move.') %>', - wsProblem: '<%= l('Websocket communication error') %>', -}; -% end +%= javascript '/partial/index.js' %= javascript '/js/sjcl.js' %= javascript '/js/moment-with-locales.min.js' %= javascript '/js/lufi-up.js' diff --git a/themes/default/templates/layouts/default.html.ep b/themes/default/templates/layouts/default.html.ep index e406644..2addc67 100644 --- a/themes/default/templates/layouts/default.html.ep +++ b/themes/default/templates/layouts/default.html.ep @@ -17,37 +17,7 @@ %= stylesheet '/css/materialize.min.css' %= stylesheet '/css/lufi.css' - %= javascript begin - function confirmExit() { - console.log(i18n.confirmExit); - return i18n.confirmExit; - } - - // Is the browser IE? - var isIE = /*@cc_on!@*/false || !!document.documentMode; - - // If the browser is IE, add readAsBinaryString function and store the data - if (isIE == true){ - if (FileReader.prototype.readAsBinaryString === undefined) { - FileReader.prototype.readAsBinaryString = function (fileData) { - var binary = ""; - var pt = this; - var reader = new FileReader(); - reader.onload = function (e) { - var bytes = new Uint8Array(reader.result); - var length = bytes.byteLength; - for (var i = 0; i < length; i++) { - binary += String.fromCharCode(bytes[i]); - } - //pt.result - readonly so assign content to another property - pt.content = binary; - $(pt).trigger('onloadend'); - } - reader.readAsArrayBuffer(fileData); - } - } - } - % end + %= javascript '/js/ie-detection.js' @@ -90,10 +60,6 @@ % } %= javascript '/js/materialize.js' - %= javascript begin - $(document).ready(function() { - $(".button-collapse").sideNav(); - }); - %end + %= javascript '/js/sidenav.js' diff --git a/themes/default/templates/mail.html.ep b/themes/default/templates/mail.html.ep index 94bab1d..7886b7a 100644 --- a/themes/default/templates/mail.html.ep +++ b/themes/default/templates/mail.html.ep @@ -46,63 +46,5 @@ <%= l('Send with your own mail software') %>
-%= javascript begin - function findItem(name) { - var files = localStorage.getItem('files'); - if (files === null) { - files = new Array(); - } else { - files = JSON.parse(files); - } - var i; - for (i = 0; i < files.length; i++) { - if (files[i].short === name) { - return files[i]; - } - } - } - function updateMailtoLink() { - var btn = document.getElementById('mailto'); - var emails = document.getElementById('emails'); - var subject = document.getElementById('subject'); - var text = document.getElementById('body'); - - btn.href = 'mailto:'+encodeURIComponent(emails.value)+'?subject='+encodeURIComponent(subject.value)+'&body='+encodeURIComponent(text.value); - } - function populateBody() { - var links = [ - % for my $link (@{$links}) { - '<%= $link %>', - % } - ]; - var text = "<%== l('Hello,\n\nHere\'s some files I want to share with you:\n') %>"; - links.forEach(function(name, index, array) { - var item = findItem(name); - if (item !== null && item !== undefined) { - var limit = (item.delay === 0) ? null : moment.unix(item.delay * 86400 + item.created_at).locale(window.navigator.language).format('LLLL'); - text = text+'- '+item.name+'<%= l(':') %> '+item.url; - if (limit !== null) { - text = text+"\n (<%= l('deadline: ') %>"+limit+')'; - } - text = text+"\n"; - } - }); - - text = text+"\n--\n<%= l('Share your files in total privacy on %1', url_for('/')->to_abs) %>"; - tArea = document.getElementById('body').value = text; - updateMailtoLink(); - } - document.addEventListener('DOMContentLoaded', function() { -% unless (defined(stash('msg')) || defined(stash('values'))) { - populateBody(); -% } - - var emails = document.getElementById('emails'); - var subject = document.getElementById('subject'); - var text = document.getElementById('body'); - emails.addEventListener('change', updateMailtoLink); - subject.addEventListener('change', updateMailtoLink); - text.addEventListener('change', updateMailtoLink); - }); -% end +%= javascript '/partial/mail.js' %= javascript '/js/moment-with-locales.min.js' diff --git a/themes/default/templates/partial/files.js.ep b/themes/default/templates/partial/files.js.ep new file mode 100644 index 0000000..24d3e14 --- /dev/null +++ b/themes/default/templates/partial/files.js.ep @@ -0,0 +1,16 @@ +% # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab: +% if (defined($self->config('fixed_domain')) && $self->config('fixed_domain')) { + var baseURL = '<%= url_for('/')->host($self->config('fixed_domain'))->to_abs() %>'; +% } else { + var baseURL = '<%= url_for('/')->to_abs() %>'; +% } +var actionURL = '<%= url_for('/')->to_abs() %>'; +var counterURL = '<%== url_for('counter') %>'; +var i18n = { + noExpiration: '<%= l('No expiration delay') %>', + importProcessed: '<%= l('The data has been successfully imported.') %>', +}; +$(document).ready(function() { + populateFilesTable(); +}); + diff --git a/themes/default/templates/partial/index.js.ep b/themes/default/templates/partial/index.js.ep new file mode 100644 index 0000000..b56acbc --- /dev/null +++ b/themes/default/templates/partial/index.js.ep @@ -0,0 +1,30 @@ +% # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab: +$(document).ready(function(){ + $('.modal-trigger').leanModal(); + $('select').material_select(); +}); +var ws_url = '<%= url_for('upload')->to_abs() %>'; +% if (defined($self->config('fixed_domain')) && $self->config('fixed_domain')) { +var baseURL = '<%= url_for('/')->host($self->config('fixed_domain'))->to_abs() %>'; +% } else { +var baseURL = '<%= url_for('/')->to_abs() %>'; +% } +var actionURL = '<%= url_for('/')->to_abs() %>'; +var i18n = { + confirmExit: '<%= l('You have attempted to leave this page. The upload will be canceled. Are you sure?') %>', + copyAll: '<%= l('Copy all links to clipboard') %>', + copySuccess: '<%= l('The link(s) has been copied to your clipboard') %>', + copyFail: '<%= l('Unable to copy the link(s) to your clipboard') %>', + cpText: '<%= l('Copy to clipboard') %>', + delText: '<%= l('Deletion link') %>', + dlText: '<%= l('Download link') %>', + download: '<%= l('Download') %>', + encrypting: '<%= l('Encrypting part XX1 of XX2') %>', + expiration: '<%= l('Expiration:') %>', + hit: '<%= l('Hit Enter, then Ctrl+C to copy the download link') %>', + hits: '<%= l('Hit Enter, then Ctrl+C to copy all the download links') %>', + mailTo: '<%= l('Send all links by email') %>', + noLimit: '<%= l('No expiration delay') %>', + sending: '<%= l('Sending part XX1 of XX2. Please, be patient, the progress bar can take a while to move.') %>', + wsProblem: '<%= l('Websocket communication error') %>', +}; diff --git a/themes/default/templates/partial/mail.js.ep b/themes/default/templates/partial/mail.js.ep new file mode 100644 index 0000000..ed482d7 --- /dev/null +++ b/themes/default/templates/partial/mail.js.ep @@ -0,0 +1,58 @@ +% # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab: +function findItem(name) { + var files = localStorage.getItem('files'); + if (files === null) { + files = new Array(); + } else { + files = JSON.parse(files); + } + var i; + for (i = 0; i < files.length; i++) { + if (files[i].short === name) { + return files[i]; + } + } +} +function updateMailtoLink() { + var btn = document.getElementById('mailto'); + var emails = document.getElementById('emails'); + var subject = document.getElementById('subject'); + var text = document.getElementById('body'); + + btn.href = 'mailto:'+encodeURIComponent(emails.value)+'?subject='+encodeURIComponent(subject.value)+'&body='+encodeURIComponent(text.value); +} +function populateBody() { + var links = [ + % for my $link (@{$links}) { + '<%= $link %>', + % } + ]; + var text = "<%== l('Hello,\n\nHere\'s some files I want to share with you:\n') %>"; + links.forEach(function(name, index, array) { + var item = findItem(name); + if (item !== null && item !== undefined) { + var limit = (item.delay === 0) ? null : moment.unix(item.delay * 86400 + item.created_at).locale(window.navigator.language).format('LLLL'); + text = text+'- '+item.name+'<%= l(':') %> '+item.url; + if (limit !== null) { + text = text+"\n (<%= l('deadline: ') %>"+limit+')'; + } + text = text+"\n"; + } + }); + + text = text+"\n--\n<%= l('Share your files in total privacy on %1', url_for('/')->to_abs) %>"; + tArea = document.getElementById('body').value = text; + updateMailtoLink(); +} +document.addEventListener('DOMContentLoaded', function() { +% unless (defined(stash('msg')) || defined(stash('values'))) { + populateBody(); +% } + + var emails = document.getElementById('emails'); + var subject = document.getElementById('subject'); + var text = document.getElementById('body'); + emails.addEventListener('change', updateMailtoLink); + subject.addEventListener('change', updateMailtoLink); + text.addEventListener('change', updateMailtoLink); +}); diff --git a/themes/default/templates/partial/render.js.ep b/themes/default/templates/partial/render.js.ep new file mode 100644 index 0000000..60435e5 --- /dev/null +++ b/themes/default/templates/partial/render.js.ep @@ -0,0 +1,11 @@ +% # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab: +var ws_url = '<%= url_for('download')->to_abs() %>'; +var i18n = { + aborted1: '<%= l('Download aborted.') %>', + aborted2: '<%= l('Click here to refresh the page and restart the download.') %>', + badkey: '<%= l('It seems that the key in your URL is incorrect. Please, verify your URL.') %>', + confirmExit: '<%= l('You have attempted to leave this page. The download will be canceled. Are you sure?') %>', + download: '<%= l('Get the file') %>', + loading: '<%= l('Asking for file part XX1 of %1', stash('f')->nbslices) %>', + nokey: '<%= l('You don\'t seem to have a key in your URL. You won\'t be able to decrypt the file. Download canceled.') %>', +} diff --git a/themes/default/templates/render.html.ep b/themes/default/templates/render.html.ep index d867d8a..f1e5f13 100644 --- a/themes/default/templates/render.html.ep +++ b/themes/default/templates/render.html.ep @@ -41,18 +41,7 @@ -%= javascript begin -var ws_url = '<%= url_for('download')->to_abs() %>'; -var i18n = { - aborted1: '<%= l('Download aborted.') %>', - aborted2: '<%= l('Click here to refresh the page and restart the download.') %>', - badkey: '<%= l('It seems that the key in your URL is incorrect. Please, verify your URL.') %>', - confirmExit: '<%= l('You have attempted to leave this page. The download will be canceled. Are you sure?') %>', - download: '<%= l('Get the file') %>', - loading: '<%= l('Asking for file part XX1 of %1', stash('f')->nbslices) %>', - nokey: '<%= l('You don\'t seem to have a key in your URL. You won\'t be able to decrypt the file. Download canceled.') %>', -} -% end +%= javascript '/partial/render.js' %= javascript '/js/filesize.min.js' %= javascript '/js/sjcl.js' %= javascript '/js/lufi-down.js' From 80c7ecd5f473108eafc2409784cadf9b998753fa Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 21 Oct 2018 14:41:11 +0200 Subject: [PATCH 11/49] Add start_tls option for ldap --- cpanfile | 2 +- lufi.conf.template | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cpanfile b/cpanfile index 4659f35..b519fdf 100644 --- a/cpanfile +++ b/cpanfile @@ -4,7 +4,7 @@ requires 'Mojolicious::Plugin::DebugDumperHelper'; requires 'Mojolicious::Plugin::I18N'; requires 'Mojolicious::Plugin::Mail'; requires 'Mojolicious::Plugin::FiatTux::Helpers', '== 0.01', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-helpers/-/archive/0.01/mojolicious-plugin-fiattux-helpers-0.01.tar.gz'; -requires 'Mojolicious::Plugin::FiatTux::GrantAccess', '== 0.03', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-grantaccess/-/archive/0.03/mojolicious-plugin-fiattux-grantaccess-0.03.tar.gz'; +requires 'Mojolicious::Plugin::FiatTux::GrantAccess', '== 0.05', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-grantaccess/-/archive/0.05/mojolicious-plugin-fiattux-grantaccess-0.05.tar.gz'; requires 'EV'; requires 'Filesys::DiskUsage'; requires 'Switch'; diff --git a/lufi.conf.template b/lufi.conf.template index 22649d0..f01833c 100644 --- a/lufi.conf.template +++ b/lufi.conf.template @@ -146,6 +146,12 @@ # bind_pwd => 'secr3t', # search bind password # user_attr => 'uid', # user attribute (uid, mail, sAMAccountName, etc.) # user_filter => '(!(uid=ldap_user))', # user filter (to exclude some users, etc.) + # # optional start_tls configuration. See https://metacpan.org/pod/distribution/perl-ldap/lib/Net/LDAP.pod#start_tls + # # don't set or uncomment if you don't want to configure it + # start_tls => { + # verify => 'optional', + # clientcert => '/etc/ssl/certs/ca-bundle.pem' + # } #}, # set `htpasswd` if you want to use an htpasswd file instead of ldap From b6188097b1d1f92603f88e4a672c8646393b3ef4 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 21 Oct 2018 15:26:20 +0200 Subject: [PATCH 12/49] Fix #119 - Use GzipStatic and StaticCache plugins for speed --- CHANGELOG | 1 + cpanfile | 2 ++ cpanfile.snapshot | 15 +++++++++++++++ lib/Lufi.pm | 6 ++++++ lib/Mounter.pm | 6 ++++++ themes/default/lib/Lufi/I18N/ca.po | 4 ++-- themes/default/lib/Lufi/I18N/en.po | 4 ++-- themes/default/lib/Lufi/I18N/fr.po | 4 ++-- themes/default/lib/Lufi/I18N/it.po | 4 ++-- themes/default/lib/Lufi/I18N/nl.po | 4 ++-- themes/default/lib/Lufi/I18N/oc.po | 4 ++-- themes/default/lib/Lufi/I18N/pt.po | 4 ++-- 12 files changed, 44 insertions(+), 14 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 328fea3..2a79211 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ Revision history for Lufi - Use Mojo::SQLite instead of ORLite - Use FiatTux plugins - Option to force "Burn after reading" for each uploaded file + - Use GzipStatic and StaticCache plugins for speed 0.02.2 2017-09-18 - Fix cron tasks bug diff --git a/cpanfile b/cpanfile index b519fdf..96ef475 100644 --- a/cpanfile +++ b/cpanfile @@ -3,6 +3,8 @@ requires 'Mojolicious', '>= 7.31'; requires 'Mojolicious::Plugin::DebugDumperHelper'; requires 'Mojolicious::Plugin::I18N'; requires 'Mojolicious::Plugin::Mail'; +requires 'Mojolicious::Plugin::GzipStatic'; +requires 'Mojolicious::Plugin::StaticCache'; requires 'Mojolicious::Plugin::FiatTux::Helpers', '== 0.01', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-helpers/-/archive/0.01/mojolicious-plugin-fiattux-helpers-0.01.tar.gz'; requires 'Mojolicious::Plugin::FiatTux::GrantAccess', '== 0.05', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-grantaccess/-/archive/0.05/mojolicious-plugin-fiattux-grantaccess-0.05.tar.gz'; requires 'EV'; diff --git a/cpanfile.snapshot b/cpanfile.snapshot index 7c983f9..e5411ee 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -1032,6 +1032,14 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 Mojolicious 6.11 + Mojolicious-Plugin-GzipStatic-0.04 + pathname: L/LD/LDIDRY/Mojolicious-Plugin-GzipStatic-0.04.tar.gz + provides: + Mojolicious::Plugin::GzipStatic 0.04 + requirements: + ExtUtils::MakeMaker 0 + IO::Compress::Gzip 0 + Mojolicious 7.75 Mojolicious-Plugin-I18N-1.6 pathname: S/SH/SHARIFULN/Mojolicious-Plugin-I18N-1.6.tar.gz provides: @@ -1060,6 +1068,13 @@ DISTRIBUTIONS requirements: ExtUtils::MakeMaker 0 Mojolicious 7.23 + Mojolicious-Plugin-StaticCache-0.02 + pathname: L/LD/LDIDRY/Mojolicious-Plugin-StaticCache-0.02.tar.gz + provides: + Mojolicious::Plugin::StaticCache 0.02 + requirements: + ExtUtils::MakeMaker 0 + Mojolicious 7.33 Moo-2.003004 pathname: H/HA/HAARG/Moo-2.003004.tar.gz provides: diff --git a/lib/Lufi.pm b/lib/Lufi.pm index 1cf7437..3270ae4 100644 --- a/lib/Lufi.pm +++ b/lib/Lufi.pm @@ -67,6 +67,12 @@ sub startup { # Debug $self->plugin('DebugDumperHelper'); + # Compress static assets + $self->plugin('GzipStatic'); + + # Cache static assets + $self->plugin('StaticCache'); + # Fiat Tux helpers $self->plugin('FiatTux::Helpers'); diff --git a/lib/Mounter.pm b/lib/Mounter.pm index ab5b097..fd636ff 100644 --- a/lib/Mounter.pm +++ b/lib/Mounter.pm @@ -46,6 +46,12 @@ sub startup { } ); + # Compress static assets + $self->plugin('GzipStatic'); + + # Cache static assets + $self->plugin('StaticCache'); + # Helpers $self->plugin('Lufi::Plugin::Helpers'); diff --git a/themes/default/lib/Lufi/I18N/ca.po b/themes/default/lib/Lufi/I18N/ca.po index 17b72ae..a7de962 100644 --- a/themes/default/lib/Lufi/I18N/ca.po +++ b/themes/default/lib/Lufi/I18N/ca.po @@ -308,7 +308,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:137 +#: lib/Lufi.pm:143 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -349,7 +349,7 @@ msgstr "Compartiu fitxers amb total privacitat a %1" msgid "Signin" msgstr "Autenticació" -#: lib/Lufi.pm:140 +#: 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 "" diff --git a/themes/default/lib/Lufi/I18N/en.po b/themes/default/lib/Lufi/I18N/en.po index d9f5822..a2ca174 100644 --- a/themes/default/lib/Lufi/I18N/en.po +++ b/themes/default/lib/Lufi/I18N/en.po @@ -304,7 +304,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:137 +#: lib/Lufi.pm:143 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -345,7 +345,7 @@ msgstr "" msgid "Signin" msgstr "" -#: lib/Lufi.pm:140 +#: 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 "" diff --git a/themes/default/lib/Lufi/I18N/fr.po b/themes/default/lib/Lufi/I18N/fr.po index 647312f..96da5a4 100644 --- a/themes/default/lib/Lufi/I18N/fr.po +++ b/themes/default/lib/Lufi/I18N/fr.po @@ -306,7 +306,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:137 +#: lib/Lufi.pm:143 msgid "Please, check your credentials: unable to authenticate." msgstr "Veuillez vérifier vos identifiants : impossible de vous authentifier." @@ -347,7 +347,7 @@ msgstr "Partagez vos fichiers en toute confidentialité sur %1" msgid "Signin" msgstr "Connexion" -#: lib/Lufi.pm:140 +#: 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 "Désolé, vous n’êtes pas autorisé à utiliser ce service. Contactez votre administrateur si vous pensez qu’il s’agit d’une erreur." diff --git a/themes/default/lib/Lufi/I18N/it.po b/themes/default/lib/Lufi/I18N/it.po index 7502567..445a764 100644 --- a/themes/default/lib/Lufi/I18N/it.po +++ b/themes/default/lib/Lufi/I18N/it.po @@ -306,7 +306,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:137 +#: lib/Lufi.pm:143 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -351,7 +351,7 @@ msgstr "Condividi tutti i file in totale riservatezza su %1" msgid "Signin" msgstr "Autenticazione" -#: lib/Lufi.pm:140 +#: 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 "" diff --git a/themes/default/lib/Lufi/I18N/nl.po b/themes/default/lib/Lufi/I18N/nl.po index 08394a3..de9e67d 100644 --- a/themes/default/lib/Lufi/I18N/nl.po +++ b/themes/default/lib/Lufi/I18N/nl.po @@ -293,7 +293,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:137 +#: lib/Lufi.pm:143 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -338,7 +338,7 @@ msgstr "Deel je bestanden met volledige privacy op %1" msgid "Signin" msgstr "Inloggen" -#: lib/Lufi.pm:140 +#: 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 "" diff --git a/themes/default/lib/Lufi/I18N/oc.po b/themes/default/lib/Lufi/I18N/oc.po index e6ca54f..5be5dff 100644 --- a/themes/default/lib/Lufi/I18N/oc.po +++ b/themes/default/lib/Lufi/I18N/oc.po @@ -306,7 +306,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:137 +#: lib/Lufi.pm:143 msgid "Please, check your credentials: unable to authenticate." msgstr "Mercés de verificar vòstres identificants : impossible de vos autentificar." @@ -347,7 +347,7 @@ msgstr "Partejatz vòstres fichièrs en tota confidencialitat sus %1" msgid "Signin" msgstr "Connexion" -#: lib/Lufi.pm:140 +#: 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 "O planhèm collèga, sètz pas autorizat a utilizar aqueste servici. Contactatz vòstre administrator sistèma se pensatz que i a un problèma." diff --git a/themes/default/lib/Lufi/I18N/pt.po b/themes/default/lib/Lufi/I18N/pt.po index 26d3663..b466d49 100644 --- a/themes/default/lib/Lufi/I18N/pt.po +++ b/themes/default/lib/Lufi/I18N/pt.po @@ -315,7 +315,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:137 +#: lib/Lufi.pm:143 msgid "Please, check your credentials: unable to authenticate." msgstr "" @@ -356,7 +356,7 @@ msgstr "Partilhe os seus ficheiros com toda a privacidade em %1" msgid "Signin" msgstr "Conexão" -#: lib/Lufi.pm:140 +#: 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 "" From 25ab7e644da09494e03b5c3bee924f922a81f503 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 21 Oct 2018 18:24:48 +0200 Subject: [PATCH 13/49] Fix #78 - Allow to block files by setting an abuse field in DB --- CHANGELOG | 1 + lib/Lufi.pm | 130 ++++++------------ lib/Lufi/Controller/Auth.pm | 38 +++++ lib/Lufi/Controller/Files.pm | 24 ++++ lib/Lufi/Controller/Misc.pm | 28 ++++ lib/Lufi/DB/File.pm | 8 +- lib/Lufi/DB/File/SQLite.pm | 1 - lib/Lufi/Plugin/Helpers.pm | 19 ++- lufi.conf.template | 11 +- themes/default/lib/Lufi/I18N/ca.po | 46 +++---- themes/default/lib/Lufi/I18N/en.po | 46 +++---- themes/default/lib/Lufi/I18N/fr.po | 48 ++++--- themes/default/lib/Lufi/I18N/it.po | 46 +++---- themes/default/lib/Lufi/I18N/nl.po | 46 +++---- themes/default/lib/Lufi/I18N/oc.po | 46 ++++--- themes/default/lib/Lufi/I18N/pt.po | 46 +++---- themes/default/templates/mail.html.ep | 2 +- themes/default/templates/partial/mail.js.ep | 4 +- themes/default/templates/partial/render.js.ep | 4 +- themes/default/templates/render.html.ep | 2 +- utilities/migrations/pg.sql | 4 + utilities/migrations/sqlite.sql | 28 +++- 22 files changed, 368 insertions(+), 260 deletions(-) create mode 100644 lib/Lufi/Controller/Auth.pm diff --git a/CHANGELOG b/CHANGELOG index 2a79211..fda3386 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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 diff --git a/lib/Lufi.pm b/lib/Lufi.pm index 3270ae4..1c1c281 100644 --- a/lib/Lufi.pm +++ b/lib/Lufi.pm @@ -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'); - } - }); - # Authentication - $r->post('/login' => sub { - my $c = shift; - my $login = $c->param('login'); - my $pwd = $c->param('password'); + $r->get('/login') + ->to('Auth#login_page'); + + # Authentication + $r->post('/login') + ->to('Auth#login'); - 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'); - } - }); # 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; diff --git a/lib/Lufi/Controller/Auth.pm b/lib/Lufi/Controller/Auth.pm new file mode 100644 index 0000000..8d2a50e --- /dev/null +++ b/lib/Lufi/Controller/Auth.pm @@ -0,0 +1,38 @@ +# 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; diff --git a/lib/Lufi/Controller/Files.pm b/lib/Lufi/Controller/Files.pm index d4ed027..46b760c 100644 --- a/lib/Lufi/Controller/Files.pm +++ b/lib/Lufi/Controller/Files.pm @@ -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; diff --git a/lib/Lufi/Controller/Misc.pm b/lib/Lufi/Controller/Misc.pm index 1783d61..17eff6b 100644 --- a/lib/Lufi/Controller/Misc.pm +++ b/lib/Lufi/Controller/Misc.pm @@ -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; diff --git a/lib/Lufi/DB/File.pm b/lib/Lufi/DB/File.pm index 6ffc001..b0fd6ae 100644 --- a/lib/Lufi/DB/File.pm +++ b/lib/Lufi/DB/File.pm @@ -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 : string +=item B : integer + =item B : 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; } diff --git a/lib/Lufi/DB/File/SQLite.pm b/lib/Lufi/DB/File/SQLite.pm index 4a896a8..213e896 100644 --- a/lib/Lufi/DB/File/SQLite.pm +++ b/lib/Lufi/DB/File/SQLite.pm @@ -1,7 +1,6 @@ # 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; diff --git a/lib/Lufi/Plugin/Helpers.pm b/lib/Lufi/Plugin/Helpers.pm index 55ebcdf..0599084 100644 --- a/lib/Lufi/Plugin/Helpers.pm +++ b/lib/Lufi/Plugin/Helpers.pm @@ -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); diff --git a/lufi.conf.template b/lufi.conf.template index f01833c..5b196c7 100644 --- a/lufi.conf.template +++ b/lufi.conf.template @@ -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 ######################### diff --git a/themes/default/lib/Lufi/I18N/ca.po b/themes/default/lib/Lufi/I18N/ca.po index a7de962..8fd6c1f 100644 --- a/themes/default/lib/Lufi/I18N/ca.po +++ b/themes/default/lib/Lufi/I18N/ca.po @@ -56,7 +56,7 @@ msgstr "" msgid "As Lufi is a free software licensed under of the terms of the AGPLv3, you can install it on you own server. Have a look on the Wiki for the procedure." msgstr "Com que Lufi és programari lliure, autoritzat sota els termes de l'AGPLv3, el podeu instal·lar al vostre propi servidor. Pel que fa a com fer-ho, feu un cop d'ull al Wiki." -#. (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 Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "L'autor original (i per ara l'únic) és Luc Didry. Si voleu fer una contribució podeu fer-ho via Tipeee o via Liberapay." -#: 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 "" diff --git a/themes/default/lib/Lufi/I18N/en.po b/themes/default/lib/Lufi/I18N/en.po index a2ca174..bf9e9da 100644 --- a/themes/default/lib/Lufi/I18N/en.po +++ b/themes/default/lib/Lufi/I18N/en.po @@ -53,7 +53,7 @@ msgstr "" msgid "As Lufi is a free software licensed under of the terms of the AGPLv3, you can install it on you own server. Have a look on the Wiki 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 Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." 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 "" diff --git a/themes/default/lib/Lufi/I18N/fr.po b/themes/default/lib/Lufi/I18N/fr.po index 96da5a4..3768c1d 100644 --- a/themes/default/lib/Lufi/I18N/fr.po +++ b/themes/default/lib/Lufi/I18N/fr.po @@ -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 AGPLv3, you can install it on you own server. Have a look on the Wiki for the procedure." msgstr "Comme Lufi est un logiciel libre soumis aux termes de la license AGPLv3, vous pouvez l’installer sur votre propre serveur. Veuillez consulter le Wiki 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" -#: lib/Lufi/Controller/Files.pm:395 +#: lib/Lufi/Controller/Files.pm:419 msgid "File deleted" msgstr "Fichier supprimé" @@ -274,14 +274,14 @@ msgstr "Lufi est un logiciel libre d’hébergement de fichiers." #: themes/default/templates/files.html.ep:33 msgid "Mail" -msgstr "" +msgstr "Mail" #: themes/default/templates/files.html.ep:3 themes/default/templates/layouts/default.html.ep:31 themes/default/templates/layouts/default.html.ep:43 msgid "My files" msgstr "Mes fichiers" #. (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 "Espace disque insuffisant sur le serveur pour ce fichier (taille du fichier : %1)." @@ -306,9 +306,9 @@ 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:143 -msgid "Please, check your credentials: unable to authenticate." -msgstr "Veuillez vérifier vos identifiants : impossible de vous authentifier." +#: lib/Lufi/Controller/Auth.pm:24 +msgid "Please, check your credentials or your right to access this service: unable to authenticate." +msgstr "Veuillez vérifier vos identifiants ou votre droit d’accès à ce service : impossible de vous authentifier." #: themes/default/templates/about.html.ep:5 msgid "Privacy" @@ -347,7 +347,7 @@ msgstr "Partagez vos fichiers en toute confidentialité sur %1" msgid "Signin" msgstr "Connexion" -#: 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 "Désolé, vous n’êtes pas autorisé à utiliser ce service. Contactez votre administrateur si vous pensez qu’il s’agit d’une erreur." @@ -355,7 +355,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:43 +#: lib/Lufi/Controller/Files.pm:53 msgid "Sorry, uploading is disabled." msgstr "Désolé, l’envoi de fichier est désactivé." @@ -375,7 +375,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:392 +#: lib/Lufi/Controller/Files.pm:416 msgid "The file has already been deleted" msgstr "Le fichier a déjà été supprimé" @@ -400,10 +400,14 @@ msgstr "Le mail a été envoyé." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "L’auteur originel (et pour l’instant, le seul) est Luc Didry. Si vous avez envie de le supporter, vous pouvez le faire via Tipeee ou via Liberapay." -#: 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 "Le serveur a été incapable de retrouver l’enregistrement du fichier auquel ajouter votre fragment de fichier. Veuillez contacter l’administrateur." +#: 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 "Ce serveur impose des limitations selon la taille des fichiers. Le délai d’expiration de votre fichier sera le minimum entre ce que vous avez choisi et les limites suivantes :" @@ -413,17 +417,17 @@ msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossible de copier le(s) lien(s) dans votre presse-papier" #. ($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 "Impossible de récupérer le compteur pour %1. Le fichier n’existe pas. Il va être supprimé de votre localStorage." #. ($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 "Impossible de récupérer le compteur pour %1. Le jeton est invalide." #. ($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 "Impossible de récupérer le compteur pour %1. Vous n’êtes pas connecté·e." @@ -480,11 +484,11 @@ msgid "You must give email addresses." msgstr "Vous devez envoyer des adresses mail." #. (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 "Votre fichier est trop volumineux : %1 (la taille maximum autorisée est %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 "Votre mot de passe est invalide. Veuillez rafraîchir la page pour réessayer." diff --git a/themes/default/lib/Lufi/I18N/it.po b/themes/default/lib/Lufi/I18N/it.po index 445a764..ef703e7 100644 --- a/themes/default/lib/Lufi/I18N/it.po +++ b/themes/default/lib/Lufi/I18N/it.po @@ -55,7 +55,7 @@ msgstr "" msgid "As Lufi is a free software licensed under of the terms of the AGPLv3, you can install it on you own server. Have a look on the Wiki for the procedure." msgstr "Poiché Lufi è un software libero soggetto ai termini della licenza AGPLv3, potete installarlo sul vostro server. Si consulti Wiki per vedere la procedura." -#. (stash('f') +#. (stash('nbslices') #: themes/default/templates/partial/render.js.ep:9 msgid "Asking for file part XX1 of %1" msgstr "Recupero della porzione del file XX1 su %1" @@ -92,15 +92,15 @@ msgstr "Copiare tutti i link negli appunti" msgid "Copy to clipboard" msgstr "Copiare negli appunti" -#: lib/Lufi/Controller/Files.pm:431 +#: lib/Lufi/Controller/Files.pm:455 msgid "Could not delete the file. You are not authenticated." msgstr "Impossibile cancellare il file. Non siete autenticati." -#: 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 "Impossibile trovare il file. Sei sicuro che URL e token siano corretti ?" -#: 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 "Impossibile trovare il file. Sei sicuro che l'URL sia corretto?" @@ -160,15 +160,15 @@ msgstr "Email" msgid "Encrypting part XX1 of XX2" msgstr "Cifratura della parte XX1 di XX2" -#: lib/Lufi/Controller/Files.pm:227 +#: lib/Lufi/Controller/Files.pm:237 msgid "Error: the file existed but was deleted." msgstr "Errore: il file esisteva ma è stato eliminato" -#: lib/Lufi/Controller/Files.pm:293 +#: lib/Lufi/Controller/Files.pm:317 msgid "Error: the file has not been sent entirely." msgstr "Errore: il file non è stato inviato completamente" -#: 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 "Errore: impossibile trovare il file. Sei certo dell'URL ?" @@ -184,7 +184,7 @@ msgstr "Scadrà il" msgid "Export localStorage data" msgstr "Esportare i dati del localStorage" -#: lib/Lufi/Controller/Files.pm:395 +#: lib/Lufi/Controller/Files.pm:419 msgid "File deleted" msgstr "File cancellato" @@ -281,7 +281,7 @@ msgid "My files" msgstr "I miei file" #. (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 "Spazio disco insufficiente sul server per questo file (dimensione: %1)." @@ -306,8 +306,8 @@ 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: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 @@ -351,15 +351,11 @@ msgstr "Condividi tutti i file in totale riservatezza su %1" msgid "Signin" msgstr "Autenticazione" -#: 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 "L'invio del file è attualemente disattivato. Riprovare più tardi." -#: lib/Lufi/Controller/Files.pm:43 +#: lib/Lufi/Controller/Files.pm:53 msgid "Sorry, uploading is disabled." msgstr "L'invio del file è attualemente disattivato." @@ -383,7 +379,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:392 +#: lib/Lufi/Controller/Files.pm:416 msgid "The file has already been deleted" msgstr "Il file è già stato cancellato" @@ -408,10 +404,14 @@ msgstr "Email inviata." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "L'autore ( e per ora l'unico) è Luc Didry. Se aveste voglia di aiutarlo, potreste farlo tramite Tipeee ou via Liberapay." -#: 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 "Il server non è stato in grado di trovare il file record a cui aggiungere la vostra porzione di file. Prego contattare l'amministratore." +#: 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 "Questo server pone delle limitazioni in base alla dimensione del file.La data di scadenza del tuo file sarà la minore tra quella scelta e queste limitazioni:" @@ -421,17 +421,17 @@ msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossibile copiare i link negli appunti" #. ($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 "Impossibile recuperare il contatore per %1. Il file non esiste. Il file sarà eliminato dal tuo localStorage." #. ($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 "Impossibile recuperare il contatore per %1. Il token non è valido." #. ($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 "Impossibile recuperare il contatore per %1. Non sei autenticato." @@ -488,11 +488,11 @@ msgid "You must give email addresses." msgstr "Devi fornire gli indirizzi email." #. (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 "Il vostro file è troppo grande : %1 (la dimensione massima permessa è %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 "" diff --git a/themes/default/lib/Lufi/I18N/nl.po b/themes/default/lib/Lufi/I18N/nl.po index de9e67d..ce7d919 100644 --- a/themes/default/lib/Lufi/I18N/nl.po +++ b/themes/default/lib/Lufi/I18N/nl.po @@ -42,7 +42,7 @@ msgstr "" msgid "As Lufi is a free software licensed under of the terms of the AGPLv3, you can install it on you own server. Have a look on the Wiki for the procedure." msgstr "Aangezien Lufi een gratis software id die gelicentieerd staat onder de voorwaarden van AGPLv3, kan je het installeren op je eigen server. Bekijk Wiki voor de procedure." -#. (stash('f') +#. (stash('nbslices') #: themes/default/templates/partial/render.js.ep:9 msgid "Asking for file part XX1 of %1" msgstr "Deel XX1 van %1 wordt opgehaald" @@ -79,15 +79,15 @@ msgstr "Kopieer alle links naar klembord" msgid "Copy to clipboard" msgstr "Kopieer naar klembord" -#: lib/Lufi/Controller/Files.pm:431 +#: lib/Lufi/Controller/Files.pm:455 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:413 +#: lib/Lufi/Controller/Files.pm:437 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:324 +#: lib/Lufi/Controller/Files.pm:348 msgid "Could not find the file. Are you sure of the URL?" msgstr "Kan het bestand niet vinden. Klopt de URL?" @@ -147,15 +147,15 @@ msgstr "Emails" msgid "Encrypting part XX1 of XX2" msgstr "Encrypten deel XX1 van XX2 " -#: lib/Lufi/Controller/Files.pm:227 +#: lib/Lufi/Controller/Files.pm:237 msgid "Error: the file existed but was deleted." msgstr "Fout: het bestand bestond wel maar is verwijderd." -#: lib/Lufi/Controller/Files.pm:293 +#: lib/Lufi/Controller/Files.pm:317 msgid "Error: the file has not been sent entirely." msgstr "Fout: het bestand is niet volledig opgestuurd." -#: 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 "Fout: kan het bestand niet vinden. Is de URL juist?" @@ -171,7 +171,7 @@ msgstr "Vervalt op" msgid "Export localStorage data" msgstr "Exporteer opgeslagen data" -#: lib/Lufi/Controller/Files.pm:395 +#: lib/Lufi/Controller/Files.pm:419 msgid "File deleted" msgstr "Bestand verwijderd" @@ -268,7 +268,7 @@ msgid "My files" msgstr "Mijn bestanden" #. (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 "Geen genoeg ruimte op de server voor deze bestand (grootte: %1)." @@ -293,8 +293,8 @@ 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: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 @@ -338,15 +338,11 @@ msgstr "Deel je bestanden met volledige privacy op %1" msgid "Signin" msgstr "Inloggen" -#: 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 "Sorry, uploaden is momenteel uitgeschakeld. Probeer het later nogmaals." -#: lib/Lufi/Controller/Files.pm:43 +#: lib/Lufi/Controller/Files.pm:53 msgid "Sorry, uploading is disabled." msgstr "SOrry, uploaden is uitgeschakeld." @@ -366,7 +362,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:392 +#: lib/Lufi/Controller/Files.pm:416 msgid "The file has already been deleted" msgstr "Bestand is reeds verwijderd" @@ -391,10 +387,14 @@ msgstr "Email is verzonden." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "De oorspronkelijke auteur is Luc Didry. Als je hem wilt ondersteunen, dan kan dat via Tipeee of via Liberapay." -#: 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 "Server kon een deel van het bestand niet vinden. Neem contact op met beheerder." +#: 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 "Deze server stelt beperkingen vast volgens de bestandsgrootte. De vervaldatum van uw bestand zal het minimum zijn tussen wat u kiest en de volgende beperkingen:" @@ -404,17 +404,17 @@ msgid "Unable to copy the link(s) to your clipboard" msgstr "Kan de link(s) niet naar je klembord kopieeren" #. ($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 "Kan geen teller verkrijgen voor %1. Bestand bestaat niet. Het zal verwijderd worden van opgeslagen data." #. ($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 "Kan geen teller verkrijgen voor %1. De token is ongeldig." #. ($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 "Kan geen teller verkrijgen voor %1. Je bent niet geauthenticeerd." @@ -471,11 +471,11 @@ msgid "You must give email addresses." msgstr "Je moet een mail adres opgeven." #. (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 "Je bestand is te groot: %1 (max: %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 "" diff --git a/themes/default/lib/Lufi/I18N/oc.po b/themes/default/lib/Lufi/I18N/oc.po index 5be5dff..211f175 100644 --- a/themes/default/lib/Lufi/I18N/oc.po +++ b/themes/default/lib/Lufi/I18N/oc.po @@ -55,7 +55,7 @@ msgstr "Apondre un senhal al(s) fichièr(s)" msgid "As Lufi is a free software licensed under of the terms of the AGPLv3, you can install it on you own server. Have a look on the Wiki for the procedure." msgstr "Ja que Lufi es un logicial liure somés als tèrmes de la licéncia AGPLv3, podètz l’installar sus vòstre pròpri servidor. Mercés de consultar lo Wiki per veire la procedura." -#. (stash('f') +#. (stash('nbslices') #: themes/default/templates/partial/render.js.ep:9 msgid "Asking for file part XX1 of %1" msgstr "Demanda del tròç XX1 sus %1 del fichièr" @@ -92,15 +92,15 @@ msgstr "Copiar totes los ligams al quicha-papièrs" msgid "Copy to clipboard" msgstr "Copiar al quicha-papièrs" -#: 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 suprimir lo fichièr. Sètz pas connectat-ada." -#: 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 trobar lo fichièr. Sètz segur-a que l’URL e lo geton son 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 trobar lo fichièr. Sètz segur-a que l’URL es bona ?" @@ -160,15 +160,15 @@ msgstr "Corrièl" msgid "Encrypting part XX1 of XX2" msgstr "Chiframent del tròç XX1 sus XX2" -#: lib/Lufi/Controller/Files.pm:227 +#: lib/Lufi/Controller/Files.pm:237 msgid "Error: the file existed but was deleted." msgstr "Error : lo fichièr existissiá mas es estat suprimit" -#: lib/Lufi/Controller/Files.pm:293 +#: lib/Lufi/Controller/Files.pm:317 msgid "Error: the file has not been sent entirely." msgstr "Error : lo fichièr es pas estat mandat completament" -#: 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 : impossible de trobar lo fichièr. Sètz segur-a de l’URL ?" @@ -184,7 +184,7 @@ msgstr "Expira lo" msgid "Export localStorage data" msgstr "Exportar las donadas localStorage" -#: lib/Lufi/Controller/Files.pm:395 +#: lib/Lufi/Controller/Files.pm:419 msgid "File deleted" msgstr "Fichièr suprimit" @@ -281,7 +281,7 @@ msgid "My files" msgstr "Mos fichièrs" #. (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 "Espaci disc insufisent sul servidor per aqueste fichièr (talha del fichièr : \"%1)." @@ -306,7 +306,11 @@ 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:143 +#: lib/Lufi/Controller/Auth.pm:24 +msgid "Please, check your credentials or your right to access this service: unable to authenticate." +msgstr "" + +#: msgid "Please, check your credentials: unable to authenticate." msgstr "Mercés de verificar vòstres identificants : impossible de vos autentificar." @@ -347,7 +351,7 @@ msgstr "Partejatz vòstres fichièrs en tota confidencialitat sus %1" msgid "Signin" msgstr "Connexion" -#: 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 "O planhèm collèga, sètz pas autorizat a utilizar aqueste servici. Contactatz vòstre administrator sistèma se pensatz que i a un problèma." @@ -355,7 +359,7 @@ msgstr "O planhèm collèga, sètz pas autorizat a utilizar aqueste servici. Con 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:43 +#: lib/Lufi/Controller/Files.pm:53 msgid "Sorry, uploading is disabled." msgstr "O planhèm, la foncion per mandar de fichièr es desactivada." @@ -375,7 +379,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:392 +#: lib/Lufi/Controller/Files.pm:416 msgid "The file has already been deleted" msgstr "Lo fichièr es ja estat suprimit" @@ -400,10 +404,14 @@ msgstr "Lo corrièl es estat mandat." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "L’autor original (e pel moment, lo sol) es Luc Didry. S’avètz enveja de lo sostenir, podètz o far via Tipeee o via Liberapay." -#: 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 "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." +#: 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 "Aqueste servidor impausa de limitacions segon la talha dels fichièrs. Lo relambi d’expiracion de vòstre fichièr serà lo minimum entre çò qu’avètz causit e los limits seguents :" @@ -413,17 +421,17 @@ msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossible de copiar lo(s) ligams(s) dins vòstre quicha-papièrs" #. ($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 "Impossible de recuperar lo comptador per %1. Lo fichièr existís pas. Serà levat de vòstre localStorage." #. ($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 "Impossible de recuperar lo comptador per %1. Lo geton es invalid." #. ($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 "Impossible de recuperar lo comptador per %1. Sètz pas connectat·ada." @@ -480,11 +488,11 @@ msgid "You must give email addresses." msgstr "Vos cal donar d’adreças." #. (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 "Vòstre fichièr es tròp voluminós : %1 (la talha maximum autorizada es %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 "Lo senhal es pas valid. Mercés d’actualizar la pagina e ensajar tornamai." diff --git a/themes/default/lib/Lufi/I18N/pt.po b/themes/default/lib/Lufi/I18N/pt.po index b466d49..f8e66e9 100644 --- a/themes/default/lib/Lufi/I18N/pt.po +++ b/themes/default/lib/Lufi/I18N/pt.po @@ -56,7 +56,7 @@ msgstr "" msgid "As Lufi is a free software licensed under of the terms of the AGPLv3, you can install it on you own server. Have a look on the Wiki for the procedure." msgstr "Como Lufi é um programa livre sob os termos da licença AGPLv3, pode instalar-lo no seu prórpio servidor. Para saber mais clique aqui Wiki para ver o procedimento." -#. (stash('f') +#. (stash('nbslices') #: themes/default/templates/partial/render.js.ep:9 msgid "Asking for file part XX1 of %1" msgstr "Pedido de recuperação de um fragmento do ficheiro XX1 de %1" @@ -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:431 +#: lib/Lufi/Controller/Files.pm:455 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:413 +#: lib/Lufi/Controller/Files.pm:437 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:324 +#: lib/Lufi/Controller/Files.pm:348 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?" @@ -165,15 +165,15 @@ msgstr "E-mails" msgid "Encrypting part XX1 of XX2" msgstr "Codificação do fragmento XX1 de XX2" -#: lib/Lufi/Controller/Files.pm:227 +#: lib/Lufi/Controller/Files.pm:237 msgid "Error: the file existed but was deleted." msgstr "Erro: o ficheiro existia mas foi apagado." -#: lib/Lufi/Controller/Files.pm:293 +#: lib/Lufi/Controller/Files.pm:317 msgid "Error: the file has not been sent entirely." msgstr "Erro: o ficheiro não foi enviado na totalidade." -#: 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 "Erro: impossível encontrar o ficheiro. Tem a certeza do URL?" @@ -189,7 +189,7 @@ msgstr "Expira no" msgid "Export localStorage data" msgstr "Exportar os dados localStorage" -#: lib/Lufi/Controller/Files.pm:395 +#: lib/Lufi/Controller/Files.pm:419 msgid "File deleted" msgstr "Ficheiro apagado" @@ -290,7 +290,7 @@ msgid "My files" msgstr "Meus ficheiros" #. (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 "O servidor não tem espaço suficiente para este ficheiro (tamanho: %1)." @@ -315,8 +315,8 @@ 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: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 @@ -356,15 +356,11 @@ msgstr "Partilhe os seus ficheiros com toda a privacidade em %1" msgid "Signin" msgstr "Conexão" -#: 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 "Desculpe, o envio do ficheiro está atualmente desativado. Tente mais tarde." -#: lib/Lufi/Controller/Files.pm:43 +#: lib/Lufi/Controller/Files.pm:53 msgid "Sorry, uploading is disabled." msgstr "Desculpe, o envio do ficheiro está desativado." @@ -384,7 +380,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:392 +#: lib/Lufi/Controller/Files.pm:416 msgid "The file has already been deleted" msgstr "O ficheiro já foi apagado" @@ -409,10 +405,14 @@ msgstr "O e-mail foi enviado." msgid "The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay." msgstr "O autor original (e por agora, o único) é Luc Didry. Se o desejar apoiar pode fazer-lo via Tipeee ou via Liberapay." -#: 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 "O servidor foi incapaz de encontrar o registo do ficheiro no qual devia-se juntar o fragmento do seu ficheiro. Contacte o 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 "O servidor exige limites segundo o tamanho dos ficheiros. O prazo de expiração dos seu ficheiro sera o minimo entre o que você escolheu e os limites seguintes:" @@ -422,17 +422,17 @@ msgid "Unable to copy the link(s) to your clipboard" msgstr "Impossível copiar o(s) link(s) na sua área de transferência" #. ($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 "Impossível recuperar o contador para %1. O ficheiro não existe. Isso vai apagar a sua localStorage." #. ($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 "Impossível recuperar o contador para %1. O símbolo é inválido." #. ($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 "Impossível recuperar o contador para %1. Não está conectado." @@ -493,11 +493,11 @@ msgid "You must give email addresses." msgstr "Deve escrever os e-mails." #. (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 "O seu ficheiro é grande de mais: %1 (o tamanho máximo autorizado é de %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 "" diff --git a/themes/default/templates/mail.html.ep b/themes/default/templates/mail.html.ep index 7886b7a..d72d839 100644 --- a/themes/default/templates/mail.html.ep +++ b/themes/default/templates/mail.html.ep @@ -46,5 +46,5 @@ <%= l('Send with your own mail software') %>
-%= javascript '/partial/mail.js' +%= javascript url_for('/partial/mail.js')->query(populate => (!defined(stash('msg')) && !defined(stash('values'))), links => $links) %= javascript '/js/moment-with-locales.min.js' diff --git a/themes/default/templates/partial/mail.js.ep b/themes/default/templates/partial/mail.js.ep index ed482d7..d96bbae 100644 --- a/themes/default/templates/partial/mail.js.ep +++ b/themes/default/templates/partial/mail.js.ep @@ -23,7 +23,7 @@ function updateMailtoLink() { } function populateBody() { var links = [ - % for my $link (@{$links}) { + % for my $link (@{stash('links')}) { '<%= $link %>', % } ]; @@ -45,7 +45,7 @@ function populateBody() { updateMailtoLink(); } document.addEventListener('DOMContentLoaded', function() { -% unless (defined(stash('msg')) || defined(stash('values'))) { +% if (stash('populate')) { populateBody(); % } diff --git a/themes/default/templates/partial/render.js.ep b/themes/default/templates/partial/render.js.ep index 60435e5..0cafdad 100644 --- a/themes/default/templates/partial/render.js.ep +++ b/themes/default/templates/partial/render.js.ep @@ -1,11 +1,11 @@ % # vim:set sts=4 sw=4 ts=4 ft=javascript expandtab: -var ws_url = '<%= url_for('download')->to_abs() %>'; +var ws_url = '<%= url_for('download')->to_abs().stash('file') %>'; var i18n = { aborted1: '<%= l('Download aborted.') %>', aborted2: '<%= l('Click here to refresh the page and restart the download.') %>', badkey: '<%= l('It seems that the key in your URL is incorrect. Please, verify your URL.') %>', confirmExit: '<%= l('You have attempted to leave this page. The download will be canceled. Are you sure?') %>', download: '<%= l('Get the file') %>', - loading: '<%= l('Asking for file part XX1 of %1', stash('f')->nbslices) %>', + loading: '<%= l('Asking for file part XX1 of %1', stash('nbslices')) %>', nokey: '<%= l('You don\'t seem to have a key in your URL. You won\'t be able to decrypt the file. Download canceled.') %>', } diff --git a/themes/default/templates/render.html.ep b/themes/default/templates/render.html.ep index f1e5f13..6018c25 100644 --- a/themes/default/templates/render.html.ep +++ b/themes/default/templates/render.html.ep @@ -41,7 +41,7 @@ -%= javascript '/partial/render.js' +%= javascript '/partial/render.js?nbslices='.stash('f')->nbslices.'&file='.stash('f')->short %= javascript '/js/filesize.min.js' %= javascript '/js/sjcl.js' %= javascript '/js/lufi-down.js' diff --git a/utilities/migrations/pg.sql b/utilities/migrations/pg.sql index 5406a18..c4e3341 100644 --- a/utilities/migrations/pg.sql +++ b/utilities/migrations/pg.sql @@ -26,3 +26,7 @@ CREATE TABLE IF NOT EXISTS slices ( -- 1 down DROP TABLE slices; DROP TABLE files; +-- 2 up +ALTER TABLE files ADD COLUMN abuse integer; +-- 2 down +ALTER TABLE files DROP COLUMN abuse; diff --git a/utilities/migrations/sqlite.sql b/utilities/migrations/sqlite.sql index 90584f1..bd5bd69 100644 --- a/utilities/migrations/sqlite.sql +++ b/utilities/migrations/sqlite.sql @@ -13,7 +13,8 @@ CREATE TABLE IF NOT EXISTS files ( last_access_at INTEGER, mod_token TEXT, nbslices INTEGER, - complete INTEGER + complete INTEGER, + passwd TEXT ); CREATE TABLE IF NOT EXISTS slices ( short TEXT, @@ -26,3 +27,28 @@ CREATE INDEX IF NOT EXISTS slices_idx ON slices(short); DROP INDEX slices_idx ON slices(short); DROP TABLE slices; DROP TABLE files; +-- 2 up +ALTER TABLE files ADD COLUMN abuse INTEGER; +-- 2 down +BEGIN TRANSACTION; + CREATE TABLE files_backup ( + short TEXT PRIMARY KEY, + deleted INTEGER, + mediatype TEXT, + filename TEXT, + filesize INTEGER, + counter INTEGER, + delete_at_first_view INTEGER, + delete_at_day INTEGER, + created_at INTEGER, + created_by TEXT, + last_access_at INTEGER, + mod_token TEXT, + nbslices INTEGER, + complete INTEGER, + passwd TEXT + ); + INSERT INTO files_backup SELECT 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 FROM files; + DROP TABLE files; + ALTER TABLE files_backup RENAME TO files; +COMMIT; From ed472d705e893a47d23453d4636186b01f5349dd Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 21 Oct 2018 18:47:46 +0200 Subject: [PATCH 14/49] Fix #115 - Display file size when uploading --- CHANGELOG | 1 + themes/default/public/js/lufi-up.js | 7 +++++-- themes/default/templates/index.html.ep | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index fda3386..97f17c2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,7 @@ Revision history for Lufi - 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 + - Display file size when uploading 0.02.2 2017-09-18 - Fix cron tasks bug diff --git a/themes/default/public/js/lufi-up.js b/themes/default/public/js/lufi-up.js index e594927..e60787c 100644 --- a/themes/default/public/js/lufi-up.js +++ b/themes/default/public/js/lufi-up.js @@ -137,6 +137,7 @@ function uploadFile(i, delay, del_at_first_view) { // Get the file and properties var file = window.fileList[i]; var name = escapeHtml(file.name); + var size = filesize(file.size); var parts = Math.ceil(file.size/window.sliceLength); if (parts === 0) { parts = 1; @@ -152,7 +153,7 @@ function uploadFile(i, delay, del_at_first_view) { '', '', '
', - '', name, '', + '', name, ' (', size,')', '

', '
', '
', @@ -266,12 +267,13 @@ function updateProgressBar(data) { $('#parts-'+window.fc).remove(); var n = $('#name-'+window.fc); + var s = $('#size-'+window.fc); var d = $('
'); var url = baseURL+'r/'+short+'#'+key; var del_url = actionURL+'d/'+short+'/'+data.token; var links = encodeURIComponent('["'+short+'"]'); var limit = (delay === 0) ? i18n.noLimit : i18n.expiration+' '+moment.unix(delay * 86400 + created_at).locale(window.navigator.language).format('LLLL'); - n.html(n.html()+'
'+limit); + n.html(n.html()+' '+s.html()+'
'+limit); d.html(['
', '
', '', @@ -293,6 +295,7 @@ function updateProgressBar(data) { '', '
', '
'].join('')); + s.remove(); var p2 = dp.parent(); var p1 = p2.parent(); diff --git a/themes/default/templates/index.html.ep b/themes/default/templates/index.html.ep index 7fcb687..4d239b2 100644 --- a/themes/default/templates/index.html.ep +++ b/themes/default/templates/index.html.ep @@ -101,5 +101,6 @@ %= javascript '/partial/index.js' %= javascript '/js/sjcl.js' %= javascript '/js/moment-with-locales.min.js' +%= javascript '/js/filesize.min.js' %= javascript '/js/lufi-up.js' % } From 377ba0d0b8ede4ece269e3febf3d7c92daec9b07 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Sun, 21 Oct 2018 20:17:40 +0200 Subject: [PATCH 15/49] Add Content-Security-Policy header - related to #80 --- CHANGELOG | 1 + cpanfile | 1 + cpanfile.snapshot | 7 ++ lib/Lufi.pm | 7 +- lib/Lufi/Plugin/Headers.pm | 52 +++++++++ lib/Mounter.pm | 7 +- lufi.conf.template | 29 +++++ themes/default/lib/Lufi/I18N/ca.po | 8 +- themes/default/lib/Lufi/I18N/en.po | 8 +- themes/default/lib/Lufi/I18N/fr.po | 8 +- themes/default/lib/Lufi/I18N/it.po | 8 +- themes/default/lib/Lufi/I18N/nl.po | 8 +- themes/default/lib/Lufi/I18N/oc.po | 8 +- themes/default/lib/Lufi/I18N/pt.po | 8 +- themes/default/public/css/lufi.css | 104 ++++++++++++++++++ themes/default/public/js/filesize.min.js | 10 +- themes/default/public/js/filesize.min.js.map | 1 + themes/default/public/js/lufi-down.js | 6 +- themes/default/public/js/lufi-files.js | 15 ++- themes/default/public/js/lufi-up.js | 33 ++++-- themes/default/templates/files.html.ep | 8 +- .../default/templates/layouts/default.html.ep | 4 +- themes/default/templates/partial/files.js.ep | 4 + themes/default/templates/partial/mail.js.ep | 7 +- 24 files changed, 293 insertions(+), 59 deletions(-) create mode 100644 lib/Lufi/Plugin/Headers.pm create mode 100644 themes/default/public/js/filesize.min.js.map diff --git a/CHANGELOG b/CHANGELOG index 97f17c2..c3f40aa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,7 @@ Revision history for Lufi - Use GzipStatic and StaticCache plugins for speed - Allow to block files by setting an abuse field in DB - Display file size when uploading + - Add Content-Security-Policy header 0.02.2 2017-09-18 - Fix cron tasks bug diff --git a/cpanfile b/cpanfile index 96ef475..13f5a43 100644 --- a/cpanfile +++ b/cpanfile @@ -5,6 +5,7 @@ requires 'Mojolicious::Plugin::I18N'; requires 'Mojolicious::Plugin::Mail'; requires 'Mojolicious::Plugin::GzipStatic'; requires 'Mojolicious::Plugin::StaticCache'; +requires 'Mojolicious::Plugin::CSPHeader'; requires 'Mojolicious::Plugin::FiatTux::Helpers', '== 0.01', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-helpers/-/archive/0.01/mojolicious-plugin-fiattux-helpers-0.01.tar.gz'; requires 'Mojolicious::Plugin::FiatTux::GrantAccess', '== 0.05', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-grantaccess/-/archive/0.05/mojolicious-plugin-fiattux-grantaccess-0.05.tar.gz'; requires 'EV'; diff --git a/cpanfile.snapshot b/cpanfile.snapshot index e5411ee..25e52b4 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -1025,6 +1025,13 @@ DISTRIBUTIONS perl 5.010 strict 0 warnings 0 + Mojolicious-Plugin-CSPHeader-0.03 + pathname: L/LD/LDIDRY/Mojolicious-Plugin-CSPHeader-0.03.tar.gz + provides: + Mojolicious::Plugin::CSPHeader 0.03 + requirements: + ExtUtils::MakeMaker 0 + Mojolicious 7.75 Mojolicious-Plugin-DebugDumperHelper-0.03 pathname: L/LD/LDIDRY/Mojolicious-Plugin-DebugDumperHelper-0.03.tar.gz provides: diff --git a/lib/Lufi.pm b/lib/Lufi.pm index 1c1c281..5f47c7f 100644 --- a/lib/Lufi.pm +++ b/lib/Lufi.pm @@ -32,6 +32,9 @@ sub startup { dbtype => 'sqlite', db_path => 'lufi.db', force_burn_after_reading => 0, + x_frame_options => 'DENY', + x_content_type_options => 'nosniff', + x_xss_protection => '1; mode=block', } }); @@ -69,8 +72,8 @@ sub startup { # Compress static assets $self->plugin('GzipStatic'); - # Cache static assets - $self->plugin('StaticCache'); + # Headers + $self->plugin('Lufi::Plugin::Headers'); # Fiat Tux helpers $self->plugin('FiatTux::Helpers'); diff --git a/lib/Lufi/Plugin/Headers.pm b/lib/Lufi/Plugin/Headers.pm new file mode 100644 index 0000000..8c26cc5 --- /dev/null +++ b/lib/Lufi/Plugin/Headers.pm @@ -0,0 +1,52 @@ +package Lufi::Plugin::Headers; +use Mojo::Base 'Mojolicious::Plugin'; + +sub register { + my ($self, $app) = @_; + + # Assets Cache headers + $app->plugin('StaticCache'); + + # Add CSP Header + if (!defined($app->config('csp')) || (defined($app->config('csp')) && $app->config('csp') ne '')) { + my $directives = { + 'default-src' => "'none'", + 'script-src' => "'self' 'unsafe-inline' 'unsafe-eval'", + 'style-src' => "'self' 'unsafe-inline'", + 'img-src' => "'self' blob:", + 'media-src' => "blob:", + 'font-src' => "'self'", + 'form-action' => "'self'", + 'base-uri' => "'self'", + 'connect-src' => "'self'", + }; + + my $frame_ancestors = ''; + $frame_ancestors = "'none'" if $app->config('x_frame_options') eq 'DENY'; + $frame_ancestors = "'self'" if $app->config('x_frame_options') eq 'SAMEORIGIN'; + if ($app->config('x_frame_options') =~ m#^ALLOW-FROM#) { + $frame_ancestors = $app->config('x_frame_options'); + $frame_ancestors =~ s#ALLOW-FROM +##; + } + $directives->{'frame-ancestors'} = $frame_ancestors if $frame_ancestors; + + $app->plugin('CSPHeader', + csp => $app->config('csp'), + directives => $directives + ); + } + + # Add other headers + $app->hook( + before_dispatch => sub { + my $c = shift; + + $c->res->headers->header('X-Frame-Options' => $app->config('x_frame_options')) if $app->config('x_frame_options'); + $c->res->headers->header('X-Content-Type-Options' => $app->config('x_content_type_options')) if $app->config('x_content_type_options'); + $c->res->headers->header('X-XSS-Protection' => $app->config('x_xss_protection')) if $app->config('x_xss_protection'); + } + ); + +} + +1; diff --git a/lib/Mounter.pm b/lib/Mounter.pm index fd636ff..4d43d3c 100644 --- a/lib/Mounter.pm +++ b/lib/Mounter.pm @@ -42,6 +42,9 @@ sub startup { dbtype => 'sqlite', db_path => 'lufi.db', force_burn_after_reading => 0, + x_frame_options => 'DENY', + x_content_type_options => 'nosniff', + x_xss_protection => '1; mode=block', } } ); @@ -49,8 +52,8 @@ sub startup { # Compress static assets $self->plugin('GzipStatic'); - # Cache static assets - $self->plugin('StaticCache'); + # Headers + $self->plugin('Lufi::Plugin::Headers'); # Helpers $self->plugin('Lufi::Plugin::Helpers'); diff --git a/lufi.conf.template b/lufi.conf.template index 5b196c7..3ff1a97 100644 --- a/lufi.conf.template +++ b/lufi.conf.template @@ -184,6 +184,35 @@ # 1 => 'Illegal content', #}, + # Content-Security-Policy header that will be sent by Lufi + # Set to '' to disable CSP header + # https://content-security-policy.com/ provides a good documentation about CSP. + # https://report-uri.com/home/generate provides a tool to generate a CSP header. + # optional, default is "base-uri 'self'; connect-src 'self'; default-src 'none'; font-src 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' blob:; media-src blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'" + # the default value is good for `default` and `milligram` themes + #csp => "base-uri 'self'; connect-src 'self'; default-src 'none'; font-src 'self'; form-action 'self'; frame-ancestors 'none'; img-src 'self' blob:; media-src blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'" + + # X-Frame-Options header that will be sent by Lufi + # Valid values are: 'DENY', 'SAMEORIGIN', 'ALLOW-FROM https://example.com/' + # Set to '' to disable X-Frame-Options header + # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options + # Please note that this will add a "frame-ancestors" directive to the CSP header (see above) accordingly + # to the chosen setting (See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors) + # optional, default is 'DENY' + #x_frame_options => 'DENY', + + # X-Content-Type-Options that will be sent by Lufi + # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + # Set to '' to disable X-Content-Type-Options header + # optional, default is 'nosniff' + #x_content_type_options => 'nosniff', + + # X-XSS-Protection that will be sent by Lufi + # See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection + # Set to '' to disable X-XSS-Protection header + # optional, default is '1; mode=block' + #x_xss_protection => '1; mode=block', + ######################### # Lufi cron jobs settings ######################### diff --git a/themes/default/lib/Lufi/I18N/ca.po b/themes/default/lib/Lufi/I18N/ca.po index 8fd6c1f..c0f8e86 100644 --- a/themes/default/lib/Lufi/I18N/ca.po +++ b/themes/default/lib/Lufi/I18N/ca.po @@ -32,7 +32,7 @@ msgstr "1 any" msgid "24 hours" msgstr "24 hores" -#: themes/default/templates/partial/mail.js.ep:35 +#: themes/default/templates/partial/mail.js.ep:40 msgid ":" msgstr ":" @@ -205,7 +205,7 @@ msgstr "Obté el fitxer" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Obteniu el codi font al repositori oficial o a la seva rèplica a Github" -#: themes/default/templates/partial/mail.js.ep:30 +#: themes/default/templates/partial/mail.js.ep:35 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Hola,\\n\\nVe't aquí uns fitxers que vull compartir amb tu:" @@ -341,7 +341,7 @@ msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a msgstr "S'està enviant el tros XX1 de XX2. Si us plau, paciència; la barra de progrés pot trigar una mica a bellugar-se. " #. (url_for('/') -#: themes/default/templates/partial/mail.js.ep:43 +#: themes/default/templates/partial/mail.js.ep:48 msgid "Share your files in total privacy on %1" msgstr "Compartiu fitxers amb total privacitat a %1" @@ -502,7 +502,7 @@ msgstr "entre %1 i %2, el fitxer es mantindrà %3 dia/es al servidor." msgid "between %1 and %2, the file will be kept forever." msgstr "entre %1 i %2, el fitxer es mantindrà per sempre al servidor." -#: themes/default/templates/partial/mail.js.ep:37 +#: themes/default/templates/partial/mail.js.ep:42 msgid "deadline: " msgstr "termini:" diff --git a/themes/default/lib/Lufi/I18N/en.po b/themes/default/lib/Lufi/I18N/en.po index bf9e9da..ee222a5 100644 --- a/themes/default/lib/Lufi/I18N/en.po +++ b/themes/default/lib/Lufi/I18N/en.po @@ -29,7 +29,7 @@ msgstr "" msgid "24 hours" msgstr "" -#: themes/default/templates/partial/mail.js.ep:35 +#: themes/default/templates/partial/mail.js.ep:40 msgid ":" msgstr "" @@ -202,7 +202,7 @@ msgstr "" msgid "Get the source code on the official repository or on its Github mirror" msgstr "" -#: themes/default/templates/partial/mail.js.ep:30 +#: themes/default/templates/partial/mail.js.ep:35 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "" @@ -337,7 +337,7 @@ msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a msgstr "" #. (url_for('/') -#: themes/default/templates/partial/mail.js.ep:43 +#: themes/default/templates/partial/mail.js.ep:48 msgid "Share your files in total privacy on %1" msgstr "" @@ -496,7 +496,7 @@ msgstr "" msgid "between %1 and %2, the file will be kept forever." msgstr "" -#: themes/default/templates/partial/mail.js.ep:37 +#: themes/default/templates/partial/mail.js.ep:42 msgid "deadline: " msgstr "" diff --git a/themes/default/lib/Lufi/I18N/fr.po b/themes/default/lib/Lufi/I18N/fr.po index 3768c1d..97a5a6d 100644 --- a/themes/default/lib/Lufi/I18N/fr.po +++ b/themes/default/lib/Lufi/I18N/fr.po @@ -31,7 +31,7 @@ msgstr "1 an" msgid "24 hours" msgstr "24 heures" -#: themes/default/templates/partial/mail.js.ep:35 +#: themes/default/templates/partial/mail.js.ep:40 msgid ":" msgstr " :" @@ -204,7 +204,7 @@ msgstr "Récupérer le fichier" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Récupérez le code source sur le dépôt officiel ou sur son miroir Github." -#: themes/default/templates/partial/mail.js.ep:30 +#: themes/default/templates/partial/mail.js.ep:35 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Bonjour,\\n\\nVoici quelques fichiers que je souhaite partager avec toi :\\n" @@ -339,7 +339,7 @@ msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a msgstr "Envoi du fragment XX1 sur XX2. Veuillez patienter, la barre de progression peut mettre du temps avant d’avancer." #. (url_for('/') -#: themes/default/templates/partial/mail.js.ep:43 +#: themes/default/templates/partial/mail.js.ep:48 msgid "Share your files in total privacy on %1" msgstr "Partagez vos fichiers en toute confidentialité sur %1" @@ -502,7 +502,7 @@ msgstr "entre %1 et %2, le fichier sera conservé %3 jour(s) ;" msgid "between %1 and %2, the file will be kept forever." msgstr "entre %1 et %2, le fichier sera conservé indéfiniment ;" -#: themes/default/templates/partial/mail.js.ep:37 +#: themes/default/templates/partial/mail.js.ep:42 msgid "deadline: " msgstr "dernier délai pour télécharger : " diff --git a/themes/default/lib/Lufi/I18N/it.po b/themes/default/lib/Lufi/I18N/it.po index ef703e7..1208bf2 100644 --- a/themes/default/lib/Lufi/I18N/it.po +++ b/themes/default/lib/Lufi/I18N/it.po @@ -31,7 +31,7 @@ msgstr "1 anno" msgid "24 hours" msgstr "24 ore" -#: themes/default/templates/partial/mail.js.ep:35 +#: themes/default/templates/partial/mail.js.ep:40 msgid ":" msgstr "A :" @@ -204,7 +204,7 @@ msgstr "Ottenere il file" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Ottenere il codice sorgente su le dépôt officiel ou sur son miroir Github." -#: themes/default/templates/partial/mail.js.ep:30 +#: themes/default/templates/partial/mail.js.ep:35 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Buongiorno,\\n\\necco qualche file che vorrei condividere con te:\\n" @@ -343,7 +343,7 @@ msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a msgstr "Invio della parte XX1 su XX2. Prego attendere, la barra di avanzamento può impiegare del tempo prima di colorarsi." #. (url_for('/') -#: themes/default/templates/partial/mail.js.ep:43 +#: themes/default/templates/partial/mail.js.ep:48 msgid "Share your files in total privacy on %1" msgstr "Condividi tutti i file in totale riservatezza su %1" @@ -506,7 +506,7 @@ msgstr "tra %1 e %2, il file sarà conservato %3 giorno(i);" msgid "between %1 and %2, the file will be kept forever." msgstr "tra %1 e %2, il file sarà conservato per sempre;" -#: themes/default/templates/partial/mail.js.ep:37 +#: themes/default/templates/partial/mail.js.ep:42 msgid "deadline: " msgstr "scadenza: " diff --git a/themes/default/lib/Lufi/I18N/nl.po b/themes/default/lib/Lufi/I18N/nl.po index ce7d919..deac954 100644 --- a/themes/default/lib/Lufi/I18N/nl.po +++ b/themes/default/lib/Lufi/I18N/nl.po @@ -18,7 +18,7 @@ msgstr "1 jaar" msgid "24 hours" msgstr "24 uur" -#: themes/default/templates/partial/mail.js.ep:35 +#: themes/default/templates/partial/mail.js.ep:40 msgid ":" msgstr ":" @@ -191,7 +191,7 @@ msgstr "Download bestand" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Krijg de broncode op de officiële repository of op Github mirror" -#: themes/default/templates/partial/mail.js.ep:30 +#: themes/default/templates/partial/mail.js.ep:35 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Hallo,\\n\\nHier zijn enkele bestanden die ik met je wil delen:\\n\\n" @@ -330,7 +330,7 @@ msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a msgstr "Versturen deel XX1 van XX2. Een ogenblik geduld..." #. (url_for('/') -#: themes/default/templates/partial/mail.js.ep:43 +#: themes/default/templates/partial/mail.js.ep:48 msgid "Share your files in total privacy on %1" msgstr "Deel je bestanden met volledige privacy op %1" @@ -521,7 +521,7 @@ msgstr "tussen %1 en %1, bestand zal bewaard worden voor %3 dag(en)." msgid "between %1 and %2, the file will be kept forever." msgstr "tussen %1 en %2, bestand zal voor altijd bewaard worden." -#: themes/default/templates/partial/mail.js.ep:37 +#: themes/default/templates/partial/mail.js.ep:42 msgid "deadline: " msgstr "deadline: " diff --git a/themes/default/lib/Lufi/I18N/oc.po b/themes/default/lib/Lufi/I18N/oc.po index 211f175..31854c7 100644 --- a/themes/default/lib/Lufi/I18N/oc.po +++ b/themes/default/lib/Lufi/I18N/oc.po @@ -31,7 +31,7 @@ msgstr "1 an" msgid "24 hours" msgstr "24 oras" -#: themes/default/templates/partial/mail.js.ep:35 +#: themes/default/templates/partial/mail.js.ep:40 msgid ":" msgstr " :" @@ -204,7 +204,7 @@ msgstr "Recuperar lo fichièr" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Recuperatz lo còdi font sul depaus oficial o sus son miralh Github." -#: themes/default/templates/partial/mail.js.ep:30 +#: themes/default/templates/partial/mail.js.ep:35 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Bonjorn,\\n\\nVaquí qualques fichièrs que desiri partejar amb tu :\\n" @@ -343,7 +343,7 @@ msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a msgstr "Mandadís del fragment XX1 sus XX2. Pacientatz, la barra de progression pòt metre de temps abans d’avançar." #. (url_for('/') -#: themes/default/templates/partial/mail.js.ep:43 +#: themes/default/templates/partial/mail.js.ep:48 msgid "Share your files in total privacy on %1" msgstr "Partejatz vòstres fichièrs en tota confidencialitat sus %1" @@ -506,7 +506,7 @@ msgstr "entre %1 e %2, lo fichièr serà gardat %3 jorn(s) ;" msgid "between %1 and %2, the file will be kept forever." msgstr "entre %1 e %2, lo fichièr serà gardat per totjorn. ;" -#: themes/default/templates/partial/mail.js.ep:37 +#: themes/default/templates/partial/mail.js.ep:42 msgid "deadline: " msgstr "darrièr relambi per telecargar :" diff --git a/themes/default/lib/Lufi/I18N/pt.po b/themes/default/lib/Lufi/I18N/pt.po index f8e66e9..993e9dd 100644 --- a/themes/default/lib/Lufi/I18N/pt.po +++ b/themes/default/lib/Lufi/I18N/pt.po @@ -32,7 +32,7 @@ msgstr "1 ano" msgid "24 hours" msgstr "24 horas" -#: themes/default/templates/partial/mail.js.ep:35 +#: themes/default/templates/partial/mail.js.ep:40 msgid ":" msgstr " :" @@ -209,7 +209,7 @@ msgstr "Recuperar o ficheiro" msgid "Get the source code on the official repository or on its Github mirror" msgstr "Recupere o código-fonte no o depósito oficial ou então réplicas Github." -#: themes/default/templates/partial/mail.js.ep:30 +#: themes/default/templates/partial/mail.js.ep:35 msgid "Hello,\\n\\nHere's some files I want to share with you:\\n" msgstr "Olá,\\n\\nAqui estão alguns ficheiros que gostaria de partilhar contigo:\\n" @@ -348,7 +348,7 @@ msgid "Sending part XX1 of XX2. Please, be patient, the progress bar can take a msgstr "Envio do fragmento XX1 de XX2. Por favor aguarde, a barra de progressão pode levar algum tempo antes de avançar." #. (url_for('/') -#: themes/default/templates/partial/mail.js.ep:43 +#: themes/default/templates/partial/mail.js.ep:48 msgid "Share your files in total privacy on %1" msgstr "Partilhe os seus ficheiros com toda a privacidade em %1" @@ -511,7 +511,7 @@ msgstr "entre %1 e %2, o ficheiro será conservado %3 dia(s) ;" msgid "between %1 and %2, the file will be kept forever." msgstr "entre %1 e %2, o ficheiro será conservado por um tempo indeterminado." -#: themes/default/templates/partial/mail.js.ep:37 +#: themes/default/templates/partial/mail.js.ep:42 msgid "deadline: " msgstr "Data-limite: " diff --git a/themes/default/public/css/lufi.css b/themes/default/public/css/lufi.css index 2732e14..e07a977 100644 --- a/themes/default/public/css/lufi.css +++ b/themes/default/public/css/lufi.css @@ -112,3 +112,107 @@ a.classic:focus { color: #9e9e9e; font-size: 1.5rem; } +.white-background { + background-color: #FFF; +} +.width-0 { width: 0%; } +.width-1 { width: 1%; } +.width-2 { width: 2%; } +.width-3 { width: 3%; } +.width-4 { width: 4%; } +.width-5 { width: 5%; } +.width-6 { width: 6%; } +.width-7 { width: 7%; } +.width-8 { width: 8%; } +.width-9 { width: 9%; } +.width-10 { width: 10%; } +.width-11 { width: 11%; } +.width-12 { width: 12%; } +.width-13 { width: 13%; } +.width-14 { width: 14%; } +.width-15 { width: 15%; } +.width-16 { width: 16%; } +.width-17 { width: 17%; } +.width-18 { width: 18%; } +.width-19 { width: 19%; } +.width-20 { width: 20%; } +.width-21 { width: 21%; } +.width-22 { width: 22%; } +.width-23 { width: 23%; } +.width-24 { width: 24%; } +.width-25 { width: 25%; } +.width-26 { width: 26%; } +.width-27 { width: 27%; } +.width-28 { width: 28%; } +.width-29 { width: 29%; } +.width-30 { width: 30%; } +.width-31 { width: 31%; } +.width-32 { width: 32%; } +.width-33 { width: 33%; } +.width-34 { width: 34%; } +.width-35 { width: 35%; } +.width-36 { width: 36%; } +.width-37 { width: 37%; } +.width-38 { width: 38%; } +.width-39 { width: 39%; } +.width-40 { width: 40%; } +.width-41 { width: 41%; } +.width-42 { width: 42%; } +.width-43 { width: 43%; } +.width-44 { width: 44%; } +.width-45 { width: 45%; } +.width-46 { width: 46%; } +.width-47 { width: 47%; } +.width-48 { width: 48%; } +.width-49 { width: 49%; } +.width-50 { width: 50%; } +.width-51 { width: 51%; } +.width-52 { width: 52%; } +.width-53 { width: 53%; } +.width-54 { width: 54%; } +.width-55 { width: 55%; } +.width-56 { width: 56%; } +.width-57 { width: 57%; } +.width-58 { width: 58%; } +.width-59 { width: 59%; } +.width-60 { width: 60%; } +.width-61 { width: 61%; } +.width-62 { width: 62%; } +.width-63 { width: 63%; } +.width-64 { width: 64%; } +.width-65 { width: 65%; } +.width-66 { width: 66%; } +.width-67 { width: 67%; } +.width-68 { width: 68%; } +.width-69 { width: 69%; } +.width-70 { width: 70%; } +.width-71 { width: 71%; } +.width-72 { width: 72%; } +.width-73 { width: 73%; } +.width-74 { width: 74%; } +.width-75 { width: 75%; } +.width-76 { width: 76%; } +.width-77 { width: 77%; } +.width-78 { width: 78%; } +.width-79 { width: 79%; } +.width-80 { width: 80%; } +.width-81 { width: 81%; } +.width-82 { width: 82%; } +.width-83 { width: 83%; } +.width-84 { width: 84%; } +.width-85 { width: 85%; } +.width-86 { width: 86%; } +.width-87 { width: 87%; } +.width-88 { width: 88%; } +.width-89 { width: 89%; } +.width-90 { width: 90%; } +.width-91 { width: 91%; } +.width-92 { width: 92%; } +.width-93 { width: 93%; } +.width-94 { width: 94%; } +.width-95 { width: 95%; } +.width-96 { width: 96%; } +.width-97 { width: 97%; } +.width-98 { width: 98%; } +.width-99 { width: 99%; } +.width-100 { width: 100%; } diff --git a/themes/default/public/js/filesize.min.js b/themes/default/public/js/filesize.min.js index 6338a47..397c24b 100644 --- a/themes/default/public/js/filesize.min.js +++ b/themes/default/public/js/filesize.min.js @@ -1,6 +1,6 @@ /* - * 2015 Jason Mulligan - * @version 3.1.2 - * */ -"use strict";!function(a){var b=/b$/,c={bits:["B","kb","Mb","Gb","Tb","Pb","Eb","Zb","Yb"],bytes:["B","kB","MB","GB","TB","PB","EB","ZB","YB"]},d=function(a){var d=void 0===arguments[1]?{}:arguments[1],e=[],f=!1,g=0,h=void 0,i=void 0,j=void 0,k=void 0,l=void 0,m=void 0,n=void 0,o=void 0,p=void 0,q=void 0,r=void 0;if(isNaN(a))throw new Error("Invalid arguments");return j=d.bits===!0,p=d.unix===!0,i=void 0!==d.base?d.base:2,o=void 0!==d.round?d.round:p?1:2,q=void 0!==d.spacer?d.spacer:p?"":" ",r=void 0!==d.suffixes?d.suffixes:{},n=void 0!==d.output?d.output:"string",h=void 0!==d.exponent?d.exponent:-1,m=Number(a),l=0>m,k=i>2?1e3:1024,l&&(m=-m),0===m?(e[0]=0,e[1]=p?"":"B"):((-1===h||isNaN(h))&&(h=Math.floor(Math.log(m)/Math.log(k))),h>8&&(g=1e3*g*(h-8),h=8),g=2===i?m/Math.pow(2,10*h):m/Math.pow(1e3,h),j&&(g=8*g,g>k&&(g/=k,h++)),e[0]=Number(g.toFixed(h>0?o:0)),e[1]=c[j?"bits":"bytes"][h],!f&&p&&(j&&b.test(e[1])&&(e[1]=e[1].toLowerCase()),e[1]=e[1].charAt(0),"B"===e[1]?(e[0]=Math.floor(e[0]),e[1]=""):j||"k"!==e[1]||(e[1]="K"))),l&&(e[0]=-e[0]),e[1]=r[e[1]]||e[1],"array"===n?e:"exponent"===n?h:"object"===n?{value:e[0],suffix:e[1]}:e.join(q)};"undefined"!=typeof exports?module.exports=d:"function"==typeof define?define(function(){return d}):a.filesize=d}("undefined"!=typeof global?global:window); -//# sourceMappingURL=filesize.min.js.map + 2018 Jason Mulligan + @version 3.6.1 +*/ +"use strict";!function(e){var i=/^(b|B)$/,t={iec:{bits:["b","Kib","Mib","Gib","Tib","Pib","Eib","Zib","Yib"],bytes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},jedec:{bits:["b","Kb","Mb","Gb","Tb","Pb","Eb","Zb","Yb"],bytes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]}},o={iec:["","kibi","mebi","gibi","tebi","pebi","exbi","zebi","yobi"],jedec:["","kilo","mega","giga","tera","peta","exa","zetta","yotta"]};function b(e){var b,n,r,a,s,f,d,u,l,B,c,p,y,g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},m=[],v=0,x=void 0,h=void 0;if(isNaN(e))throw new Error("Invalid arguments");return n=!0===g.bits,l=!0===g.unix,b=g.base||2,u=void 0!==g.round?g.round:l?1:2,B=void 0!==g.separator&&g.separator||"",c=void 0!==g.spacer?g.spacer:l?"":" ",y=g.symbols||g.suffixes||{},p=2===b&&g.standard||"jedec",d=g.output||"string",a=!0===g.fullform,s=g.fullforms instanceof Array?g.fullforms:[],x=void 0!==g.exponent?g.exponent:-1,f=(h=Number(e))<0,r=b>2?1e3:1024,f&&(h=-h),(-1===x||isNaN(x))&&(x=Math.floor(Math.log(h)/Math.log(r)))<0&&(x=0),x>8&&(x=8),0===h?(m[0]=0,m[1]=l?"":t[p][n?"bits":"bytes"][x]):(v=h/(2===b?Math.pow(2,10*x):Math.pow(1e3,x)),n&&(v*=8)>=r&&x<8&&(v/=r,x++),m[0]=Number(v.toFixed(x>0?u:0)),m[1]=10===b&&1===x?n?"kb":"kB":t[p][n?"bits":"bytes"][x],l&&(m[1]="jedec"===p?m[1].charAt(0):x>0?m[1].replace(/B$/,""):m[1],i.test(m[1])&&(m[0]=Math.floor(m[0]),m[1]=""))),f&&(m[0]=-m[0]),m[1]=y[m[1]]||m[1],"array"===d?m:"exponent"===d?x:"object"===d?{value:m[0],suffix:m[1],symbol:m[1]}:(a&&(m[1]=s[x]?s[x]:o[p][x]+(n?"bit":"byte")+(1===m[0]?"":"s")),B.length>0&&(m[0]=m[0].toString().replace(".",B)),m.join(c))}b.partial=function(e){return function(i){return b(i,e)}},"undefined"!=typeof exports?module.exports=b:"function"==typeof define&&define.amd?define(function(){return b}):e.filesize=b}("undefined"!=typeof window?window:global); +//# sourceMappingURL=filesize.min.js.map \ No newline at end of file diff --git a/themes/default/public/js/filesize.min.js.map b/themes/default/public/js/filesize.min.js.map new file mode 100644 index 0000000..da026c7 --- /dev/null +++ b/themes/default/public/js/filesize.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["filesize.js"],"names":["global","b","symbol","iec","bits","bytes","jedec","fullform","filesize","arg","base","ceil","full","fullforms","neg","output","round","unix","separator","spacer","standard","symbols","descriptor","arguments","length","undefined","result","val","e","num","isNaN","Error","suffixes","Array","exponent","Number","Math","floor","log","pow","toFixed","charAt","replace","test","value","suffix","toString","join","partial","opt","exports","module","define","amd","window"],"mappings":";;;;AAAA,cASA,SAAWA,GACV,IAAIC,EAAI,UACJC,GACHC,KACCC,MAAO,IAAK,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,OAC7DC,OAAQ,IAAK,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,QAE/DC,OACCF,MAAO,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MACtDC,OAAQ,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,QAGrDE,GACHJ,KAAM,GAAI,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,QAClEG,OAAQ,GAAI,OAAQ,OAAQ,OAAQ,OAAQ,OAAQ,MAAO,QAAS,UAWrE,SAASE,EAASC,GACjB,IAKIC,EACAN,EACAO,EACAC,EACAC,EACAC,EAEAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAlBAC,EAAaC,UAAUC,OAAS,QAAsBC,IAAjBF,UAAU,GAAmBA,UAAU,MAE5EG,KACAC,EAAM,EACNC,OAAI,EAOJC,OAAM,EASV,GAAIC,MAAMrB,GACT,MAAM,IAAIsB,MAAM,qBA4EjB,OAzEA3B,GAA2B,IAApBkB,EAAWlB,KAClBa,GAA2B,IAApBK,EAAWL,KAClBP,EAAOY,EAAWZ,MAAQ,EAC1BM,OAA6B,IAArBM,EAAWN,MAAmBM,EAAWN,MAAQC,EAAO,EAAI,EACpEC,OAAqC,IAAzBI,EAAWJ,WAAuBI,EAAWJ,WAAkB,GAC3EC,OAA+B,IAAtBG,EAAWH,OAAoBG,EAAWH,OAASF,EAAO,GAAK,IACxEI,EAAUC,EAAWD,SAAWC,EAAWU,aAC3CZ,EAAoB,IAATV,GAAaY,EAAWF,UAAsB,QACzDL,EAASO,EAAWP,QAAU,SAC9BH,GAA+B,IAAxBU,EAAWf,SAClBM,EAAYS,EAAWT,qBAAqBoB,MAAQX,EAAWT,aAC/De,OAA4B,IAAxBN,EAAWY,SAAsBZ,EAAWY,UAAY,EAE5DpB,GADAe,EAAMM,OAAO1B,IACD,EACZE,EAAOD,EAAO,EAAI,IAAO,KAGrBI,IACHe,GAAOA,KAIG,IAAPD,GAAYE,MAAMF,MACrBA,EAAIQ,KAAKC,MAAMD,KAAKE,IAAIT,GAAOO,KAAKE,IAAI3B,KAEhC,IACPiB,EAAI,GAKFA,EAAI,IACPA,EAAI,GAIO,IAARC,GACHH,EAAO,GAAK,EACZA,EAAO,GAAKT,EAAO,GAAKf,EAAOkB,GAAUhB,EAAO,OAAS,SAASwB,KAElED,EAAME,GAAgB,IAATnB,EAAa0B,KAAKG,IAAI,EAAO,GAAJX,GAAUQ,KAAKG,IAAI,IAAMX,IAE3DxB,IACHuB,GAAY,IAEDhB,GAAQiB,EAAI,IACtBD,GAAYhB,EACZiB,KAIFF,EAAO,GAAKS,OAAOR,EAAIa,QAAQZ,EAAI,EAAIZ,EAAQ,IAC/CU,EAAO,GAAc,KAAThB,GAAqB,IAANkB,EAAUxB,EAAO,KAAO,KAAOF,EAAOkB,GAAUhB,EAAO,OAAS,SAASwB,GAEhGX,IACHS,EAAO,GAAkB,UAAbN,EAAuBM,EAAO,GAAGe,OAAO,GAAKb,EAAI,EAAIF,EAAO,GAAGgB,QAAQ,KAAM,IAAMhB,EAAO,GAElGzB,EAAE0C,KAAKjB,EAAO,MACjBA,EAAO,GAAKU,KAAKC,MAAMX,EAAO,IAC9BA,EAAO,GAAK,MAMXZ,IACHY,EAAO,IAAMA,EAAO,IAIrBA,EAAO,GAAKL,EAAQK,EAAO,KAAOA,EAAO,GAG1B,UAAXX,EACIW,EAGO,aAAXX,EACIa,EAGO,WAAXb,GACM6B,MAAOlB,EAAO,GAAImB,OAAQnB,EAAO,GAAIxB,OAAQwB,EAAO,KAG1Dd,IACHc,EAAO,GAAKb,EAAUe,GAAKf,EAAUe,GAAKrB,EAASa,GAAUQ,IAAMxB,EAAO,MAAQ,SAAyB,IAAdsB,EAAO,GAAW,GAAK,MAGjHR,EAAUM,OAAS,IACtBE,EAAO,GAAKA,EAAO,GAAGoB,WAAWJ,QAAQ,IAAKxB,IAGxCQ,EAAOqB,KAAK5B,IAIpBX,EAASwC,QAAU,SAAUC,GAC5B,OAAO,SAAUxC,GAChB,OAAOD,EAASC,EAAKwC,KAKA,oBAAZC,QACVC,OAAOD,QAAU1C,EACW,mBAAX4C,QAAyBA,OAAOC,IACjDD,OAAO,WACN,OAAO5C,IAGRR,EAAOQ,SAAWA,EAjKpB,CAmKqB,oBAAX8C,OAAyBA,OAAStD","file":"filesize.min.js"} \ No newline at end of file diff --git a/themes/default/public/js/lufi-down.js b/themes/default/public/js/lufi-down.js index 671c302..dfe0b44 100644 --- a/themes/default/public/js/lufi-down.js +++ b/themes/default/public/js/lufi-down.js @@ -173,8 +173,12 @@ $(document).ready(function(){ window.ws.onclose = function() {}; window.ws.close(); $('#please-wait, #loading, #pbd, #abort').remove(); - $('#filesize').parent().append('

'+i18n.aborted1+'

'+i18n.aborted2+'

'); + $('#filesize').parent().append('

'+i18n.aborted1+'

'+i18n.aborted2+'

'); window.onbeforeunload = null; + $('#reloadLocation').on('click', function(e) { + e.preventDefault(); + window.location.reload(); + }) }); $('#filesize').html(filesize($('#filesize').attr('data-filesize'), {base: 10})); window.a = new Array(); diff --git a/themes/default/public/js/lufi-files.js b/themes/default/public/js/lufi-files.js index 7bcfff0..a234e60 100644 --- a/themes/default/public/js/lufi-files.js +++ b/themes/default/public/js/lufi-files.js @@ -43,7 +43,8 @@ function itemExists(name) { } } -function purgeExpired() { +function purgeExpired(event) { + event.preventDefault(); var files = JSON.parse(localStorage.getItem('files')); files.forEach(function(element, index, array) { @@ -67,7 +68,8 @@ function purgeExpired() { }); } -function exportStorage() { +function exportStorage(event) { + event.preventDefault(); var a = $(''); a.hide(); $('body').append(a); @@ -122,6 +124,7 @@ function delFile() { } else { alert(data.msg); } + evaluateMassDelete(); }, error: function() { }, @@ -140,7 +143,8 @@ function evaluateMassDelete() { } } -function massDelete() { +function massDelete(event) { + event.preventDefault(); $('input[data-checked="data-checked"]').each(delFile); } @@ -227,3 +231,8 @@ function populateFilesTable() { }); }); } + +function clickImport(event) { + event.preventDefault(); + $('#import').click(); +} diff --git a/themes/default/public/js/lufi-up.js b/themes/default/public/js/lufi-up.js index e60787c..d78b41f 100644 --- a/themes/default/public/js/lufi-up.js +++ b/themes/default/public/js/lufi-up.js @@ -30,7 +30,8 @@ function copyToClipboard(txt) { } // Copy all links to clipboard -function copyAllToClipboard() { +function copyAllToClipboard(event) { + event.preventDefault(); var text = new Array(); var a = $('.link-input'); var i; @@ -49,9 +50,8 @@ function copyAllToClipboard() { var msg = successful ? i18n.copySuccess : i18n.copyFail; Materialize.toast(msg, 4000); } catch (err) { - textArea.css('width', ''); - textArea.css('height', ''); - textArea.css('background', '#FFFFFF'); + textArea.removeClass('textarea-hidden'); + textArea.addClass('white-background'); alert(i18n.hits); } @@ -149,7 +149,7 @@ function uploadFile(i, delay, del_at_first_view) { w.addClass('list-group-item'); w.html(['
', '
', - '', + '', '', '', '
', @@ -157,12 +157,16 @@ function uploadFile(i, delay, del_at_first_view) { '

', '
', '
', - '
', + '
', '', name, '0%', '
', '
', '
'].join('')); r.append(w); + $('#destroy-'+window.fc).on('click', function(event) { + event.preventDefault(); + destroyBlock(this) + }); sliceAndUpload(randomkey, i, parts, 0, delay, del_at_first_view, null); } @@ -280,18 +284,18 @@ function updateProgressBar(data) { '', '', '', - '', + '', '', '', '', - '', + '', '', '
', '
', '', '', '', - '', + '', '', '
', '
'].join('')); @@ -303,13 +307,18 @@ function updateProgressBar(data) { p2.remove(); p1.append(d); + $('#copyurl-'+window.fc).on('click', function(e) { + e.preventDefault(); + copyToClipboard(url); + }); $("input[type='text']").on("click", function () { $(this).select(); }); // Add copy all and mailto buttons var misc = $('#misc'); if (misc.html() === '') { - misc.html(''+i18n.copyAll+' '+i18n.mailTo+''); + misc.html(''+i18n.copyAll+' '+i18n.mailTo+''); + $('#copyall').on('click', copyAllToClipboard); } else { updateMailLink(); } @@ -333,7 +342,9 @@ function updateProgressBar(data) { j++; // Update progress bar var percent = Math.round(100 * j/parts); - dp.css('width', percent+'%'); + dp.removeClass(); + dp.addClass('determinate'); + dp.addClass('width-'+percent); dp.attr('aria-valuenow', percent); // Encrypt and upload next slice diff --git a/themes/default/templates/files.html.ep b/themes/default/templates/files.html.ep index 551b80c..342a27c 100644 --- a/themes/default/templates/files.html.ep +++ b/themes/default/templates/files.html.ep @@ -9,13 +9,13 @@ <%= l('Rows in red mean that the files have expired and are no longer available.') %>

diff --git a/themes/default/templates/layouts/default.html.ep b/themes/default/templates/layouts/default.html.ep index 2addc67..e293b75 100644 --- a/themes/default/templates/layouts/default.html.ep +++ b/themes/default/templates/layouts/default.html.ep @@ -24,7 +24,7 @@
', '
'].join('')); - r.append(w); + r.prepend(w); $('#destroy-'+window.fc).on('click', function(event) { event.preventDefault(); destroyBlock(this) @@ -425,12 +425,34 @@ function spawnWebsocket(i, callback) { return ws; } -// When it's ready -$(document).ready(function(){ - // Dropzone events binding +// Dropzone events binding +function bindDropZone() { var dropZone = document.getElementById('files'); dropZone.addEventListener('dragover', handleDragOver, false); dropZone.addEventListener('drop', handleDrop, false); + $('#file-browser-span').removeClass('disabled'); + $('#file-browser-span').addClass('cyan'); + $('#file-browser-button').attr('disabled', null); + $('#file-browser-button').on('change', function(e) { + handleFiles(this.files); + }); +} + +// When it's ready +$(document).ready(function(){ + if (!sjcl.random.isReady(10)) { + var loop = setInterval(function() { + if (!sjcl.random.isReady(10)) { + $('#not-enough-entropy').removeClass('hiddendiv'); + } else { + $('#not-enough-entropy').addClass('hiddendiv'); + bindDropZone(); + clearInterval(loop); + } + }, 1000); + } else { + bindDropZone(); + } $('label[for="first-view"]').on('click', function(){ if ($('#first-view').attr('data-checked') && $('#first-view').attr('data-checked') === 'data-checked') { $('#first-view').attr('data-checked', null); diff --git a/themes/default/public/js/sjcl.js b/themes/default/public/js/sjcl.js index e22ab03..c3c3ea9 100644 --- a/themes/default/public/js/sjcl.js +++ b/themes/default/public/js/sjcl.js @@ -1,58 +1,60 @@ -"use strict";function q(a){throw a;}var s=void 0,u=!1;var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}}; -"undefined"!==typeof module&&module.exports&&(module.exports=sjcl);"function"===typeof define&&define([],function(){return sjcl}); -sjcl.cipher.aes=function(a){this.l[0][0][0]||this.G();var b,c,d,e,g=this.l[0][4],f=this.l[1];b=a.length;var h=1;4!==b&&(6!==b&&8!==b)&&q(new sjcl.exception.invalid("invalid aes key size"));this.b=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(0===a%b||8===b&&4===a%b)c=g[c>>>24]<<24^g[c>>16&255]<<16^g[c>>8&255]<<8^g[c&255],0===a%b&&(c=c<<8^c>>>24^h<<24,h=h<<1^283*(h>>7));d[a]=d[a-b]^c}for(b=0;a;b++,a--)c=d[b&3?a:a-4],e[b]=4>=a||4>b?c:f[0][g[c>>>24]]^f[1][g[c>>16&255]]^f[2][g[c>>8&255]]^f[3][g[c& +"use strict";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}}; +sjcl.cipher.aes=function(a){this.s[0][0][0]||this.O();var b,c,d,e,f=this.s[0][4],g=this.s[1];b=a.length;var h=1;if(4!==b&&6!==b&&8!==b)throw new sjcl.exception.invalid("invalid aes key size");this.b=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(0===a%b||8===b&&4===a%b)c=f[c>>>24]<<24^f[c>>16&255]<<16^f[c>>8&255]<<8^f[c&255],0===a%b&&(c=c<<8^c>>>24^h<<24,h=h<<1^283*(h>>7));d[a]=d[a-b]^c}for(b=0;a;b++,a--)c=d[b&3?a:a-4],e[b]=4>=a||4>b?c:g[0][f[c>>>24]]^g[1][f[c>>16&255]]^g[2][f[c>>8&255]]^g[3][f[c& 255]]}; -sjcl.cipher.aes.prototype={encrypt:function(a){return w(this,a,0)},decrypt:function(a){return w(this,a,1)},l:[[[],[],[],[],[]],[[],[],[],[],[]]],G:function(){var a=this.l[0],b=this.l[1],c=a[4],d=b[4],e,g,f,h=[],l=[],k,m,n,p;for(e=0;0x100>e;e++)l[(h[e]=e<<1^283*(e>>7))^e]=e;for(g=f=0;!c[g];g^=k||1,f=l[f]||1){n=f^f<<1^f<<2^f<<3^f<<4;n=n>>8^n&255^99;c[g]=n;d[n]=g;m=h[e=h[k=h[g]]];p=0x1010101*m^0x10001*e^0x101*k^0x1010100*g;m=0x101*h[n]^0x1010100*n;for(e=0;4>e;e++)a[e][g]=m=m<<24^m>>>8,b[e][n]=p=p<<24^p>>>8}for(e= +sjcl.cipher.aes.prototype={encrypt:function(a){return t(this,a,0)},decrypt:function(a){return t(this,a,1)},s:[[[],[],[],[],[]],[[],[],[],[],[]]],O:function(){var a=this.s[0],b=this.s[1],c=a[4],d=b[4],e,f,g,h=[],k=[],l,n,m,p;for(e=0;0x100>e;e++)k[(h[e]=e<<1^283*(e>>7))^e]=e;for(f=g=0;!c[f];f^=l||1,g=k[g]||1)for(m=g^g<<1^g<<2^g<<3^g<<4,m=m>>8^m&255^99,c[f]=m,d[m]=f,n=h[e=h[l=h[f]]],p=0x1010101*n^0x10001*e^0x101*l^0x1010100*f,n=0x101*h[m]^0x1010100*m,e=0;4>e;e++)a[e][f]=n=n<<24^n>>>8,b[e][m]=p=p<<24^p>>>8;for(e= 0;5>e;e++)a[e]=a[e].slice(0),b[e]=b[e].slice(0)}}; -function w(a,b,c){4!==b.length&&q(new sjcl.exception.invalid("invalid aes block size"));var d=a.b[c],e=b[0]^d[0],g=b[c?3:1]^d[1],f=b[2]^d[2];b=b[c?1:3]^d[3];var h,l,k,m=d.length/4-2,n,p=4,t=[0,0,0,0];h=a.l[c];a=h[0];var r=h[1],v=h[2],y=h[3],z=h[4];for(n=0;n>>24]^r[g>>16&255]^v[f>>8&255]^y[b&255]^d[p],l=a[g>>>24]^r[f>>16&255]^v[b>>8&255]^y[e&255]^d[p+1],k=a[f>>>24]^r[b>>16&255]^v[e>>8&255]^y[g&255]^d[p+2],b=a[b>>>24]^r[e>>16&255]^v[g>>8&255]^y[f&255]^d[p+3],p+=4,e=h,g=l,f=k;for(n=0;4> -n;n++)t[c?3&-n:n]=z[e>>>24]<<24^z[g>>16&255]<<16^z[f>>8&255]<<8^z[b&255]^d[p++],h=e,e=g,g=f,f=b,b=h;return t} -sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.R(a.slice(b/32),32-(b&31)).slice(1);return c===s?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+0x10000000000*a},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return u;var c=0,d;for(d=0;d>>b),c=a[e]<<32-b;e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,32>>24|c>>>8&0xff00|(c&0xff00)<<8|c<<24;return a}}; -sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d>>24),e<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c>>f)>>>e),fm){if(!b)try{return sjcl.codec.base32hex.toBits(a)}catch(p){}q(new sjcl.exception.invalid("this isn't "+n+"!"))}h>e?(h-=e,g.push(k^m>>>h),k=m<>>24]^q[f>>16&255]^v[g>>8&255]^w[b&255]^d[p],k=a[f>>>24]^q[g>>16&255]^v[b>>8&255]^w[e&255]^d[p+1],l=a[g>>>24]^q[b>>16&255]^v[e>>8&255]^w[f&255]^d[p+2],b=a[b>>>24]^q[e>>16&255]^v[f>>8&255]^w[g&255]^d[p+3],p+=4,e=h,f=k,g=l;for(m= +0;4>m;m++)r[c?3&-m:m]=x[e>>>24]<<24^x[f>>16&255]<<16^x[g>>8&255]<<8^x[b&255]^d[p++],h=e,e=f,f=g,g=b,b=h;return r} +sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.$(a.slice(b/32),32-(b&31)).slice(1);return void 0===c?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+0x10000000000*a},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return!1;var c=0,d;for(d=0;d>>b),c=a[e]<<32-b;e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,32>>24|c>>>8&0xff00|(c&0xff00)<<8|c<<24;return a}}; +sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d>>8>>>8>>>8),e<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c>>g)>>>e),gn){if(!b)try{return sjcl.codec.base32hex.toBits(a)}catch(p){}throw new sjcl.exception.invalid("this isn't "+m+"!");}h>e?(h-=e,f.push(l^n>>>h),l=n<>>e)>>>26),6>e?(f=a[c]<<6-e,e+=26,c++):(f<<=6,e-=6);for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d,e=0,g=sjcl.codec.base64.p,f=0,h;b&&(g=g.substr(0,62)+"-_");for(d=0;dh&&q(new sjcl.exception.invalid("this isn't base64!")),26>>e),f=h<<32-e):(e+=6,f^=h<<32-e);e&56&&c.push(sjcl.bitArray.partial(e&56,f,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.b[0]||this.G();a?(this.s=a.s.slice(0),this.o=a.o.slice(0),this.i=a.i):this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()}; -sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.s=this.P.slice(0);this.o=[];this.i=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.o=sjcl.bitArray.concat(this.o,a);b=this.i;a=this.i=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)x(this,c.splice(0,16));return this},finalize:function(){var a,b=this.o,c=this.s,b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.i/ -4294967296));for(b.push(this.i|0);b.length;)x(this,b.splice(0,16));this.reset();return c},P:[],b:[],G:function(){function a(a){return 0x100000000*(a-Math.floor(a))|0}var b=0,c=2,d;a:for(;64>b;c++){for(d=2;d*d<=c;d++)if(0===c%d)continue a;8>b&&(this.P[b]=a(Math.pow(c,0.5)));this.b[b]=a(Math.pow(c,1/3));b++}}}; -function x(a,b){var c,d,e,g=b.slice(0),f=a.s,h=a.b,l=f[0],k=f[1],m=f[2],n=f[3],p=f[4],t=f[5],r=f[6],v=f[7];for(c=0;64>c;c++)16>c?d=g[c]:(d=g[c+1&15],e=g[c+14&15],d=g[c&15]=(d>>>7^d>>>18^d>>>3^d<<25^d<<14)+(e>>>17^e>>>19^e>>>10^e<<15^e<<13)+g[c&15]+g[c+9&15]|0),d=d+v+(p>>>6^p>>>11^p>>>25^p<<26^p<<21^p<<7)+(r^p&(t^r))+h[c],v=r,r=t,t=p,p=n+d|0,n=m,m=k,k=l,l=d+(k&m^n&(k^m))+(k>>>2^k>>>13^k>>>22^k<<30^k<<19^k<<10)|0;f[0]=f[0]+l|0;f[1]=f[1]+k|0;f[2]=f[2]+m|0;f[3]=f[3]+n|0;f[4]=f[4]+p|0;f[5]=f[5]+t|0;f[6]= -f[6]+r|0;f[7]=f[7]+v|0} -sjcl.mode.ccm={name:"ccm",t:[],listenProgress:function(a){sjcl.mode.ccm.t.push(a)},unListenProgress:function(a){a=sjcl.mode.ccm.t.indexOf(a);-1l&&q(new sjcl.exception.invalid("ccm: iv must be at least 7 bytes"));for(g=2;4>g&&k>>>8*g;g++);g<15-l&&(g=15-l);c=h.clamp(c,8*(15- -g));b=sjcl.mode.ccm.M(a,b,c,d,e,g);f=sjcl.mode.ccm.q(a,f,c,b,e,g);return h.concat(f.data,f.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var g=sjcl.bitArray,f=g.bitLength(c)/8,h=g.bitLength(b),l=g.clamp(b,h-e),k=g.bitSlice(b,h-e),h=(h-e)/8;7>f&&q(new sjcl.exception.invalid("ccm: iv must be at least 7 bytes"));for(b=2;4>b&&h>>>8*b;b++);b<15-f&&(b=15-f);c=g.clamp(c,8*(15-b));l=sjcl.mode.ccm.q(a,l,c,k,e,b);a=sjcl.mode.ccm.M(a,l.data,c,d,e,b);g.equal(l.tag,a)||q(new sjcl.exception.corrupt("ccm: tag doesn't match")); -return l.data},ea:function(a,b,c,d,e,g){var f=[],h=sjcl.bitArray,l=h.g;d=[h.partial(8,(b.length?64:0)|d-2<<2|g-1)];d=h.concat(d,c);d[3]|=e;d=a.encrypt(d);if(b.length){c=h.bitLength(b)/8;65279>=c?f=[h.partial(16,c)]:0xffffffff>=c&&(f=h.concat([h.partial(16,65534)],[c]));f=h.concat(f,b);for(b=0;be||16m&&(sjcl.mode.ccm.X(f/ -l),m+=n),c[3]++,e=a.encrypt(c),b[f]^=e[0],b[f+1]^=e[1],b[f+2]^=e[2],b[f+3]^=e[3];return{tag:d,data:h.clamp(b,k)}}}; -sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,g){128!==sjcl.bitArray.bitLength(c)&&q(new sjcl.exception.invalid("ocb iv must be 128 bits"));var f,h=sjcl.mode.ocb2.J,l=sjcl.bitArray,k=l.g,m=[0,0,0,0];c=h(a.encrypt(c));var n,p=[];d=d||[];e=e||64;for(f=0;f+4e.bitLength(c)&&(h=g(h,d(h)),c=e.concat(c,[-2147483648,0,0,0]));f=g(f,c);return a.encrypt(g(d(g(h, -d(h))),f))},J:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^135*(a[0]>>>31)]}}; -sjcl.mode.gcm={name:"gcm",encrypt:function(a,b,c,d,e){var g=b.slice(0);b=sjcl.bitArray;d=d||[];a=sjcl.mode.gcm.q(!0,a,g,d,c,e||128);return b.concat(a.data,a.tag)},decrypt:function(a,b,c,d,e){var g=b.slice(0),f=sjcl.bitArray,h=f.bitLength(g);e=e||128;d=d||[];e<=h?(b=f.bitSlice(g,h-e),g=f.bitSlice(g,0,h-e)):(b=g,g=[]);a=sjcl.mode.gcm.q(u,a,g,d,c,e);f.equal(a.tag,b)||q(new sjcl.exception.corrupt("gcm: tag doesn't match"));return a.data},ba:function(a,b){var c,d,e,g,f,h=sjcl.bitArray.g;e=[0,0,0,0];g= -b.slice(0);for(c=0;128>c;c++){(d=0!==(a[Math.floor(c/32)]&1<<31-c%32))&&(e=h(e,g));f=0!==(g[3]&1);for(d=3;0>>1|(g[d-1]&1)<<31;g[0]>>>=1;f&&(g[0]^=-0x1f000000)}return e},h:function(a,b,c){var d,e=c.length;b=b.slice(0);for(d=0;de&&(a=b.hash(a));for(d=0;dd||0>c)&&q(sjcl.exception.invalid("invalid params to pbkdf2"));"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));e=e||sjcl.misc.hmac;a=new e(a);var g,f,h,l,k=[],m=sjcl.bitArray;for(l=1;32*k.length<(d||1);l++){e=g=a.encrypt(m.concat(b,[l]));for(f=1;ff;f++)e.push(0x100000000*Math.random()|0);for(f=0;f=1<this.k&&(this.k=g);this.H++; -this.b=sjcl.hash.sha256.hash(this.b.concat(e));this.C=new sjcl.cipher.aes(this.b);for(d=0;4>d&&!(this.f[d]=this.f[d]+1|0,this.f[d]);d++);}for(d=0;d>>=1;this.c[f].update([d,this.F++,2,b,g,a.length].concat(a))}break;case "string":b===s&&(b=a.length);this.c[f].update([d,this.F++,3,b,g,a.length]);this.c[f].update(a);break;default:l=1}l&&q(new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string"));this.j[f]+=b;this.d+=b;h===this.m&&(this.isReady()!==this.m&&C("seeded",Math.max(this.k,this.d)),C("progress",this.getProgress()))},isReady:function(a){a=this.K[a!==s?a:this.D];return this.k&&this.k>=a?this.j[0]>this.T&& -(new Date).valueOf()>this.Q?this.A|this.w:this.w:this.d>=a?this.A|this.m:this.m},getProgress:function(a){a=this.K[a?a:this.D];return this.k>=a?1:this.d>a?1:this.d/a},startCollectors:function(){this.r||(this.a={loadTimeCollector:D(this,this.da),mouseCollector:D(this,this.fa),keyboardCollector:D(this,this.ca),accelerometerCollector:D(this,this.W),touchCollector:D(this,this.ha)},window.addEventListener?(window.addEventListener("load",this.a.loadTimeCollector,u),window.addEventListener("mousemove",this.a.mouseCollector, -u),window.addEventListener("keypress",this.a.keyboardCollector,u),window.addEventListener("devicemotion",this.a.accelerometerCollector,u),window.addEventListener("touchmove",this.a.touchCollector,u)):document.attachEvent?(document.attachEvent("onload",this.a.loadTimeCollector),document.attachEvent("onmousemove",this.a.mouseCollector),document.attachEvent("keypress",this.a.keyboardCollector)):q(new sjcl.exception.bug("can't attach event")),this.r=!0)},stopCollectors:function(){this.r&&(window.removeEventListener? -(window.removeEventListener("load",this.a.loadTimeCollector,u),window.removeEventListener("mousemove",this.a.mouseCollector,u),window.removeEventListener("keypress",this.a.keyboardCollector,u),window.removeEventListener("devicemotion",this.a.accelerometerCollector,u),window.removeEventListener("touchmove",this.a.touchCollector,u)):document.detachEvent&&(document.detachEvent("onload",this.a.loadTimeCollector),document.detachEvent("onmousemove",this.a.mouseCollector),document.detachEvent("keypress", -this.a.keyboardCollector)),this.r=u)},addEventListener:function(a,b){this.B[a][this.Y++]=b},removeEventListener:function(a,b){var c,d,e=this.B[a],g=[];for(d in e)e.hasOwnProperty(d)&&e[d]===b&&g.push(d);for(c=0;cb&&!(a.f[b]=a.f[b]+1|0,a.f[b]);b++);return a.C.encrypt(a.f)}function D(a,b){return function(){b.apply(a,arguments)}}sjcl.random=new sjcl.prng(6); -a:try{var F,G,H,I;if(I="undefined"!==typeof module){var J;if(J=module.exports){var K;try{K=require("crypto")}catch(L){K=null}J=(G=K)&&G.randomBytes}I=J}if(I)F=G.randomBytes(128),F=new Uint32Array((new Uint8Array(F)).buffer),sjcl.random.addEntropy(F,1024,"crypto['randomBytes']");else if("undefined"!==typeof window&&"undefined"!==typeof Uint32Array){H=new Uint32Array(32);if(window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(H);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(H); -else break a;sjcl.random.addEntropy(H,1024,"crypto['getRandomValues']")}}catch(M){"undefined"!==typeof window&&window.console&&(console.log("There was an error collecting entropy from the browser:"),console.log(M))} -sjcl.json={defaults:{v:1,iter:1E3,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},aa:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,g=e.e({iv:sjcl.random.randomWords(4,0)},e.defaults),f;e.e(g,c);c=g.adata;"string"===typeof g.salt&&(g.salt=sjcl.codec.base64.toBits(g.salt));"string"===typeof g.iv&&(g.iv=sjcl.codec.base64.toBits(g.iv));(!sjcl.mode[g.mode]||!sjcl.cipher[g.cipher]||"string"===typeof a&&100>=g.iter||64!==g.ts&&96!==g.ts&&128!==g.ts||128!==g.ks&&192!==g.ks&&0x100!==g.ks||2>g.iv.length|| -4=b.iter||64!==b.ts&&96!==b.ts&&128!==b.ts||128!==b.ks&&192!==b.ks&&0x100!==b.ks||!b.iv||2>b.iv.length||4>>e)>>>26),6>e?(g=a[c]<<6-e,e+=26,c++):(g<<=6,e-=6);for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d,e=0,f=sjcl.codec.base64.B,g=0,h;b&&(f=f.substr(0,62)+"-_");for(d=0;dh)throw new sjcl.exception.invalid("this isn't base64!");26>>e),g=h<<32-e):(e+=6,g^=h<<32-e)}e&56&&c.push(sjcl.bitArray.partial(e&56,g,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.b[0]||this.O();a?(this.F=a.F.slice(0),this.A=a.A.slice(0),this.l=a.l):this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()}; +sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.F=this.Y.slice(0);this.A=[];this.l=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.A=sjcl.bitArray.concat(this.A,a);b=this.l;a=this.l=b+sjcl.bitArray.bitLength(a);if(0x1fffffffffffffb;c++){e=!0;for(d=2;d*d<=c;d++)if(0===c%d){e= +!1;break}e&&(8>b&&(this.Y[b]=a(Math.pow(c,.5))),this.b[b]=a(Math.pow(c,1/3)),b++)}}}; +function u(a,b){var c,d,e,f=a.F,g=a.b,h=f[0],k=f[1],l=f[2],n=f[3],m=f[4],p=f[5],r=f[6],q=f[7];for(c=0;64>c;c++)16>c?d=b[c]:(d=b[c+1&15],e=b[c+14&15],d=b[c&15]=(d>>>7^d>>>18^d>>>3^d<<25^d<<14)+(e>>>17^e>>>19^e>>>10^e<<15^e<<13)+b[c&15]+b[c+9&15]|0),d=d+q+(m>>>6^m>>>11^m>>>25^m<<26^m<<21^m<<7)+(r^m&(p^r))+g[c],q=r,r=p,p=m,m=n+d|0,n=l,l=k,k=h,h=d+(k&l^n&(k^l))+(k>>>2^k>>>13^k>>>22^k<<30^k<<19^k<<10)|0;f[0]=f[0]+h|0;f[1]=f[1]+k|0;f[2]=f[2]+l|0;f[3]=f[3]+n|0;f[4]=f[4]+m|0;f[5]=f[5]+p|0;f[6]=f[6]+r|0;f[7]= +f[7]+q|0} +sjcl.mode.ccm={name:"ccm",G:[],listenProgress:function(a){sjcl.mode.ccm.G.push(a)},unListenProgress:function(a){a=sjcl.mode.ccm.G.indexOf(a);-1k)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(f=2;4>f&&l>>>8*f;f++);f<15-k&&(f=15-k);c=h.clamp(c, +8*(15-f));b=sjcl.mode.ccm.V(a,b,c,d,e,f);g=sjcl.mode.ccm.C(a,g,c,b,e,f);return h.concat(g.data,g.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var f=sjcl.bitArray,g=f.bitLength(c)/8,h=f.bitLength(b),k=f.clamp(b,h-e),l=f.bitSlice(b,h-e),h=(h-e)/8;if(7>g)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;4>b&&h>>>8*b;b++);b<15-g&&(b=15-g);c=f.clamp(c,8*(15-b));k=sjcl.mode.ccm.C(a,k,c,l,e,b);a=sjcl.mode.ccm.V(a,k.data,c,d,e,b);if(!f.equal(k.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match"); +return k.data},na:function(a,b,c,d,e,f){var g=[],h=sjcl.bitArray,k=h.i;d=[h.partial(8,(b.length?64:0)|d-2<<2|f-1)];d=h.concat(d,c);d[3]|=e;d=a.encrypt(d);if(b.length)for(c=h.bitLength(b)/8,65279>=c?g=[h.partial(16,c)]:0xffffffff>=c&&(g=h.concat([h.partial(16,65534)],[c])),g=h.concat(g,b),b=0;be||16n&&(sjcl.mode.ccm.fa(g/ +k),n+=m),c[3]++,e=a.encrypt(c),b[g]^=e[0],b[g+1]^=e[1],b[g+2]^=e[2],b[g+3]^=e[3];return{tag:d,data:h.clamp(b,l)}}}; +sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,f){if(128!==sjcl.bitArray.bitLength(c))throw new sjcl.exception.invalid("ocb iv must be 128 bits");var g,h=sjcl.mode.ocb2.S,k=sjcl.bitArray,l=k.i,n=[0,0,0,0];c=h(a.encrypt(c));var m,p=[];d=d||[];e=e||64;for(g=0;g+4e.bitLength(c)&&(h=f(h,d(h)),c=e.concat(c,[-2147483648,0,0,0]));g=f(g,c); +return a.encrypt(f(d(f(h,d(h))),g))},S:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^135*(a[0]>>>31)]}}; +sjcl.mode.gcm={name:"gcm",encrypt:function(a,b,c,d,e){var f=b.slice(0);b=sjcl.bitArray;d=d||[];a=sjcl.mode.gcm.C(!0,a,f,d,c,e||128);return b.concat(a.data,a.tag)},decrypt:function(a,b,c,d,e){var f=b.slice(0),g=sjcl.bitArray,h=g.bitLength(f);e=e||128;d=d||[];e<=h?(b=g.bitSlice(f,h-e),f=g.bitSlice(f,0,h-e)):(b=f,f=[]);a=sjcl.mode.gcm.C(!1,a,f,d,c,e);if(!g.equal(a.tag,b))throw new sjcl.exception.corrupt("gcm: tag doesn't match");return a.data},ka:function(a,b){var c,d,e,f,g,h=sjcl.bitArray.i;e=[0,0, +0,0];f=b.slice(0);for(c=0;128>c;c++){(d=0!==(a[Math.floor(c/32)]&1<<31-c%32))&&(e=h(e,f));g=0!==(f[3]&1);for(d=3;0>>1|(f[d-1]&1)<<31;f[0]>>>=1;g&&(f[0]^=-0x1f000000)}return e},j:function(a,b,c){var d,e=c.length;b=b.slice(0);for(d=0;de&&(a=b.hash(a));for(d=0;dd||0>c)throw new sjcl.exception.invalid("invalid params to pbkdf2");"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));e=e||sjcl.misc.hmac;a=new e(a);var f,g,h,k,l=[],n=sjcl.bitArray;for(k=1;32*l.length<(d||1);k++){e=f=a.encrypt(n.concat(b,[k]));for(g=1;gg;g++)e.push(0x100000000*Math.random()|0);for(g=0;g=1<this.o&&(this.o= +f);this.P++;this.b=sjcl.hash.sha256.hash(this.b.concat(e));this.L=new sjcl.cipher.aes(this.b);for(d=0;4>d&&(this.h[d]=this.h[d]+1|0,!this.h[d]);d++);}for(d=0;d>>1;this.c[g].update([d,this.N++,2,b,f,a.length].concat(a))}break;case "string":void 0===b&&(b=a.length);this.c[g].update([d,this.N++,3,b,f,a.length]);this.c[g].update(a);break;default:k=1}if(k)throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string");this.m[g]+=b;this.f+=b;h===this.u&&(this.isReady()!==this.u&&A("seeded",Math.max(this.o,this.f)),A("progress",this.getProgress()))}, +isReady:function(a){a=this.T[void 0!==a?a:this.M];return this.o&&this.o>=a?this.m[0]>this.ba&&(new Date).valueOf()>this.Z?this.J|this.I:this.I:this.f>=a?this.J|this.u:this.u},getProgress:function(a){a=this.T[a?a:this.M];return this.o>=a?1:this.f>a?1:this.f/a},startCollectors:function(){if(!this.D){this.a={loadTimeCollector:B(this,this.ma),mouseCollector:B(this,this.oa),keyboardCollector:B(this,this.la),accelerometerCollector:B(this,this.ea),touchCollector:B(this,this.qa)};if(window.addEventListener)window.addEventListener("load", +this.a.loadTimeCollector,!1),window.addEventListener("mousemove",this.a.mouseCollector,!1),window.addEventListener("keypress",this.a.keyboardCollector,!1),window.addEventListener("devicemotion",this.a.accelerometerCollector,!1),window.addEventListener("touchmove",this.a.touchCollector,!1);else if(document.attachEvent)document.attachEvent("onload",this.a.loadTimeCollector),document.attachEvent("onmousemove",this.a.mouseCollector),document.attachEvent("keypress",this.a.keyboardCollector);else throw new sjcl.exception.bug("can't attach event"); +this.D=!0}},stopCollectors:function(){this.D&&(window.removeEventListener?(window.removeEventListener("load",this.a.loadTimeCollector,!1),window.removeEventListener("mousemove",this.a.mouseCollector,!1),window.removeEventListener("keypress",this.a.keyboardCollector,!1),window.removeEventListener("devicemotion",this.a.accelerometerCollector,!1),window.removeEventListener("touchmove",this.a.touchCollector,!1)):document.detachEvent&&(document.detachEvent("onload",this.a.loadTimeCollector),document.detachEvent("onmousemove", +this.a.mouseCollector),document.detachEvent("keypress",this.a.keyboardCollector)),this.D=!1)},addEventListener:function(a,b){this.K[a][this.ga++]=b},removeEventListener:function(a,b){var c,d,e=this.K[a],f=[];for(d in e)e.hasOwnProperty(d)&&e[d]===b&&f.push(d);for(c=0;cb&&(a.h[b]=a.h[b]+1|0,!a.h[b]);b++);return a.L.encrypt(a.h)} +function B(a,b){return function(){b.apply(a,arguments)}}sjcl.random=new sjcl.prng(6); +a:try{var D,E,F,G;if(G="undefined"!==typeof module&&module.exports){var H;try{H=require("crypto")}catch(a){H=null}G=E=H}if(G&&E.randomBytes)D=E.randomBytes(128),D=new Uint32Array((new Uint8Array(D)).buffer),sjcl.random.addEntropy(D,1024,"crypto['randomBytes']");else if("undefined"!==typeof window&&"undefined"!==typeof Uint32Array){F=new Uint32Array(32);if(window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(F);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(F); +else break a;sjcl.random.addEntropy(F,1024,"crypto['getRandomValues']")}}catch(a){"undefined"!==typeof window&&window.console&&(console.log("There was an error collecting entropy from the browser:"),console.log(a))} +sjcl.json={defaults:{v:1,iter:1E4,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},ja:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,f=e.g({iv:sjcl.random.randomWords(4,0)},e.defaults),g;e.g(f,c);c=f.adata;"string"===typeof f.salt&&(f.salt=sjcl.codec.base64.toBits(f.salt));"string"===typeof f.iv&&(f.iv=sjcl.codec.base64.toBits(f.iv));if(!sjcl.mode[f.mode]||!sjcl.cipher[f.cipher]||"string"===typeof a&&100>=f.iter||64!==f.ts&&96!==f.ts&&128!==f.ts||128!==f.ks&&192!==f.ks&&0x100!==f.ks||2>f.iv.length|| +4=b.iter||64!==b.ts&&96!==b.ts&&128!==b.ts||128!==b.ks&&192!==b.ks&&0x100!==b.ks||!b.iv||2>b.iv.length||4
% } +
+
+
+ <%= l('Your browser has not enough entropy to generate a strong encryption key. Please wait (it\'s better if you do things on your computer while waiting).') %> +
+
+
% if (stop_upload) {
@@ -87,8 +94,8 @@

<%= l('Drop files here') %>

<%= l('or') %>

From 6a4e48d3cb8f91ac59ceee69c7496684f148fbc6 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Mon, 22 Oct 2018 20:31:52 +0200 Subject: [PATCH 18/49] [i18n] Fix typographic apostroph --- themes/default/lib/Lufi/I18N/fr.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/default/lib/Lufi/I18N/fr.po b/themes/default/lib/Lufi/I18N/fr.po index 065b14b..9004da5 100644 --- a/themes/default/lib/Lufi/I18N/fr.po +++ b/themes/default/lib/Lufi/I18N/fr.po @@ -522,7 +522,7 @@ msgstr "pour %1 et plus, le fichier sera conservé indéfiniment." #: themes/default/templates/index.html.ep:3 msgid "no time limit" -msgstr "Pas de délai d'expiration" +msgstr "Pas de délai d’expiration" #: themes/default/templates/index.html.ep:95 msgid "or" From 377a48bda262831f79fa7a380f52124f259572e3 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Mon, 22 Oct 2018 20:54:28 +0200 Subject: [PATCH 19/49] Add report file link in the navbar --- CHANGELOG | 1 + cpanfile | 1 + cpanfile.snapshot | 52 +++++++++++++++++++ lib/Lufi.pm | 12 ++++- lufi.conf.template | 8 ++- themes/default/lib/Lufi/I18N/ca.po | 14 +++-- themes/default/lib/Lufi/I18N/en.po | 14 +++-- themes/default/lib/Lufi/I18N/fr.po | 14 +++-- themes/default/lib/Lufi/I18N/it.po | 14 +++-- themes/default/lib/Lufi/I18N/nl.po | 14 +++-- themes/default/lib/Lufi/I18N/oc.po | 14 +++-- themes/default/lib/Lufi/I18N/pt.po | 14 +++-- themes/default/templates/about.html.ep | 2 +- .../default/templates/layouts/default.html.ep | 2 + 14 files changed, 138 insertions(+), 38 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1b0c0e8..7bd6ec8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,7 @@ Revision history for Lufi - Add Content-Security-Policy header - Update sjcl.js - Mitigate genRandomKey exception risk + - Add report file link in the navbar 0.02.2 2017-09-18 - Fix cron tasks bug diff --git a/cpanfile b/cpanfile index c437532..e5b8559 100644 --- a/cpanfile +++ b/cpanfile @@ -18,6 +18,7 @@ requires 'Number::Bytes::Human'; requires 'Filesys::DfPortable'; requires 'Data::Entropy'; requires 'Crypt::SaltedHash'; +requires 'Data::Validate::URI'; feature 'ldap', 'LDAP authentication support' => sub { requires 'Net::LDAP'; diff --git a/cpanfile.snapshot b/cpanfile.snapshot index 25e52b4..9808c67 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -265,6 +265,37 @@ DISTRIBUTIONS perl 5.006 strict 0 warnings 0 + Data-Validate-Domain-0.14 + pathname: D/DR/DROLSKY/Data-Validate-Domain-0.14.tar.gz + provides: + Data::Validate::Domain 0.14 + requirements: + Exporter 0 + ExtUtils::MakeMaker 0 + Net::Domain::TLD 1.74 + strict 0 + warnings 0 + Data-Validate-IP-0.27 + pathname: D/DR/DROLSKY/Data-Validate-IP-0.27.tar.gz + provides: + Data::Validate::IP 0.27 + requirements: + Exporter 0 + ExtUtils::MakeMaker 0 + NetAddr::IP 4 + Scalar::Util 0 + base 0 + perl 5.008 + strict 0 + warnings 0 + Data-Validate-URI-0.07 + pathname: S/SO/SONNEN/Data-Validate-URI-0.07.tar.gz + provides: + Data::Validate::URI 0.07 + requirements: + Data::Validate::Domain 0 + Data::Validate::IP 0 + ExtUtils::MakeMaker 0 Devel-GlobalDestruction-0.14 pathname: H/HA/HAARG/Devel-GlobalDestruction-0.14.tar.gz provides: @@ -1236,6 +1267,14 @@ DISTRIBUTIONS Test::More 0.52 Time::Local 1.19 perl 5.006 + Net-Domain-TLD-1.75 + pathname: A/AL/ALEXP/Net-Domain-TLD-1.75.tar.gz + provides: + Net::Domain::TLD 1.75 + requirements: + Carp 0 + ExtUtils::MakeMaker 0 + Storable 0 Net-HTTP-6.18 pathname: O/OA/OALDERS/Net-HTTP-6.18.tar.gz provides: @@ -1265,6 +1304,19 @@ DISTRIBUTIONS MIME::Base64 0 Test::More 0.60_01 perl 5.005 + NetAddr-IP-4.079 + pathname: M/MI/MIKER/NetAddr-IP-4.079.tar.gz + provides: + NetAddr::IP 4.079 + NetAddr::IP::InetBase 0.08 + NetAddr::IP::Lite 1.57 + NetAddr::IP::Util 1.53 + NetAddr::IP::UtilPP 1.09 + NetAddr::IP::UtilPolluted 1.53 + NetAddr::IP::Util_IS 1 + requirements: + ExtUtils::MakeMaker 0 + Test::More 0 Number-Bytes-Human-0.11 pathname: F/FE/FERREIRA/Number-Bytes-Human-0.11.tar.gz provides: diff --git a/lib/Lufi.pm b/lib/Lufi.pm index 5f47c7f..eaa0db0 100644 --- a/lib/Lufi.pm +++ b/lib/Lufi.pm @@ -4,6 +4,8 @@ use Mojo::Base 'Mojolicious'; use Net::LDAP; use Apache::Htpasswd; use Mojolicious::Sessions; +use Email::Valid; +use Data::Validate::URI qw(is_web_uri); $ENV{MOJO_MAX_WEBSOCKET_SIZE} = 100485760; # 10 * 1024 * 1024 = 10MiB @@ -38,7 +40,15 @@ sub startup { } }); - die "You need to provide a contact information in lufi.conf!" unless (defined($self->config('contact'))); + die 'You need to provide a contact information in lufi.conf!' unless (defined($self->config('contact'))); + die 'You need to provide a **report** information in lufi.conf!' unless (defined($self->config('report'))); + + if (Email::Valid->address($self->config('report'))) { + $self->config('report' => 'mailto:'.$self->config('report')); + } elsif (!is_web_uri($self->config('report'))) { + die 'You need to provide an email address or an URL as report information in lufi.conf!'; + } + # Themes handling shift @{$self->renderer->paths}; diff --git a/lufi.conf.template b/lufi.conf.template index 3ff1a97..0136e1b 100644 --- a/lufi.conf.template +++ b/lufi.conf.template @@ -18,8 +18,14 @@ }, # put a way to contact you here and uncomment it + # you can put some HTML in it # MANDATORY - #contact => 'admin[at]example.com', + #contact => 'Contact page', + + # put an URL or an email address to receive file reports and uncomment it + # it's for make reporting illegal files easy for users + # MANDATORY + #report => 'report@example.com', # array of random strings used to encrypt cookies # optional, default is ['fdjsofjoihrei'], PLEASE, CHANGE IT diff --git a/themes/default/lib/Lufi/I18N/ca.po b/themes/default/lib/Lufi/I18N/ca.po index 74437fd..7a35c95 100644 --- a/themes/default/lib/Lufi/I18N/ca.po +++ b/themes/default/lib/Lufi/I18N/ca.po @@ -44,7 +44,7 @@ msgstr "Un agraïment amb la foto d'un gatet a <%= l('Drag and drop files in the appropriate area or use the traditional way to send files and the files will be chunked, encrypted and sent to the server. You will get two links per file: a download link, that you give to the people you want to share the file with and a deletion link, allowing you to delete the file whenever you want.') %>

<%= l('You can see the list of your files by clicking on the "My files" link at the top right of this page.') %>

<%= l('How to report an illegal file?') %>

-

<%= l('Please contact the administrator: %1', config('contact')) %>

+

<%== l('Please contact the administrator: %1', config('contact')) %>

<%= l('Who wrote this software?') %>

<%== l('The original (and only for now) author is Luc Didry. If you want to support him, you can do it via Tipeee or via Liberapay.') %>
<%== l('A thank you with a photo of kitten on Diaspora* or Mastodon is cool too ;-)') %>

diff --git a/themes/default/templates/layouts/default.html.ep b/themes/default/templates/layouts/default.html.ep index e293b75..fb0c2fa 100644 --- a/themes/default/templates/layouts/default.html.ep +++ b/themes/default/templates/layouts/default.html.ep @@ -26,6 +26,7 @@
    +
  • <%= l('Report file') %>
  • % if ((!defined(config('ldap')) && !defined(config('htpasswd'))) || is_user_authenticated()) { ><%= l('Upload files') %> ><%= l('My files') %> From 986e7793db7adc2028b2c2b2110280ca0e88c760 Mon Sep 17 00:00:00 2001 From: Luc Didry Date: Mon, 22 Oct 2018 23:54:20 +0200 Subject: [PATCH 20/49] Allow to choose your language --- CHANGELOG | 1 + cpanfile | 2 +- cpanfile.snapshot | 20 +++++--- lib/Lufi.pm | 4 ++ lib/Lufi/Controller/Misc.pm | 13 +++++ themes/default/lib/Lufi/I18N/ca.po | 48 ++++++++++--------- themes/default/lib/Lufi/I18N/en.po | 48 ++++++++++--------- themes/default/lib/Lufi/I18N/fr.po | 48 ++++++++++--------- themes/default/lib/Lufi/I18N/it.po | 48 ++++++++++--------- themes/default/lib/Lufi/I18N/nl.po | 48 ++++++++++--------- themes/default/lib/Lufi/I18N/oc.po | 48 ++++++++++--------- themes/default/lib/Lufi/I18N/pt.po | 48 ++++++++++--------- themes/default/public/css/lufi.css | 19 ++++++++ themes/default/public/js/jquery-2.1.1.min.js | 4 -- themes/default/public/js/jquery-2.2.4.min.js | 4 ++ themes/default/public/js/lufi-common.js | 8 ++++ .../default/templates/layouts/default.html.ep | 25 +++++++++- themes/default/templates/partial/index.js.ep | 1 - themes/default/templates/partial/layout.js.ep | 2 + 19 files changed, 272 insertions(+), 167 deletions(-) delete mode 100644 themes/default/public/js/jquery-2.1.1.min.js create mode 100644 themes/default/public/js/jquery-2.2.4.min.js create mode 100644 themes/default/templates/partial/layout.js.ep diff --git a/CHANGELOG b/CHANGELOG index 7bd6ec8..3bf20f8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,6 +11,7 @@ Revision history for Lufi - Update sjcl.js - Mitigate genRandomKey exception risk - Add report file link in the navbar + - Allow to choose your language 0.02.2 2017-09-18 - Fix cron tasks bug diff --git a/cpanfile b/cpanfile index e5b8559..d0a62f8 100644 --- a/cpanfile +++ b/cpanfile @@ -6,7 +6,7 @@ requires 'Mojolicious::Plugin::Mail'; requires 'Mojolicious::Plugin::GzipStatic'; requires 'Mojolicious::Plugin::StaticCache'; requires 'Mojolicious::Plugin::CSPHeader'; -requires 'Mojolicious::Plugin::FiatTux::Helpers', '== 0.01', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-helpers/-/archive/0.01/mojolicious-plugin-fiattux-helpers-0.01.tar.gz'; +requires 'Mojolicious::Plugin::FiatTux::Helpers', '== 0.06', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-helpers/-/archive/0.06/mojolicious-plugin-fiattux-helpers-0.06.tar.gz'; requires 'Mojolicious::Plugin::FiatTux::GrantAccess', '== 0.05', url => 'https://framagit.org/luc/mojolicious-plugin-fiattux-grantaccess/-/archive/0.05/mojolicious-plugin-fiattux-grantaccess-0.05.tar.gz'; requires 'EV'; requires 'Filesys::DiskUsage'; diff --git a/cpanfile.snapshot b/cpanfile.snapshot index 9808c67..ce39cb1 100644 --- a/cpanfile.snapshot +++ b/cpanfile.snapshot @@ -428,10 +428,10 @@ DISTRIBUTIONS Filesys::DfPortable 0.85 requirements: ExtUtils::MakeMaker 0 - Filesys-DiskUsage-0.11 - pathname: M/MA/MANWAR/Filesys-DiskUsage-0.11.tar.gz + Filesys-DiskUsage-0.12 + pathname: M/MA/MANWAR/Filesys-DiskUsage-0.12.tar.gz provides: - Filesys::DiskUsage 0.11 + Filesys::DiskUsage 0.12 requirements: ExtUtils::MakeMaker 0 File::Basename 0 @@ -601,6 +601,13 @@ DISTRIBUTIONS Mozilla::CA 0 Net::SSLeay 1.46 Scalar::Util 0 + ISO-639_1-0.02 + pathname: L/LD/LDIDRY/ISO-639_1-0.02.tar.gz + provides: + ISO::639_1 0.02 + requirements: + Module::Build::Tiny 0.035 + perl 5.008001 JSON-2.97001 pathname: I/IS/ISHIGAKI/JSON-2.97001.tar.gz provides: @@ -925,8 +932,8 @@ DISTRIBUTIONS URI::db 0.15 URI::file 4.21 perl 5.010001 - Mojolicious-8.03 - pathname: S/SR/SRI/Mojolicious-8.03.tar.gz + Mojolicious-8.04 + pathname: S/SR/SRI/Mojolicious-8.04.tar.gz provides: Mojo undef Mojo::Asset undef @@ -946,6 +953,7 @@ DISTRIBUTIONS Mojo::DOM::CSS undef Mojo::DOM::HTML undef Mojo::Date undef + Mojo::DynamicMethods undef Mojo::EventEmitter undef Mojo::Exception undef Mojo::File undef @@ -995,7 +1003,7 @@ DISTRIBUTIONS Mojo::UserAgent::Transactor undef Mojo::Util undef Mojo::WebSocket undef - Mojolicious 8.03 + Mojolicious 8.04 Mojolicious::Command undef Mojolicious::Command::Author::cpanify undef Mojolicious::Command::Author::generate undef diff --git a/lib/Lufi.pm b/lib/Lufi.pm index eaa0db0..95d927a 100644 --- a/lib/Lufi.pm +++ b/lib/Lufi.pm @@ -128,6 +128,10 @@ sub startup { ->to('Misc#index') ->name('index'); + $r->get('/lang/:l') + ->to('Misc#change_lang') + ->name('lang'); + if (defined $self->config('ldap') || defined $self->config('htpasswd')) { # Login page $r->get('/login') diff --git a/lib/Lufi/Controller/Misc.pm b/lib/Lufi/Controller/Misc.pm index 17eff6b..488c75a 100644 --- a/lib/Lufi/Controller/Misc.pm +++ b/lib/Lufi/Controller/Misc.pm @@ -13,6 +13,19 @@ sub index { } } +sub change_lang { + my $c = shift; + my $l = $c->param('l'); + + $c->cookie($c->app->moniker.'_lang' => $l, { path => $c->config('prefix') }); + + if ($c->req->headers->referrer) { + return $c->redirect_to($c->req->headers->referrer); + } else { + return $c->redirect_to('/'); + } +} + sub about { shift->render(template => 'about'); } diff --git a/themes/default/lib/Lufi/I18N/ca.po b/themes/default/lib/Lufi/I18N/ca.po index 7a35c95..df4f86a 100644 --- a/themes/default/lib/Lufi/I18N/ca.po +++ b/themes/default/lib/Lufi/I18N/ca.po @@ -44,7 +44,7 @@ msgstr "Un agraïment amb la foto d'un gatet a a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
    ",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="
    ","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b) -},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("