Allow sending messages as well as uploading files in receive mode

This commit is contained in:
Micah Lee 2021-04-25 20:46:03 -04:00
parent 8c9d101f31
commit b343d391b3
5 changed files with 218 additions and 108 deletions

View file

@ -199,6 +199,18 @@ def main(cwd=None):
default=None, default=None,
help="Receive files: URL to receive webhook notifications", help="Receive files: URL to receive webhook notifications",
) )
parser.add_argument(
"--disable-text",
action="store_true",
dest="disable_text",
help="Receive files: Disable receiving text messages",
)
parser.add_argument(
"--disable-files",
action="store_true",
dest="disable_files",
help="Receive files: Disable receiving files",
)
# Website args # Website args
parser.add_argument( parser.add_argument(
"--disable_csp", "--disable_csp",
@ -242,6 +254,8 @@ def main(cwd=None):
autostop_sharing = not bool(args.no_autostop_sharing) autostop_sharing = not bool(args.no_autostop_sharing)
data_dir = args.data_dir data_dir = args.data_dir
webhook_url = args.webhook_url webhook_url = args.webhook_url
disable_text = args.disable_text
disable_files = args.disable_files
disable_csp = bool(args.disable_csp) disable_csp = bool(args.disable_csp)
verbose = bool(args.verbose) verbose = bool(args.verbose)
@ -292,6 +306,8 @@ def main(cwd=None):
mode_settings.set("receive", "data_dir", data_dir) mode_settings.set("receive", "data_dir", data_dir)
if webhook_url: if webhook_url:
mode_settings.set("receive", "webhook_url", webhook_url) mode_settings.set("receive", "webhook_url", webhook_url)
mode_settings.set("receive", "disable_text", disable_text)
mode_settings.set("receive", "disable_files", disable_files)
if mode == "website": if mode == "website":
mode_settings.set("website", "disable_csp", disable_csp) mode_settings.set("website", "disable_csp", disable_csp)
else: else:
@ -334,6 +350,11 @@ def main(cwd=None):
if persistent_filename: if persistent_filename:
mode_settings.set(mode, "filenames", filenames) mode_settings.set(mode, "filenames", filenames)
# In receive mode, you must allows either text, files, or both
if mode == "receive" and disable_text and disable_files:
print(f"You cannot disable both text and files")
sys.exit()
# Create the Web object # Create the Web object
web = Web(common, False, mode_settings, mode) web = Web(common, False, mode_settings, mode)

View file

@ -285,6 +285,13 @@ ul.breadcrumbs li a:link, ul.breadcrumbs li a:visited {
margin: 0 0 20px 0; margin: 0 0 20px 0;
} }
.upload-wrapper textarea {
max-width: 95%;
width: 600px;
height: 150px;
padding: 10px;
}
div#uploads { div#uploads {
width: 800px; width: 800px;
max-width: 90%; max-width: 90%;

View file

@ -11,15 +11,26 @@ $(function(){
$('#send').submit(function (event) { $('#send').submit(function (event) {
event.preventDefault(); event.preventDefault();
// Create form data, and list of filenames // Build the form data
var files = $('#file-select').get(0).files;
var filenames = [];
var formData = new FormData(); var formData = new FormData();
// Files
var $fileSelect = $('#file-select');
if ($fileSelect.length > 0) {
var files = $fileSelect.get(0).files;
var filenames = [];
for (var i = 0; i < files.length; i++) { for (var i = 0; i < files.length; i++) {
var file = files[i]; var file = files[i];
filenames.push(file.name); filenames.push(file.name);
formData.append('file[]', file, file.name); formData.append('file[]', file, file.name);
} }
}
// Text message
var $text = $('#text');
if ($text.length > 0) {
formData.append("text", $text.val())
}
// Reset the upload form // Reset the upload form
$('#send').get(0).reset(); $('#send').get(0).reset();

View file

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>OnionShare</title> <title>OnionShare</title>
<meta charset="utf-8" /> <meta charset="utf-8" />
@ -7,6 +8,7 @@
<link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon"> <link href="{{ static_url_path }}/img/favicon.ico" rel="icon" type="image/x-icon">
<link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all"> <link rel="stylesheet" rel="subresource" type="text/css" href="{{ static_url_path }}/css/style.css" media="all">
</head> </head>
<body> <body>
<header class="clearfix"> <header class="clearfix">
@ -17,8 +19,18 @@
<div class="upload-wrapper"> <div class="upload-wrapper">
<p><img class="logo" src="{{ static_url_path }}/img/logo_large.png" title="OnionShare"></p> <p><img class="logo" src="{{ static_url_path }}/img/logo_large.png" title="OnionShare"></p>
<p class="upload-header">Send Files</p> {% if not disable_text and not disable_files %}
<p class="upload-description">Select the files you want to send, then click "Send Files"...</p> <p class="upload-header">Submit Files or Messages</p>
<p class="upload-description">You can submit files, a message, or both</p>
{% endif %}
{% if not disable_text and disable_files %}
<p class="upload-header">Submit Messages</p>
<p class="upload-description">You can submit a message</p>
{% endif %}
{% if disable_text and not disable_files %}
<p class="upload-header">Submit Files</p>
<p class="upload-description">You can submit files</p>
{% endif %}
<div id="uploads"></div> <div id="uploads"></div>
@ -35,12 +47,18 @@
</div> </div>
<form id="send" method="post" enctype="multipart/form-data" action="/upload"> <form id="send" method="post" enctype="multipart/form-data" action="/upload">
{% if not disable_files %}
<p><input type="file" id="file-select" name="file[]" multiple /></p> <p><input type="file" id="file-select" name="file[]" multiple /></p>
<p><button type="submit" id="send-button" class="button">Send Files</button></p> {% endif %}
{% if not disable_text %}
<p><textarea id="text" name="text" placeholder="Write a message"></textarea></p>
{% endif %}
<p><button type="submit" id="send-button" class="button">Submit</button></p>
</form> </form>
</div> </div>
<script src="{{ static_url_path }}/js/jquery-3.5.1.min.js"></script> <script src="{{ static_url_path }}/js/jquery-3.5.1.min.js"></script>
<script async src="{{ static_url_path }}/js/receive.js" id="receive-script"></script> <script async src="{{ static_url_path }}/js/receive.js" id="receive-script"></script>
</body> </body>
</html> </html>

View file

@ -64,7 +64,10 @@ class ReceiveModeWeb:
self.web.add_request(self.web.REQUEST_LOAD, request.path) self.web.add_request(self.web.REQUEST_LOAD, request.path)
r = make_response( r = make_response(
render_template( render_template(
"receive.html", static_url_path=self.web.static_url_path "receive.html",
static_url_path=self.web.static_url_path,
disable_text=self.web.settings.get("receive", "disable_text"),
disable_files=self.web.settings.get("receive", "disable_files"),
) )
) )
return self.web.add_security_headers(r) return self.web.add_security_headers(r)
@ -75,7 +78,42 @@ class ReceiveModeWeb:
Handle the upload files POST request, though at this point, the files have Handle the upload files POST request, though at this point, the files have
already been uploaded and saved to their correct locations. already been uploaded and saved to their correct locations.
""" """
text_received = False
if not self.web.settings.get("receive", "disable_text"):
text_message = request.form.get("text")
if text_message:
if text_message.strip() != "":
text_received = True
filename = "message.txt"
local_path = os.path.join(request.receive_mode_dir, filename)
with open(local_path, "w") as f:
f.write(text_message)
basename = os.path.basename(local_path)
# TODO: possibly change this
self.web.add_request(
self.web.REQUEST_UPLOAD_SET_DIR,
request.path,
{
"id": request.history_id,
"filename": basename,
"dir": request.receive_mode_dir,
},
)
self.common.log(
"ReceiveModeWeb",
"define_routes",
f"/upload, sent text message, saving to {local_path}",
)
print(f"\nReceived: {local_path}")
files_received = 0
if not self.web.settings.get("receive", "disable_files"):
files = request.files.getlist("file[]") files = request.files.getlist("file[]")
filenames = [] filenames = []
for f in files: for f in files:
if f.filename != "": if f.filename != "":
@ -102,17 +140,26 @@ class ReceiveModeWeb:
) )
print(f"\nReceived: {local_path}") print(f"\nReceived: {local_path}")
files_received = len(filenames)
# Send webhook if configured # Send webhook if configured
if ( if (
self.web.settings.get("receive", "webhook_url") self.web.settings.get("receive", "webhook_url") is not None
and not request.upload_error and not request.upload_error
and len(files) > 0 and (text_received or files_received)
): ):
if len(files) == 1: msg = ""
file_msg = "1 file" if files_received > 0:
if files_received == 1:
msg += "1 file"
else: else:
file_msg = f"{len(files)} files" msg += f"{files_received} files"
self.send_webhook_notification(f"{file_msg} uploaded to OnionShare") if text_received:
if msg == "":
msg = "A text message"
else:
msg += " and a text message"
self.send_webhook_notification(f"{msg} submitted to OnionShare")
if request.upload_error: if request.upload_error:
self.common.log( self.common.log(
@ -140,17 +187,23 @@ class ReceiveModeWeb:
if ajax: if ajax:
info_flashes = [] info_flashes = []
if len(filenames) == 0: if files_received > 0:
msg = "No files uploaded" files_msg = ""
if ajax:
info_flashes.append(msg)
else:
flash(msg, "info")
else:
msg = "Sent "
for filename in filenames: for filename in filenames:
msg += f"{filename}, " files_msg += f"{filename}, "
msg = msg.rstrip(", ") files_msg = files_msg.rstrip(", ")
if text_received:
if files_received > 0:
msg = f"Message submitted, uploaded {files_msg}"
else:
msg = "Message submitted"
else:
if files_received > 0:
msg = f"Uploaded {files_msg}"
else:
msg = "Nothing submitted"
if ajax: if ajax:
info_flashes.append(msg) info_flashes.append(msg)
else: else: