Fix #2 Add share by mail page

This commit is contained in:
Luc Didry 2015-10-03 01:22:43 +02:00
parent 50aa763ee1
commit ae8934c1d9
10 changed files with 405 additions and 27 deletions

View File

@ -2,8 +2,10 @@ requires "Mojolicious";
requires "ORLite";
requires "Mojolicious::Plugin::DebugDumperHelper";
requires 'Mojolicious::Plugin::I18N';
requires 'Mojolicious::Plugin::Mail';
requires 'EV';
requires 'Filesys::DiskUsage';
requires 'Switch';
requires 'Locale::Maketext';
requires 'Locale::Maketext::Extract';
requires 'Email::Valid';

View File

@ -153,6 +153,26 @@ DISTRIBUTIONS
Canary::Stability 0
ExtUtils::MakeMaker 6.52
common::sense 0
Email-Date-Format-1.005
pathname: R/RJ/RJBS/Email-Date-Format-1.005.tar.gz
provides:
Email::Date::Format 1.005
requirements:
Exporter 5.57
ExtUtils::MakeMaker 0
Time::Local 0
strict 0
warnings 0
Email-Valid-1.196
pathname: R/RJ/RJBS/Email-Valid-1.196.tar.gz
provides:
Email::Valid 1.196
requirements:
ExtUtils::MakeMaker 0
Mail::Address 0
Scalar::Util 0
Test::More 0
perl 5.006
File-Remove-1.52
pathname: A/AD/ADAMK/File-Remove-1.52.tar.gz
provides:
@ -210,6 +230,87 @@ DISTRIBUTIONS
requirements:
ExtUtils::MakeMaker 6.30
Locale::Maketext 1.17
MIME-Charset-1.012
pathname: N/NE/NEZUMI/MIME-Charset-1.012.tar.gz
provides:
MIME::Charset 1.012
requirements:
CPAN 0
Encode 1.98
ExtUtils::MakeMaker 6.42
Test::More 0
perl 5.005
MIME-EncWords-1.014.3
pathname: N/NE/NEZUMI/MIME-EncWords-1.014.3.tar.gz
provides:
Encode::MIME::EncWords 0.03
MIME::EncWords 1.014003
requirements:
Encode 1.98
ExtUtils::MakeMaker 0
MIME::Base64 2.13
MIME::Charset v1.10.1
Test::More 0
MIME-Lite-3.030
pathname: R/RJ/RJBS/MIME-Lite-3.030.tar.gz
provides:
MIME::Lite 3.030
MIME::Lite::IO_Handle 3.030
MIME::Lite::IO_Scalar 3.030
MIME::Lite::IO_ScalarArray 3.030
MIME::Lite::SMTP 3.030
MailTool undef
requirements:
Email::Date::Format 1.000
ExtUtils::MakeMaker 0
File::Basename 0
File::Spec 0
MIME::Types 1.28
MIME-Types-2.11
pathname: M/MA/MARKOV/MIME-Types-2.11.tar.gz
provides:
MIME::Type 2.11
MIME::Types 2.11
MojoX::MIME::Types 2.11
requirements:
ExtUtils::MakeMaker 0
File::Basename 0
File::Spec 0
List::Util 0
Test::More 0.47
MailTools-2.14
pathname: M/MA/MARKOV/MailTools-2.14.tar.gz
provides:
Mail undef
Mail::Address 2.14
Mail::Cap 2.14
Mail::Field 2.14
Mail::Field::AddrList 2.14
Mail::Field::Date 2.14
Mail::Field::Generic 2.14
Mail::Filter 2.14
Mail::Header 2.14
Mail::Internet 2.14
Mail::Mailer 2.14
Mail::Mailer::qmail 2.14
Mail::Mailer::rfc822 2.14
Mail::Mailer::sendmail 2.14
Mail::Mailer::smtp 2.14
Mail::Mailer::smtp::pipe 2.14
Mail::Mailer::smtps 2.14
Mail::Mailer::smtps::pipe 2.14
Mail::Mailer::testfile 2.14
Mail::Mailer::testfile::pipe 2.14
Mail::Send 2.14
Mail::Util 2.14
requirements:
Date::Format 0
Date::Parse 0
ExtUtils::MakeMaker 0
IO::Handle 0
Net::Domain 1.05
Net::SMTP 1.03
Test::More 0
Module-Build-0.4214
pathname: L/LE/LEONT/Module-Build-0.4214.tar.gz
provides:
@ -392,6 +493,17 @@ DISTRIBUTIONS
Mojolicious 5
Test::More 0
perl 5.010001
Mojolicious-Plugin-Mail-1.5
pathname: S/SH/SHARIFULN/Mojolicious-Plugin-Mail-1.5.tar.gz
provides:
Mojolicious::Plugin::Mail 1.5
requirements:
Encode 0
MIME::EncWords 0
MIME::Lite 3.027
Mojolicious 5
Test::More 0
perl 5.001001
ORLite-1.98
pathname: A/AD/ADAMK/ORLite-1.98.tar.gz
provides:
@ -475,6 +587,49 @@ DISTRIBUTIONS
Test::Builder::Tester 1.02
Test::More 0
perl 5.006
TimeDate-2.30
pathname: G/GB/GBARR/TimeDate-2.30.tar.gz
provides:
Date::Format 2.24
Date::Format::Generic 2.24
Date::Language 1.10
Date::Language::Afar 0.99
Date::Language::Amharic 1.00
Date::Language::Austrian 1.01
Date::Language::Brazilian 1.01
Date::Language::Bulgarian 1.01
Date::Language::Chinese 1.00
Date::Language::Chinese_GB 1.01
Date::Language::Czech 1.01
Date::Language::Danish 1.01
Date::Language::Dutch 1.02
Date::Language::English 1.01
Date::Language::Finnish 1.01
Date::Language::French 1.04
Date::Language::Gedeo 0.99
Date::Language::German 1.02
Date::Language::Greek 1.00
Date::Language::Hungarian 1.01
Date::Language::Icelandic 1.01
Date::Language::Italian 1.01
Date::Language::Norwegian 1.01
Date::Language::Oromo 0.99
Date::Language::Romanian 1.01
Date::Language::Russian 1.01
Date::Language::Russian_cp1251 1.01
Date::Language::Russian_koi8r 1.01
Date::Language::Sidama 0.99
Date::Language::Somali 0.99
Date::Language::Spanish 1.00
Date::Language::Swedish 1.01
Date::Language::Tigrinya 1.00
Date::Language::TigrinyaEritrean 1.00
Date::Language::TigrinyaEthiopian 1.00
Date::Language::Turkish 1.0
Date::Parse 2.30
Time::Zone 2.24
requirements:
ExtUtils::MakeMaker 0
common-sense-3.74
pathname: M/ML/MLEHMANN/common-sense-3.74.tar.gz
provides:

View File

@ -17,12 +17,26 @@ sub startup {
token_length => 32,
secret => ['hfudsifdsih'],
default_delay => 0,
max_delay => 0
max_delay => 0,
mail => {
how => 'sendmail'
},
mail_sender => 'no-reply@lufi.io'
}
});
die "You need to provide a contact information in lufi.conf!" unless (defined($config->{contact}));
# Mail config
my $mail_config = {
type => 'text/plain',
encoding => 'quoted-printable',
how => $self->config('mail')->{'how'}
};
$mail_config->{howargs} = $self->config('mail')->{'howargs'} if (defined $self->config('mail')->{'howargs'});
$self->plugin('Mail' => $mail_config);
# Internationalization
$self->plugin('I18N');

View File

@ -0,0 +1,59 @@
# vim:set sw=4 ts=4 sts=4 ft=perl expandtab:
package Lufi::Controller::Mail;
use Mojo::Base 'Mojolicious::Controller';
use Email::Valid;
sub send_mail {
my $c = shift;
my $validation = $c->validation;
return $c->render(text => 'Bad CSRF token!', status => 403) if $validation->csrf_protect->has_error('csrf_token');
my $emails = $c->param('emails');
$emails =~ s/ //g;
my @a = split(',', $emails);
my @bad;
my @good;
for my $email (@a) {
if (!Email::Valid->address($email)) {
push @bad, $email;
}
}
my $msg = '';
if (scalar(@bad)) {
$msg .= $c->l('The following email addresses are not valid: %1', join(', ', @bad))."\n";
}
$msg .= $c->l('You must give email addresses.')."\n" unless (scalar(@a));
$msg .= $c->l('The email subject can\'t be empty.')."\n" unless ($c->param('subject'));
$msg .= $c->l('The email body can\'t be empty.')."\n" unless ($c->param('body'));
if ($msg) {
return $c->render(
template => 'mail',
msg => $msg,
values => {
emails => $emails,
subject => $c->param('subject'),
body => $c->param('body')
}
)
}
$c->mail(
from => $c->config('mail_sender'),
bcc => $emails,
subject => $c->param('subject'),
data => $c->param('body')
);
return $c->render(
template => 'msg',
msg_success => $c->l('The mail has been sent.')
);
}
1;

View File

