GUI displays "Read Message" button when a receive mode submission includes a message

This commit is contained in:
Micah Lee 2021-04-30 17:16:02 -07:00
parent 89bed3c5ac
commit 17966471ab
No known key found for this signature in database
GPG Key ID: 403C2657CD994F73
9 changed files with 177 additions and 62 deletions

View File

@ -99,7 +99,7 @@ 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 = request.includes_text message_received = request.includes_message
files_received = 0 files_received = 0
if not self.web.settings.get("receive", "disable_files"): if not self.web.settings.get("receive", "disable_files"):
@ -137,7 +137,7 @@ class ReceiveModeWeb:
if ( if (
self.web.settings.get("receive", "webhook_url") is not None self.web.settings.get("receive", "webhook_url") is not None
and not request.upload_error and not request.upload_error
and (text_received or files_received) and (message_received or files_received)
): ):
msg = "" msg = ""
if files_received > 0: if files_received > 0:
@ -145,7 +145,7 @@ class ReceiveModeWeb:
msg += "1 file" msg += "1 file"
else: else:
msg += f"{files_received} files" msg += f"{files_received} files"
if text_received: if message_received:
if msg == "": if msg == "":
msg = "A text message" msg = "A text message"
else: else:
@ -184,7 +184,7 @@ class ReceiveModeWeb:
files_msg += f"{filename}, " files_msg += f"{filename}, "
files_msg = files_msg.rstrip(", ") files_msg = files_msg.rstrip(", ")
if text_received: if message_received:
if files_received > 0: if files_received > 0:
msg = f"Message submitted, uploaded {files_msg}" msg = f"Message submitted, uploaded {files_msg}"
else: else:
@ -358,6 +358,7 @@ class ReceiveModeRequest(Request):
super(ReceiveModeRequest, self).__init__(environ, populate_request, shallow) super(ReceiveModeRequest, self).__init__(environ, populate_request, shallow)
self.web = environ["web"] self.web = environ["web"]
self.stop_q = environ["stop_q"] self.stop_q = environ["stop_q"]
self.filename = None
# Prevent running the close() method more than once # Prevent running the close() method more than once
self.closed = False self.closed = False
@ -458,12 +459,13 @@ class ReceiveModeRequest(Request):
self.previous_file = None self.previous_file = None
# Is there a text message? # Is there a text message?
self.includes_text = False self.includes_message = False
if not self.web.settings.get("receive", "disable_text"): if not self.web.settings.get("receive", "disable_text"):
text_message = self.form.get("text") text_message = self.form.get("text")
if text_message: if text_message:
if text_message.strip() != "": if text_message.strip() != "":
self.includes_text = True self.includes_message = True
with open(self.message_filename, "w") as f: with open(self.message_filename, "w") as f:
f.write(text_message) f.write(text_message)
@ -472,16 +474,30 @@ class ReceiveModeRequest(Request):
"__init__", "__init__",
f"saved message to {self.message_filename}", f"saved message to {self.message_filename}",
) )
print(f"\nReceived: {self.message_filename}") print(f"Received: {self.message_filename}")
# Tell the GUI about the message
self.tell_gui_request_started() self.tell_gui_request_started()
self.web.common.log(
"ReceiveModeRequest",
"__init__",
"sending REQUEST_UPLOAD_INCLUDES_MESSAGE to GUI",
)
self.web.add_request(
self.web.REQUEST_UPLOAD_INCLUDES_MESSAGE,
self.path,
{
"id": self.history_id,
"filename": self.message_filename,
},
)
def tell_gui_request_started(self): def tell_gui_request_started(self):
# Tell the GUI about the request # Tell the GUI about the request
if not self.told_gui_about_request: if not self.told_gui_about_request:
self.web.common.log( self.web.common.log(
"ReceiveModeRequest", "ReceiveModeRequest",
"_get_file_stream", "tell_gui_request_started",
"sending REQUEST_STARTED to GUI", "sending REQUEST_STARTED to GUI",
) )
self.web.add_request( self.web.add_request(
@ -490,8 +506,6 @@ class ReceiveModeRequest(Request):
{ {
"id": self.history_id, "id": self.history_id,
"content_length": self.content_length, "content_length": self.content_length,
"includes_text": self.includes_text,
"message_filename": self.message_filename,
}, },
) )
self.web.receive_mode.uploads_in_progress.append(self.history_id) self.web.receive_mode.uploads_in_progress.append(self.history_id)
@ -536,31 +550,37 @@ class ReceiveModeRequest(Request):
if self.upload_request: if self.upload_request:
self.web.common.log("ReceiveModeRequest", "close") self.web.common.log("ReceiveModeRequest", "close")
try: if self.told_gui_about_request:
if self.told_gui_about_request: history_id = self.history_id
history_id = self.history_id
if ( if not self.web.stop_q.empty() or (
not self.web.stop_q.empty() self.filename in self.progress
or not self.progress[self.filename]["complete"] and not self.progress[self.filename]["complete"]
): ):
# Inform the GUI that the upload has canceled # Inform the GUI that the upload has canceled
self.web.add_request( self.web.common.log(
self.web.REQUEST_UPLOAD_CANCELED, "ReceiveModeRequest",
self.path, "close",
{"id": history_id}, "sending REQUEST_UPLOAD_CANCELED to GUI",
) )
else: self.web.add_request(
# Inform the GUI that the upload has finished self.web.REQUEST_UPLOAD_CANCELED,
self.web.add_request( self.path,
self.web.REQUEST_UPLOAD_FINISHED, {"id": history_id},
self.path, )
{"id": history_id}, else:
) # Inform the GUI that the upload has finished
self.web.receive_mode.uploads_in_progress.remove(history_id) self.web.common.log(
"ReceiveModeRequest",
except AttributeError: "close",
pass "sending REQUEST_UPLOAD_FINISHED to GUI",
)
self.web.add_request(
self.web.REQUEST_UPLOAD_FINISHED,
self.path,
{"id": history_id},
)
self.web.receive_mode.uploads_in_progress.remove(history_id)
# If no files were written to self.receive_mode_dir, delete it # If no files were written to self.receive_mode_dir, delete it
if len(os.listdir(self.receive_mode_dir)) == 0: if len(os.listdir(self.receive_mode_dir)) == 0:

