summaryrefslogtreecommitdiff
path: root/onionshare_gui
diff options
context:
space:
mode:
authorMicah Lee <micah@micahflee.com>2019-09-03 21:46:32 -0700
committerMicah Lee <micah@micahflee.com>2019-09-03 21:46:32 -0700
commit644b47082a716de9a7e2311b9f3c2a75c4d96fbe (patch)
treef3af6cf0eee7d8f1c7c071c67231851d9db10aea /onionshare_gui
parentc55925c1ce296ec8fe31bbe1b50c23133eda687a (diff)
downloadonionshare-644b47082a716de9a7e2311b9f3c2a75c4d96fbe.tar.gz
onionshare-644b47082a716de9a7e2311b9f3c2a75c4d96fbe.zip
Start making IndividualFileHistoryItem widgets appear in the history, and make non-GET requests return 405 Method Not Allowed
Diffstat (limited to 'onionshare_gui')
-rw-r--r--onionshare_gui/mode/__init__.py47
-rw-r--r--onionshare_gui/mode/history.py99
-rw-r--r--onionshare_gui/mode/share_mode/__init__.py15
-rw-r--r--onionshare_gui/mode/website_mode/__init__.py17
-rw-r--r--onionshare_gui/onionshare_gui.py11
5 files changed, 120 insertions, 69 deletions
diff --git a/onionshare_gui/mode/__init__.py b/onionshare_gui/mode/__init__.py
index e92e36f8..b5a95f41 100644
--- a/onionshare_gui/mode/__init__.py
+++ b/onionshare_gui/mode/__init__.py
@@ -22,6 +22,8 @@ from PyQt5 import QtCore, QtWidgets, QtGui
from onionshare import strings
from onionshare.common import AutoStopTimer
+from .history import IndividualFileHistoryItem
+
from ..server_status import ServerStatus
from ..threads import OnionThread
from ..threads import AutoStartTimer
@@ -29,7 +31,7 @@ from ..widgets import Alert
class Mode(QtWidgets.QWidget):
"""
- The class that ShareMode and ReceiveMode inherit from.
+ The class that all modes inherit from
"""
start_server_finished = QtCore.pyqtSignal()
stop_server_finished = QtCore.pyqtSignal()
@@ -417,3 +419,46 @@ class Mode(QtWidgets.QWidget):
Handle REQUEST_UPLOAD_CANCELED event.
"""
pass
+
+ def handle_request_individual_file_started(self, event):
+ """
+ Handle REQUEST_INDVIDIDUAL_FILES_STARTED event.
+ Used in both Share and Website modes, so implemented here.
+ """
+ item = IndividualFileHistoryItem(self.common, event["data"], event["path"])
+ self.history.add(event["data"]["id"], item)
+ self.toggle_history.update_indicator(True)
+ self.history.in_progress_count += 1
+ self.history.update_in_progress()
+
+ def handle_request_individual_file_progress(self, event):
+ """
+ Handle REQUEST_INDVIDIDUAL_FILES_PROGRESS event.
+ Used in both Share and Website modes, so implemented here.
+ """
+ self.history.update(event["data"]["id"], event["data"]["bytes"])
+
+ # Is the download complete?
+ if event["data"]["bytes"] == self.web.share_mode.filesize:
+ # Update completed and in progress labels
+ self.history.completed_count += 1
+ self.history.in_progress_count -= 1
+ self.history.update_completed()
+ self.history.update_in_progress()
+
+ else:
+ if self.server_status.status == self.server_status.STATUS_STOPPED:
+ self.history.cancel(event["data"]["id"])
+ self.history.in_progress_count = 0
+ self.history.update_in_progress()
+
+ def handle_request_individual_file_canceled(self, event):
+ """
+ Handle REQUEST_INDVIDIDUAL_FILES_CANCELED event.
+ Used in both Share and Website modes, so implemented here.
+ """
+ self.history.cancel(event["data"]["id"])
+
+ # Update in progress count
+ self.history.in_progress_count -= 1
+ self.history.update_in_progress()
diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py
index c2c696fc..a9fbbb36 100644
--- a/onionshare_gui/mode/history.py
+++ b/onionshare_gui/mode/history.py
@@ -345,62 +345,89 @@ class IndividualFileHistoryItem(HistoryItem):
"""
Individual file history item, for share mode viewing of individual files
"""
- def __init__(self, common, path):
+ def __init__(self, common, data, path):
super(IndividualFileHistoryItem, self).__init__()
self.status = HistoryItem.STATUS_STARTED
self.common = common
- self.visited = time.time()
- self.visited_dt = datetime.fromtimestamp(self.visited)
+ self.id = id
+ self.path = path
+ self.method = data['method']
+ self.total_bytes = data['filesize']
+ self.downloaded_bytes = 0
+ self.started = time.time()
+ self.started_dt = datetime.fromtimestamp(self.started)
+ self.status = HistoryItem.STATUS_STARTED
# Labels
- self.timestamp_label = QtWidgets.QLabel(self.visited_dt.strftime("%b %d, %I:%M%p"))
- self.path_viewed_label = QtWidgets.QLabel(strings._('gui_individual_file_download').format(path))
+ self.timestamp_label = QtWidgets.QLabel(self.started_dt.strftime("%b %d, %I:%M%p"))
+ self.method_label = QtWidgets.QLabel("{} {}".format(self.method, self.path))
+ self.status_label = QtWidgets.QLabel()
+
+ # Progress bar
+ self.progress_bar = QtWidgets.QProgressBar()
+ self.progress_bar.setTextVisible(True)
+ self.progress_bar.setAttribute(QtCore.Qt.WA_DeleteOnClose)
+ self.progress_bar.setAlignment(QtCore.Qt.AlignHCenter)
+ self.progress_bar.setMinimum(0)
+ self.progress_bar.setMaximum(data['filesize'])
+ self.progress_bar.setValue(0)
+ self.progress_bar.setStyleSheet(self.common.css['downloads_uploads_progress_bar'])
+ self.progress_bar.total_bytes = data['filesize']
+
+ # Text layout
+ labels_layout = QtWidgets.QHBoxLayout()
+ labels_layout.addWidget(self.timestamp_label)
+ labels_layout.addWidget(self.method_label)
+ labels_layout.addWidget(self.status_label)
# Layout
layout = QtWidgets.QVBoxLayout()
- layout.addWidget(self.timestamp_label)
- layout.addWidget(self.path_viewed_label)
+ layout.addLayout(labels_layout)
+ layout.addWidget(self.progress_bar)
self.setLayout(layout)
+ # All non-GET requests are error 405 Method Not Allowed
+ if self.method.lower() != 'get':
+ self.status_label.setText("405")
+ self.progress_bar.hide()
+ else:
+ # Start at 0
+ self.update(0)
- def update(self):
- self.label.setText(self.get_finished_label_text(self.started_dt))
- self.status = HistoryItem.STATUS_FINISHED
-
- def cancel(self):
- self.progress_bar.setFormat(strings._('gui_canceled'))
- self.status = HistoryItem.STATUS_CANCELED
-
-class VisitHistoryItem(HistoryItem):
- """
- Download history item, for share mode
- """
- def __init__(self, common, id, total_bytes):
- super(VisitHistoryItem, self).__init__()
- self.status = HistoryItem.STATUS_STARTED
- self.common = common
-
- self.id = id
- self.visited = time.time()
- self.visited_dt = datetime.fromtimestamp(self.visited)
+ def update(self, downloaded_bytes):
+ self.downloaded_bytes = downloaded_bytes
- # Label
- self.label = QtWidgets.QLabel(strings._('gui_visit_started').format(self.visited_dt.strftime("%b %d, %I:%M%p")))
+ self.progress_bar.setValue(downloaded_bytes)
+ if downloaded_bytes == self.progress_bar.total_bytes:
+ self.progress_bar.hide()
+ self.status = HistoryItem.STATUS_FINISHED
- # Layout
- layout = QtWidgets.QVBoxLayout()
- layout.addWidget(self.label)
- self.setLayout(layout)
+ else:
+ elapsed = time.time() - self.started
+ if elapsed < 10:
+ # Wait a couple of seconds for the download rate to stabilize.
+ # This prevents a "Windows copy dialog"-esque experience at
+ # the beginning of the download.
+ pb_fmt = strings._('gui_all_modes_progress_starting').format(
+ self.common.human_readable_filesize(downloaded_bytes))
+ else:
+ pb_fmt = strings._('gui_all_modes_progress_eta').format(
+ self.common.human_readable_filesize(downloaded_bytes),
+ self.estimated_time_remaining)
- def update(self):
- self.label.setText(self.get_finished_label_text(self.started_dt))
- self.status = HistoryItem.STATUS_FINISHED
+ self.progress_bar.setFormat(pb_fmt)
def cancel(self):
self.progress_bar.setFormat(strings._('gui_canceled'))
self.status = HistoryItem.STATUS_CANCELED
+ @property
+ def estimated_time_remaining(self):
+ return self.common.estimated_time_remaining(self.downloaded_bytes,
+ self.total_bytes,
+ self.started)
+
class HistoryItemList(QtWidgets.QScrollArea):
"""
List of items
diff --git a/onionshare_gui/mode/share_mode/__init__.py b/onionshare_gui/mode/share_mode/__init__.py
index 56aa1364..b5da0cd3 100644
--- a/onionshare_gui/mode/share_mode/__init__.py
+++ b/onionshare_gui/mode/share_mode/__init__.py
@@ -225,21 +225,6 @@ class ShareMode(Mode):
"""
self.primary_action.hide()
- def handle_request_load(self, event):
- """
- Handle REQUEST_LOAD event.
- """
- self.system_tray.showMessage(strings._('systray_page_loaded_title'), strings._('systray_page_loaded_message'))
- if not self.common.settings.get('close_after_first_download') and not event["path"].startswith(('/favicon.ico', '/download', self.web.static_url_path)) and event["path"] != '/':
-
- item = IndividualFileHistoryItem(self.common, event["path"])
-
- self.history.add(0, item)
- self.toggle_history.update_indicator(True)
- self.history.completed_count += 1
- self.history.update_completed()
- self.system_tray.showMessage(strings._('systray_individual_file_downloaded_title'), strings._('systray_individual_file_downloaded_message').format(event["path"]))
-
def handle_request_started(self, event):
"""
Handle REQUEST_STARTED event.
diff --git a/onionshare_gui/mode/website_mode/__init__.py b/onionshare_gui/mode/website_mode/__init__.py
index 8ac88c8c..3d4497f0 100644
--- a/onionshare_gui/mode/website_mode/__init__.py
+++ b/onionshare_gui/mode/website_mode/__init__.py
@@ -30,7 +30,7 @@ from onionshare.web import Web
from ..file_selection import FileSelection
from .. import Mode
-from ..history import History, ToggleHistory, VisitHistoryItem
+from ..history import History, ToggleHistory
from ...widgets import Alert
class WebsiteMode(Mode):
@@ -204,21 +204,6 @@ class WebsiteMode(Mode):
"""
self.system_tray.showMessage(strings._('systray_site_loaded_title'), strings._('systray_site_loaded_message'))
- def handle_request_started(self, event):
- """
- Handle REQUEST_STARTED event.
- """
- if ( (event["path"] == '') or (event["path"].find(".htm") != -1 ) ):
- item = VisitHistoryItem(self.common, event["data"]["id"], 0)
-
- self.history.add(event["data"]["id"], item)
- self.toggle_history.update_indicator(True)
- self.history.completed_count += 1
- self.history.update_completed()
-
- self.system_tray.showMessage(strings._('systray_website_started_title'), strings._('systray_website_started_message'))
-
-
def on_reload_settings(self):
"""
If there were some files listed for sharing, we should be ok to re-enable
diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py
index bed86895..20873bc8 100644
--- a/onionshare_gui/onionshare_gui.py
+++ b/onionshare_gui/onionshare_gui.py
@@ -383,7 +383,7 @@ class OnionShareGui(QtWidgets.QMainWindow):
self.share_mode.server_status.autostart_timer_container.hide()
self.receive_mode.server_status.autostart_timer_container.hide()
self.website_mode.server_status.autostart_timer_container.hide()
-
+
d = SettingsDialog(self.common, self.onion, self.qtapp, self.config, self.local_only)
d.settings_saved.connect(reload_settings)
d.exec_()
@@ -470,6 +470,15 @@ class OnionShareGui(QtWidgets.QMainWindow):
elif event["type"] == Web.REQUEST_UPLOAD_CANCELED:
mode.handle_request_upload_canceled(event)
+ elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_STARTED:
+ mode.handle_request_individual_file_started(event)
+
+ elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_PROGRESS:
+ mode.handle_request_individual_file_progress(event)
+
+ elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_CANCELED:
+ mode.handle_request_individual_file_canceled(event)
+
if event["type"] == Web.REQUEST_ERROR_DATA_DIR_CANNOT_CREATE:
Alert(self.common, strings._('error_cannot_create_data_dir').format(event["data"]["receive_mode_dir"]))