@ -17,7 +17,7 @@ msgstr ""
#. ($delay)
#. (config('max_delay')
#: templates/index.html.ep:12 templates/index.html.ep:21 templates/index.html.ep:22
#: templates/index.html.ep:19 templates/index.html.ep:28 templates/index.html.ep:29
msgid "%1 days"
msgstr "%1 days"
@ -25,19 +25,23 @@ msgstr "%1 days"
msgid "1 year"
msgstr ""
#: templates/index.html.ep:21 templates/index.html.ep:4
#: templates/index.html.ep:28 templates/index.html.ep:4
msgid "24 hours"
msgstr ""
#: templates/layouts/default.html.ep:35
#: templates/layouts/default.html.ep:41
msgid "About"
msgstr ""
#: templates/index.html.ep:44
#: templates/index.html.ep:51
msgid "Click to open the file browser"
msgstr ""
#: templates/index.html.ep:59
#: templates/index.html.ep:65
msgid "Copy all links to clipboard"
msgstr ""
#: templates/index.html.ep:66
msgid "Copy to clipboard"
msgstr ""
@ -49,19 +53,23 @@ msgstr ""
msgid "Could not find the file. Are you sure of the URL?"
msgstr ""
#: templates/index.html.ep:35
#: templates/index.html.ep:42
msgid "Delete at first view?"
msgstr ""
#: templates/index.html.ep:60
#: templates/index.html.ep:67
msgid "Deletion link"
msgstr ""
#: templates/index.html.ep:58
#: templates/index.html.ep:69
msgid "Download"
msgstr ""
#: templates/index.html.ep:68
msgid "Download link"
msgstr ""
#: templates/index.html.ep:41
#: templates/index.html.ep:48
msgid "Drop files here"
msgstr ""
@ -69,18 +77,22 @@ msgstr ""
msgid "File deleted"
msgstr ""
#: templates/index.html.ep:57
#: templates/index.html.ep:72
msgid "Hit Enter, then Ctrl+C to copy all the download links"
msgstr ""
#: templates/index.html.ep:56
#: templates/index.html.ep:71
msgid "Hit Enter, then Ctrl+C to copy the download link"
msgstr ""
#: templates/layouts/default.html.ep:34
#: templates/layouts/default.html.ep:40
msgid "My files"
msgstr ""
#: templates/index.html.ep:73
msgid "Send all links by email"
msgstr ""
#: lib/Lufi/Controller/Files.pm:169
msgid "The file has already been deleted"
msgstr ""
@ -93,18 +105,22 @@ msgstr ""
msgid "Unable to get counter"
msgstr ""
#: templates/layouts/default.html.ep:33
#: templates/layouts/default.html.ep:39
msgid "Upload files"
msgstr ""
#: templates/index.html.ep:49
#: templates/index.html.ep:56
msgid "Uploaded files"
msgstr ""
#: templates/index.html.ep:70
msgid "You have attempted to leave this page. The upload will be canceled. Are you sure?"
msgstr ""
#: templates/index.html.ep:3
msgid "no time limit"
msgstr ""
#: templates/index.html.ep:42
#: templates/index.html.ep:49
msgid "or"
msgstr ""

View File

@ -37,7 +37,6 @@
# optional, no default
#broadcast_message => 'Maintenance',
# default time limit for files
# valid values are 0, 1, 7, 30 and 365
# optional, default is 0 (no limit)
@ -62,4 +61,17 @@
# if set, the shortened URLs will use this domain
# optional
#fixed_domain => 'example.org',
};
# Mail configuration
# See https://metacpan.org/pod/Mojolicious::Plugin::Mail#EXAMPLES
# Optional, default to sendmail method with no arguments
#mail => {
# # Valid values are 'sendmail' and 'smtp'
# how => 'smtp',
# howargs => ['smtp.example.org']
#},
# Email sender address
# Optional, default to no-reply@lufi.io
#mail_sender => 'no-reply@lufi.io'
};

View File