View File

@ -64,16 +64,17 @@ class Web:
REQUEST_PROGRESS = 2 REQUEST_PROGRESS = 2
REQUEST_CANCELED = 3 REQUEST_CANCELED = 3
REQUEST_RATE_LIMIT = 4 REQUEST_RATE_LIMIT = 4
REQUEST_UPLOAD_FILE_RENAMED = 5 REQUEST_UPLOAD_INCLUDES_MESSAGE = 5
REQUEST_UPLOAD_SET_DIR = 6 REQUEST_UPLOAD_FILE_RENAMED = 6
REQUEST_UPLOAD_FINISHED = 7 REQUEST_UPLOAD_SET_DIR = 7
REQUEST_UPLOAD_CANCELED = 8 REQUEST_UPLOAD_FINISHED = 8
REQUEST_INDIVIDUAL_FILE_STARTED = 9 REQUEST_UPLOAD_CANCELED = 9
REQUEST_INDIVIDUAL_FILE_PROGRESS = 10 REQUEST_INDIVIDUAL_FILE_STARTED = 10
REQUEST_INDIVIDUAL_FILE_CANCELED = 11 REQUEST_INDIVIDUAL_FILE_PROGRESS = 11
REQUEST_ERROR_DATA_DIR_CANNOT_CREATE = 12 REQUEST_INDIVIDUAL_FILE_CANCELED = 12
REQUEST_OTHER = 13 REQUEST_ERROR_DATA_DIR_CANNOT_CREATE = 13
REQUEST_INVALID_PASSWORD = 14 REQUEST_OTHER = 14
REQUEST_INVALID_PASSWORD = 15
def __init__(self, common, is_gui, mode_settings, mode="share"): def __init__(self, common, is_gui, mode_settings, mode="share"):
self.common = common self.common = common

View File

@ -353,6 +353,10 @@ class GuiCommon:
color: #666666; color: #666666;
font-size: 11px; font-size: 11px;
}""", }""",
"receive_message_button": """
QPushButton {
padding: 5px 10px;
}""",
# Settings dialog # Settings dialog
"settings_version": """ "settings_version": """
QLabel { QLabel {

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -195,5 +195,6 @@
"settings_error_bundled_tor_broken": "OnionShare could not connect to Tor:\n{}", "settings_error_bundled_tor_broken": "OnionShare could not connect to Tor:\n{}",
"gui_rendezvous_cleanup": "Waiting for Tor circuits to close to be sure your files have successfully transferred.\n\nThis might take a few minutes.", "gui_rendezvous_cleanup": "Waiting for Tor circuits to close to be sure your files have successfully transferred.\n\nThis might take a few minutes.",
"gui_rendezvous_cleanup_quit_early": "Quit Early", "gui_rendezvous_cleanup_quit_early": "Quit Early",
"error_port_not_available": "OnionShare port not available" "error_port_not_available": "OnionShare port not available",
"history_receive_read_message_button": "Read Message"
} }

View File

@ -447,6 +447,12 @@ class Mode(QtWidgets.QWidget):
""" """
pass pass
def handle_request_upload_includes_message(self, event):
"""
Handle REQUEST_UPLOAD_INCLUDES_MESSAGE event.
"""
pass
def handle_request_upload_file_renamed(self, event): def handle_request_upload_file_renamed(self, event):
""" """
Handle REQUEST_UPLOAD_FILE_RENAMED event. Handle REQUEST_UPLOAD_FILE_RENAMED event.

View File

