summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMicah Lee <micah@micahflee.com>2021-04-30 17:16:02 -0700
committerMicah Lee <micah@micahflee.com>2021-04-30 17:16:02 -0700
commit17966471aba795cd3ac2ce8004417ab51c50b942 (patch)
tree12881404f6e73a740a4699e42613fa0a6027e6ff
parent89bed3c5ac02b2a4b0324fd0e68aaf4756ae8a35 (diff)
downloadonionshare-17966471aba795cd3ac2ce8004417ab51c50b942.tar.gz
onionshare-17966471aba795cd3ac2ce8004417ab51c50b942.zip
GUI displays "Read Message" button when a receive mode submission includes a message
-rw-r--r--cli/onionshare_cli/web/receive_mode.py90
-rw-r--r--cli/onionshare_cli/web/web.py21
-rw-r--r--desktop/src/onionshare/gui_common.py4
-rw-r--r--desktop/src/onionshare/resources/images/open_message.pngbin0 -> 5403 bytes
-rw-r--r--desktop/src/onionshare/resources/locale/en.json3
-rw-r--r--desktop/src/onionshare/tab/mode/__init__.py6
-rw-r--r--desktop/src/onionshare/tab/mode/history.py88
-rw-r--r--desktop/src/onionshare/tab/mode/receive_mode/__init__.py26
-rw-r--r--desktop/src/onionshare/tab/tab.py3
9 files changed, 178 insertions, 63 deletions
diff --git a/cli/onionshare_cli/web/receive_mode.py b/cli/onionshare_cli/web/receive_mode.py
index bdbe0a5f..a12f5456 100644
--- a/cli/onionshare_cli/web/receive_mode.py
+++ b/cli/onionshare_cli/web/receive_mode.py
@@ -99,7 +99,7 @@ class ReceiveModeWeb:
Handle the upload files POST request, though at this point, the files have
already been uploaded and saved to their correct locations.
"""
- text_received = request.includes_text
+ message_received = request.includes_message
files_received = 0
if not self.web.settings.get("receive", "disable_files"):
@@ -137,7 +137,7 @@ class ReceiveModeWeb:
if (
self.web.settings.get("receive", "webhook_url") is not None
and not request.upload_error
- and (text_received or files_received)
+ and (message_received or files_received)
):
msg = ""
if files_received > 0:
@@ -145,7 +145,7 @@ class ReceiveModeWeb:
msg += "1 file"
else:
msg += f"{files_received} files"
- if text_received:
+ if message_received:
if msg == "":
msg = "A text message"
else:
@@ -184,7 +184,7 @@ class ReceiveModeWeb:
files_msg += f"{filename}, "
files_msg = files_msg.rstrip(", ")
- if text_received:
+ if message_received:
if files_received > 0:
msg = f"Message submitted, uploaded {files_msg}"
else:
@@ -358,6 +358,7 @@ class ReceiveModeRequest(Request):
super(ReceiveModeRequest, self).__init__(environ, populate_request, shallow)
self.web = environ["web"]
self.stop_q = environ["stop_q"]
+ self.filename = None
# Prevent running the close() method more than once
self.closed = False
@@ -458,12 +459,13 @@ class ReceiveModeRequest(Request):
self.previous_file = None
# Is there a text message?
- self.includes_text = False
+ self.includes_message = False
if not self.web.settings.get("receive", "disable_text"):
text_message = self.form.get("text")
if text_message:
if text_message.strip() != "":
- self.includes_text = True
+ self.includes_message = True
+
with open(self.message_filename, "w") as f:
f.write(text_message)
@@ -472,16 +474,30 @@ class ReceiveModeRequest(Request):
"__init__",
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.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):
# Tell the GUI about the request
if not self.told_gui_about_request:
self.web.common.log(
"ReceiveModeRequest",
- "_get_file_stream",
+ "tell_gui_request_started",
"sending REQUEST_STARTED to GUI",
)
self.web.add_request(
@@ -490,8 +506,6 @@ class ReceiveModeRequest(Request):
{
"id": self.history_id,
"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)
@@ -536,31 +550,37 @@ class ReceiveModeRequest(Request):
if self.upload_request:
self.web.common.log("ReceiveModeRequest", "close")
- try:
- if self.told_gui_about_request:
- history_id = self.history_id
-
- if (
- not self.web.stop_q.empty()
- or not self.progress[self.filename]["complete"]
- ):
- # Inform the GUI that the upload has canceled
- self.web.add_request(
- self.web.REQUEST_UPLOAD_CANCELED,
- self.path,
- {"id": history_id},
- )
- else:
- # Inform the GUI that the upload has finished
- self.web.add_request(
- self.web.REQUEST_UPLOAD_FINISHED,
- self.path,
- {"id": history_id},
- )
- self.web.receive_mode.uploads_in_progress.remove(history_id)
-
- except AttributeError:
- pass
+ if self.told_gui_about_request:
+ history_id = self.history_id
+
+ if not self.web.stop_q.empty() or (
+ self.filename in self.progress
+ and not self.progress[self.filename]["complete"]
+ ):
+ # Inform the GUI that the upload has canceled
+ self.web.common.log(
+ "ReceiveModeRequest",
+ "close",
+ "sending REQUEST_UPLOAD_CANCELED to GUI",
+ )
+ self.web.add_request(
+ self.web.REQUEST_UPLOAD_CANCELED,
+ self.path,
+ {"id": history_id},
+ )
+ else:
+ # Inform the GUI that the upload has finished
+ self.web.common.log(
+ "ReceiveModeRequest",
+ "close",
+ "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 len(os.listdir(self.receive_mode_dir)) == 0:
diff --git a/cli/onionshare_cli/web/web.py b/cli/onionshare_cli/web/web.py
index e64943e6..da15c23b 100644
--- a/cli/onionshare_cli/web/web.py
+++ b/cli/onionshare_cli/web/web.py
@@ -64,16 +64,17 @@ class Web:
REQUEST_PROGRESS = 2
REQUEST_CANCELED = 3
REQUEST_RATE_LIMIT = 4
- REQUEST_UPLOAD_FILE_RENAMED = 5
- REQUEST_UPLOAD_SET_DIR = 6
- REQUEST_UPLOAD_FINISHED = 7
- REQUEST_UPLOAD_CANCELED = 8
- REQUEST_INDIVIDUAL_FILE_STARTED = 9
- REQUEST_INDIVIDUAL_FILE_PROGRESS = 10
- REQUEST_INDIVIDUAL_FILE_CANCELED = 11
- REQUEST_ERROR_DATA_DIR_CANNOT_CREATE = 12
- REQUEST_OTHER = 13
- REQUEST_INVALID_PASSWORD = 14
+ REQUEST_UPLOAD_INCLUDES_MESSAGE = 5
+ REQUEST_UPLOAD_FILE_RENAMED = 6
+ REQUEST_UPLOAD_SET_DIR = 7
+ REQUEST_UPLOAD_FINISHED = 8
+ REQUEST_UPLOAD_CANCELED = 9
+ REQUEST_INDIVIDUAL_FILE_STARTED = 10
+ REQUEST_INDIVIDUAL_FILE_PROGRESS = 11
+ REQUEST_INDIVIDUAL_FILE_CANCELED = 12
+ REQUEST_ERROR_DATA_DIR_CANNOT_CREATE = 13
+ REQUEST_OTHER = 14
+ REQUEST_INVALID_PASSWORD = 15
def __init__(self, common, is_gui, mode_settings, mode="share"):
self.common = common
diff --git a/desktop/src/onionshare/gui_common.py b/desktop/src/onionshare/gui_common.py
index 7703f7a8..1a44a128 100644
--- a/desktop/src/onionshare/gui_common.py
+++ b/desktop/src/onionshare/gui_common.py
@@ -353,6 +353,10 @@ class GuiCommon:
color: #666666;
font-size: 11px;
}""",
+ "receive_message_button": """
+ QPushButton {
+ padding: 5px 10px;
+ }""",
# Settings dialog
"settings_version": """
QLabel {
diff --git a/desktop/src/onionshare/resources/images/open_message.png b/desktop/src/onionshare/resources/images/open_message.png
new file mode 100644
index 00000000..6712ecf9
--- /dev/null
+++ b/desktop/src/onionshare/resources/images/open_message.png
Binary files differ
diff --git a/desktop/src/onionshare/resources/locale/en.json b/desktop/src/onionshare/resources/locale/en.json
index cbd898dc..9a6240a3 100644
--- a/desktop/src/onionshare/resources/locale/en.json
+++ b/desktop/src/onionshare/resources/locale/en.json
@@ -195,5 +195,6 @@
"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_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"
} \ No newline at end of file
diff --git a/desktop/src/onionshare/tab/mode/__init__.py b/desktop/src/onionshare/tab/mode/__init__.py
index fe7d6615..567dc123 100644
--- a/desktop/src/onionshare/tab/mode/__init__.py
+++ b/desktop/src/onionshare/tab/mode/__init__.py
@@ -447,6 +447,12 @@ class Mode(QtWidgets.QWidget):
"""
pass
+ def handle_request_upload_includes_message(self, event):
+ """
+ Handle REQUEST_UPLOAD_INCLUDES_MESSAGE event.
+ """
+ pass
+
def handle_request_upload_file_renamed(self, event):
"""
Handle REQUEST_UPLOAD_FILE_RENAMED event.
diff --git a/desktop/src/onionshare/tab/mode/history.py b/desktop/src/onionshare/tab/mode/history.py
index ffd96248..386d2e2e 100644
--- a/desktop/src/onionshare/tab/mode/history.py
+++ b/desktop/src/onionshare/tab/mode/history.py
@@ -268,6 +268,66 @@ class ReceiveHistoryItemFile(QtWidgets.QWidget):
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):
def __init__(self, common, id, content_length):
super(ReceiveHistoryItem, self).__init__()
@@ -301,6 +361,9 @@ class ReceiveHistoryItem(HistoryItem):
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
self.files_layout = QtWidgets.QVBoxLayout()
self.files_layout.setContentsMargins(0, 0, 0, 0)
@@ -311,6 +374,7 @@ class ReceiveHistoryItem(HistoryItem):
# Layout
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.label)
+ layout.addWidget(self.message)
layout.addWidget(self.progress_bar)
layout.addWidget(files_widget)
layout.addStretch()
@@ -319,17 +383,14 @@ class ReceiveHistoryItem(HistoryItem):
# We're also making a dictionary of file widgets, to make them easier to access
self.files = {}
+ def includes_message(self, message_filename):
+ self.message.set_filename(message_filename)
+
def update(self, data):
"""
Using the progress from Web, update the progress bar and file size labels
for each file
"""
- # self.common.log(
- # "ReceiveHistoryItem",
- # "update",
- # f"id={self.id} data[action]={data['action']} files={list(self.files)}",
- # )
-
if data["action"] == "progress":
total_uploaded_bytes = 0
for filename in data["progress"]:
@@ -572,6 +633,13 @@ class HistoryItemList(QtWidgets.QScrollArea):
if id in self.items:
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):
"""
Reset all items, emptying the list. Override this method.
@@ -665,7 +733,7 @@ class History(QtWidgets.QWidget):
"""
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
self.empty.hide()
@@ -686,6 +754,12 @@ class History(QtWidgets.QWidget):
"""
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):
"""
Reset all items.
diff --git a/desktop/src/onionshare/tab/mode/receive_mode/__init__.py b/desktop/src/onionshare/tab/mode/receive_mode/__init__.py
index 6056b1db..4dd2980c 100644
--- a/desktop/src/onionshare/tab/mode/receive_mode/__init__.py
+++ b/desktop/src/onionshare/tab/mode/receive_mode/__init__.py
@@ -78,27 +78,24 @@ class ReceiveMode(Mode):
data_dir_layout.addWidget(data_dir_button)
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 = QtWidgets.QCheckBox()
self.disable_text_checkbox.clicked.connect(self.disable_text_checkbox_clicked)
self.disable_text_checkbox.setText(
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 = QtWidgets.QCheckBox()
self.disable_files_checkbox.clicked.connect(self.disable_files_checkbox_clicked)
self.disable_files_checkbox.setText(
strings._("mode_settings_receive_disable_files_checkbox")
)
- self.mode_settings_widget.mode_specific_layout.addWidget(
- self.disable_files_checkbox
- )
+ disable_layout = QtWidgets.QHBoxLayout()
+ 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 = self.settings.get("receive", "webhook_url")
@@ -344,8 +341,11 @@ class ReceiveMode(Mode):
Handle REQUEST_STARTED event.
"""
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.toggle_history.update_indicator(True)
self.history.in_progress_count += 1
@@ -365,6 +365,12 @@ class ReceiveMode(Mode):
{"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):
"""
Handle REQUEST_UPLOAD_FILE_RENAMED event.
diff --git a/desktop/src/onionshare/tab/tab.py b/desktop/src/onionshare/tab/tab.py
index 2d4e164c..3d88ded5 100644
--- a/desktop/src/onionshare/tab/tab.py
+++ b/desktop/src/onionshare/tab/tab.py
@@ -540,6 +540,9 @@ class Tab(QtWidgets.QWidget):
elif event["type"] == Web.REQUEST_CANCELED:
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:
mode.handle_request_upload_file_renamed(event)