@ -33,9 +33,11 @@ function copyToClipboard(el) {
}
function copyAllToClipboard() {
var text = new Array();
document.getElementByClassName('link-input').forEach(function(e, index, array) {
text.push(e.value);
});
var a = document.getElementsByClassName('link-input');
var i;
for (i = 0; i < a.length; i++) {
text.push(a[i].value);
}
var textArea = document.createElement('textarea');
textArea.style.position = 'fixed';
textArea.style.top = 0;
@ -170,8 +172,9 @@ function updateProgressBar(data) {
if (j + 1 === parts) {
var d = document.createElement('div');
var url = document.location.href.replace(/#$/, '')+'r/'+short+'#'+key;
var del_url = document.location.href.replace(/#$/, '')+'d/'+short+'/'+data.token;
var baseURL = document.location.href.replace(/#$/, '');
var url = baseURL+'r/'+short+'#'+key;
var del_url = baseURL+'d/'+short+'/'+data.token;
d.innerHTML = '<div class="form-group"><label class="sr-only" for="'
+short
+'">'
@ -207,6 +210,22 @@ function updateProgressBar(data) {
p2.remove();
p1.appendChild(d);
// Add copy all and mailto buttons
var misc = document.getElementById('misc');
if (misc.innerHTML === '') {
misc.innerHTML = '<a href="#" onclick="copyAllToClipboard();" class="btn btn-info">'+i18n.copyAll+'</a> <a id="mailto" href="'+baseURL+'m?links=["'+short+'"]" class="btn btn-info">'+i18n.mailTo+'</a>';
} else {
var a = document.getElementsByClassName('link-input');
var l = new Array();
var i;
for (i = 0; i < a.length; i++) {
l.push(a[i].id);
}
var u = baseURL+'m?links='+JSON.stringify(l);
document.getElementById('mailto').href = u;
}
// Add the file to localStorage
addItem(data.name, url, data.size, del_at_first_view, created_at, delay, data.short, data.token);
i++;

View File

@ -54,6 +54,7 @@
</div>
<div id="results">
<h2><%= l('Uploaded files') %></h2>
<div id="misc" class="form-group"></div>
<ul class="list-group" id="ul-results">
</ul>
</div>
@ -61,13 +62,15 @@
%= javascript begin
var ws_url = '<%= url_for('upload')->to_abs() %>';
var i18n = {
copyAll: '<%= l('Copy all links to clipboard') %>',
cpText: '<%= l('Copy to clipboard') %>',
delText: '<%= l('Deletion link') %>',
delText: '<%= l('Deletion link') %>',
dlText: '<%= l('Download link') %>',
download: '<%= l('Download') %>',
confirmExit: '<%= l('You have attempted to leave this page. The upload will be canceled. Are you sure?') %>',
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') %>',
}
% end
%= javascript '/js/sjcl.js'

96
templates/mail.html.ep Normal file
View File

@ -0,0 +1,96 @@
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
<div class="inner cover render">
% if (defined(stash('msg'))) {
<div class="alert alert-warning"><%= stash('msg') %></div>
% }
<div class="alert alert-info">
<p><%= l('If you send the mail from this server, the links will be send to the server, which may lower your privacy protection.') %></p>
</div>
<form action="<%= url_for('m') %>" method="post">
%= csrf_field
<div class="form-group">
<label for="emails"><%= l('Comma-separated email addresses') %></label>
% if (defined(stash('values'))) {
<input type="text" class="form-control" id="emails" name="emails" placeholder="<%= l('Emails') %>" value="<%== stash('values')->{emails} %>">
% } else {
<input type="text" class="form-control" id="emails" name="emails" placeholder="<%= l('Emails') %>">
% }
</div>
<div class="form-group">
<label for="subject"><%= l('Email subject') %></label>
% if (defined(stash('values'))) {
<input type="text" class="form-control" id="subject" name="subject" value="<%= l('Here\'s some files') %>" value="<%== stash('values')->{subject} %>">
% } else {
<input type="text" class="form-control" id="subject" name="subject" value="<%= l('Here\'s some files') %>">
% }
</div>
<div class="form-group">
<label for="body"><%= l('Email body') %></label>
<textarea class="form-control" id="body" name="body" rows="10">
% if (defined(stash('values'))) {
<%== stash('values')->{body} %>
% }
</textarea>
</div>
<button type="submit" class="btn btn-info"><%= l('Send with this server') %></button>
<a href="#" class="btn btn-primary" id="mailto"><%= l('Send with your own mail software') %></a>
</form>
</div>
%= javascript begin
function findItem(name) {
console.log(name);
var files = localStorage.getItem('files');
if (files === null) {
files = new Array();
} else {
files = JSON.parse(files);
}
var r = null;
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(body.value);
}
function populateBody() {
var links = JSON.parse('<%== $self->param('links') %>');
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) {
var limit = (item.limit === 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 '/js/moment-with-locales.min.js'

View File

@ -1,9 +1,11 @@
% # vim:set sw=4 ts=4 sts=4 ft=html.epl expandtab:
<div class="inner cover render">
% if (!defined($f) && defined($msg)) {
<div class="alert alert-warning"><%= $msg %></div>
% if (!defined(stash('f')) && defined(stash('msg'))) {
<div class="alert alert-warning"><%= stash('msg') %></div>
% } elsif (defined(stash('msg_success'))) {
<div class="alert alert-success"><%= stash('msg_success') %></div>
% } else {
<h2><%= stash('f')->filename %></h2>
<div class="alert alert-info"><%= $msg %></div>
<div class="alert alert-info"><%= stash('msg') %></div>
% }
</div>