@ -268,6 +268,66 @@ class ReceiveHistoryItemFile(QtWidgets.QWidget):
subprocess.Popen(["explorer", f"/select,{abs_filename}"]) subprocess.Popen(["explorer", f"/select,{abs_filename}"])
class ReceiveHistoryItemMessage(QtWidgets.QWidget):
def __init__(
self,
common,
):
super(ReceiveHistoryItemMessage, self).__init__()
self.common = common
self.filename = None
# Read message button
message_pixmap = QtGui.QPixmap.fromImage(
QtGui.QImage(GuiCommon.get_resource_path("images/open_message.png"))
)
message_icon = QtGui.QIcon(message_pixmap)
self.message_button = QtWidgets.QPushButton(
strings._("history_receive_read_message_button")
)
self.message_button.setStyleSheet(self.common.gui.css["receive_message_button"])
self.message_button.clicked.connect(self.open_message)
self.message_button.setIcon(message_icon)
self.message_button.setIconSize(message_pixmap.rect().size())
# Layouts
layout = QtWidgets.QHBoxLayout()
layout.addWidget(self.message_button)
layout.addStretch()
self.setLayout(layout)
self.hide()
def set_filename(self, new_filename):
self.filename = new_filename
self.show()
def open_message(self):
"""
Open the message in the operating system's default text editor
"""
self.common.log("ReceiveHistoryItemMessage", "open_message", self.filename)
# # Linux
# if self.common.platform == "Linux" or self.common.platform == "BSD":
# try:
# # If nautilus is available, open it
# subprocess.Popen(["xdg-open", self.dir])
# except Exception:
# Alert(
# self.common,
# strings._("gui_open_folder_error").format(abs_filename),
# )
# # macOS
# elif self.common.platform == "Darwin":
# subprocess.call(["open", "-R", abs_filename])
# # Windows
# elif self.common.platform == "Windows":
# subprocess.Popen(["explorer", f"/select,{abs_filename}"])
class ReceiveHistoryItem(HistoryItem): class ReceiveHistoryItem(HistoryItem):
def __init__(self, common, id, content_length): def __init__(self, common, id, content_length):
super(ReceiveHistoryItem, self).__init__() super(ReceiveHistoryItem, self).__init__()
@ -301,6 +361,9 @@ class ReceiveHistoryItem(HistoryItem):
self.common.gui.css["downloads_uploads_progress_bar"] self.common.gui.css["downloads_uploads_progress_bar"]
) )
# The message widget, if a message was included
self.message = ReceiveHistoryItemMessage(self.common)
# This layout contains file widgets # This layout contains file widgets
self.files_layout = QtWidgets.QVBoxLayout() self.files_layout = QtWidgets.QVBoxLayout()
self.files_layout.setContentsMargins(0, 0, 0, 0) self.files_layout.setContentsMargins(0, 0, 0, 0)
@ -311,6 +374,7 @@ class ReceiveHistoryItem(HistoryItem):
# Layout # Layout
layout = QtWidgets.QVBoxLayout() layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.label) layout.addWidget(self.label)
layout.addWidget(self.message)
layout.addWidget(self.progress_bar) layout.addWidget(self.progress_bar)
layout.addWidget(files_widget) layout.addWidget(files_widget)
layout.addStretch() layout.addStretch()
@ -319,17 +383,14 @@ class ReceiveHistoryItem(HistoryItem):
# We're also making a dictionary of file widgets, to make them easier to access # We're also making a dictionary of file widgets, to make them easier to access
self.files = {} self.files = {}
def includes_message(self, message_filename):
self.message.set_filename(message_filename)
def update(self, data): def update(self, data):
""" """
Using the progress from Web, update the progress bar and file size labels Using the progress from Web, update the progress bar and file size labels
for each file for each file
""" """
# self.common.log(
# "ReceiveHistoryItem",
# "update",
# f"id={self.id} data[action]={data['action']} files={list(self.files)}",
# )
if data["action"] == "progress": if data["action"] == "progress":
total_uploaded_bytes = 0 total_uploaded_bytes = 0
for filename in data["progress"]: for filename in data["progress"]:
@ -572,6 +633,13 @@ class HistoryItemList(QtWidgets.QScrollArea):
if id in self.items: if id in self.items:
self.items[id].cancel() self.items[id].cancel()
def includes_message(self, id, message_filename):
"""
Show message button for receive mode
"""
if id in self.items:
self.items[id].includes_message(message_filename)
def reset(self): def reset(self):
""" """
Reset all items, emptying the list. Override this method. Reset all items, emptying the list. Override this method.
@ -665,7 +733,7 @@ class History(QtWidgets.QWidget):
""" """
Add a new item. Add a new item.
""" """
self.common.log("History", "add", f"id: {id}, item: {item}") self.common.log("History", "add", f"id: {id}")
# Hide empty, show not empty # Hide empty, show not empty
self.empty.hide() self.empty.hide()
@ -686,6 +754,12 @@ class History(QtWidgets.QWidget):
""" """
self.item_list.cancel(id) self.item_list.cancel(id)
def includes_message(self, id, message_filename):
"""
Show the message button
"""
self.item_list.includes_message(id, message_filename)
def reset(self): def reset(self):
""" """
Reset all items. Reset all items.

View File

@ -78,27 +78,24 @@ class ReceiveMode(Mode):
data_dir_layout.addWidget(data_dir_button) data_dir_layout.addWidget(data_dir_button)
self.mode_settings_widget.mode_specific_layout.addLayout(data_dir_layout) self.mode_settings_widget.mode_specific_layout.addLayout(data_dir_layout)
# Disable text # Disable text or files
self.disable_text_checkbox = self.settings.get("receive", "disable_files") self.disable_text_checkbox = self.settings.get("receive", "disable_files")
self.disable_text_checkbox = QtWidgets.QCheckBox() self.disable_text_checkbox = QtWidgets.QCheckBox()
self.disable_text_checkbox.clicked.connect(self.disable_text_checkbox_clicked) self.disable_text_checkbox.clicked.connect(self.disable_text_checkbox_clicked)
self.disable_text_checkbox.setText( self.disable_text_checkbox.setText(
strings._("mode_settings_receive_disable_text_checkbox") strings._("mode_settings_receive_disable_text_checkbox")
) )
self.mode_settings_widget.mode_specific_layout.addWidget(
self.disable_text_checkbox
)
# Disable files
self.disable_files_checkbox = self.settings.get("receive", "disable_files") self.disable_files_checkbox = self.settings.get("receive", "disable_files")
self.disable_files_checkbox = QtWidgets.QCheckBox() self.disable_files_checkbox = QtWidgets.QCheckBox()
self.disable_files_checkbox.clicked.connect(self.disable_files_checkbox_clicked) self.disable_files_checkbox.clicked.connect(self.disable_files_checkbox_clicked)
self.disable_files_checkbox.setText( self.disable_files_checkbox.setText(
strings._("mode_settings_receive_disable_files_checkbox") strings._("mode_settings_receive_disable_files_checkbox")
) )
self.mode_settings_widget.mode_specific_layout.addWidget( disable_layout = QtWidgets.QHBoxLayout()
self.disable_files_checkbox disable_layout.addWidget(self.disable_text_checkbox)
) disable_layout.addWidget(self.disable_files_checkbox)
disable_layout.addStretch()
self.mode_settings_widget.mode_specific_layout.addLayout(disable_layout)
# Webhook URL # Webhook URL
webhook_url = self.settings.get("receive", "webhook_url") webhook_url = self.settings.get("receive", "webhook_url")
@ -344,8 +341,11 @@ class ReceiveMode(Mode):
Handle REQUEST_STARTED event. Handle REQUEST_STARTED event.
""" """
item = ReceiveHistoryItem( item = ReceiveHistoryItem(
self.common, event["data"]["id"], event["data"]["content_length"] self.common,
event["data"]["id"],
event["data"]["content_length"],
) )
self.history.add(event["data"]["id"], item) self.history.add(event["data"]["id"], item)
self.toggle_history.update_indicator(True) self.toggle_history.update_indicator(True)
self.history.in_progress_count += 1 self.history.in_progress_count += 1
@ -365,6 +365,12 @@ class ReceiveMode(Mode):
{"action": "progress", "progress": event["data"]["progress"]}, {"action": "progress", "progress": event["data"]["progress"]},
) )
def handle_request_upload_includes_message(self, event):
"""
Handle REQUEST_UPLOAD_INCLUDES_MESSAGE event.
"""
self.history.includes_message(event["data"]["id"], event["data"]["filename"])
def handle_request_upload_file_renamed(self, event): def handle_request_upload_file_renamed(self, event):
""" """
Handle REQUEST_UPLOAD_FILE_RENAMED event. Handle REQUEST_UPLOAD_FILE_RENAMED event.

View File

@ -540,6 +540,9 @@ class Tab(QtWidgets.QWidget):
elif event["type"] == Web.REQUEST_CANCELED: elif event["type"] == Web.REQUEST_CANCELED:
mode.handle_request_canceled(event) mode.handle_request_canceled(event)
elif event["type"] == Web.REQUEST_UPLOAD_INCLUDES_MESSAGE:
mode.handle_request_upload_includes_message(event)
elif event["type"] == Web.REQUEST_UPLOAD_FILE_RENAMED: elif event["type"] == Web.REQUEST_UPLOAD_FILE_RENAMED:
mode.handle_request_upload_file_renamed(event) mode.handle_request_upload_file_renamed(event)