diff --git a/install/build_rpm.sh b/install/build_rpm.sh index 0872a447..22153c6d 100755 --- a/install/build_rpm.sh +++ b/install/build_rpm.sh @@ -9,7 +9,7 @@ VERSION=`cat share/version.txt` rm -r build dist >/dev/null 2>&1 # build binary package -python3 setup.py bdist_rpm --requires="python3-flask, python3-stem, python3-qt5, python3-crypto, python3-pysocks, nautilus-python, tor, obfs4" +python3 setup.py bdist_rpm --requires="python3-flask, python3-flask-httpauth, python3-stem, python3-qt5, python3-crypto, python3-pysocks, nautilus-python, tor, obfs4" # install it echo "" diff --git a/onionshare/web/receive_mode.py b/onionshare/web/receive_mode.py index bc805445..e7f3b3ae 100644 --- a/onionshare/web/receive_mode.py +++ b/onionshare/web/receive_mode.py @@ -18,6 +18,9 @@ class ReceiveModeWeb(object): self.web = web + # Reset assets path + self.web.app.static_folder=self.common.get_resource_path('static') + self.can_upload = True self.upload_count = 0 self.uploads_in_progress = [] diff --git a/onionshare/web/share_mode.py b/onionshare/web/share_mode.py index 560a8ba4..a0c8dc90 100644 --- a/onionshare/web/share_mode.py +++ b/onionshare/web/share_mode.py @@ -34,6 +34,10 @@ class ShareModeWeb(object): # one download at a time. self.download_in_progress = False + # Reset assets path + self.web.app.static_folder=self.common.get_resource_path('static') + + self.define_routes() def define_routes(self): diff --git a/onionshare/web/website_mode.py b/onionshare/web/website_mode.py index dd7be1d5..b9fe74e0 100644 --- a/onionshare/web/website_mode.py +++ b/onionshare/web/website_mode.py @@ -25,6 +25,9 @@ class WebsiteModeWeb(object): self.download_filesize = 0 self.visit_count = 0 + # Reset assets path + self.web.app.static_folder=self.common.get_resource_path('static') + self.users = { } self.define_routes() @@ -79,7 +82,15 @@ class WebsiteModeWeb(object): Render the onionshare website. """ - self.web.add_request(self.web.REQUEST_LOAD, request.path) + # Each download has a unique id + visit_id = self.visit_count + self.visit_count += 1 + + # Tell GUI the page has been visited + self.web.add_request(self.web.REQUEST_STARTED, page_path, { + 'id': visit_id, + 'action': 'visit' + }) filelist = [] if self.file_info['files']: @@ -102,6 +113,7 @@ class WebsiteModeWeb(object): for i in filelist: filenames.append(os.path.join(self.website_folder, i)) + self.web.app.static_folder=self.common.get_resource_path('static') self.set_file_info(filenames) r = make_response(render_template( diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index 34cd8306..51b36f9a 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -347,6 +347,7 @@ class VisitHistoryItem(HistoryItem): """ def __init__(self, common, id, total_bytes): super(VisitHistoryItem, self).__init__() + self.status = HistoryItem.STATUS_STARTED self.common = common self.id = id @@ -354,13 +355,20 @@ class VisitHistoryItem(HistoryItem): self.visited_dt = datetime.fromtimestamp(self.visited) # Label - self.label = QtWidgets.QLabel(strings._('gui_visit_started').format(self.started_dt.strftime("%b %d, %I:%M%p"))) + self.label = QtWidgets.QLabel(strings._('gui_visit_started').format(self.visited_dt.strftime("%b %d, %I:%M%p"))) # Layout layout = QtWidgets.QVBoxLayout() layout.addWidget(self.label) self.setLayout(layout) + 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 HistoryItemList(QtWidgets.QScrollArea): """ @@ -425,19 +433,19 @@ class HistoryItemList(QtWidgets.QScrollArea): Reset all items, emptying the list. Override this method. """ for key, item in self.items.copy().items(): - if item.status != HistoryItem.STATUS_STARTED: - self.items_layout.removeWidget(item) - item.close() - del self.items[key] + self.items_layout.removeWidget(item) + item.close() + del self.items[key] class History(QtWidgets.QWidget): """ A history of what's happened so far in this mode. This contains an internal object full of a scrollable list of items. """ - def __init__(self, common, empty_image, empty_text, header_text): + def __init__(self, common, empty_image, empty_text, header_text, mode=''): super(History, self).__init__() self.common = common + self.mode = mode self.setMinimumWidth(350) @@ -556,12 +564,14 @@ class History(QtWidgets.QWidget): """ Update the 'in progress' widget. """ - if self.in_progress_count == 0: - image = self.common.get_resource_path('images/share_in_progress_none.png') - else: - image = self.common.get_resource_path('images/share_in_progress.png') - self.in_progress_label.setText(' {1:d}'.format(image, self.in_progress_count)) - self.in_progress_label.setToolTip(strings._('history_in_progress_tooltip').format(self.in_progress_count)) + if self.mode != 'website': + if self.in_progress_count == 0: + image = self.common.get_resource_path('images/share_in_progress_none.png') + else: + image = self.common.get_resource_path('images/share_in_progress.png') + + self.in_progress_label.setText(' {1:d}'.format(image, self.in_progress_count)) + self.in_progress_label.setToolTip(strings._('history_in_progress_tooltip').format(self.in_progress_count)) class ToggleHistory(QtWidgets.QPushButton): diff --git a/onionshare_gui/mode/website_mode/__init__.py b/onionshare_gui/mode/website_mode/__init__.py index 156f578e..06212b02 100644 --- a/onionshare_gui/mode/website_mode/__init__.py +++ b/onionshare_gui/mode/website_mode/__init__.py @@ -18,6 +18,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ import os +import secrets +import random +import string + from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings @@ -41,9 +45,6 @@ class WebsiteMode(Mode): """ Custom initialization for ReceiveMode. """ - # Threads start out as None - self.compress_thread = None - # Create the Web object self.web = Web(self.common, True, 'website') @@ -76,8 +77,9 @@ class WebsiteMode(Mode): self.history = History( self.common, QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/share_icon_transparent.png'))), - strings._('gui_share_mode_no_files'), - strings._('gui_all_modes_history') + strings._('gui_website_mode_no_files'), + strings._('gui_all_modes_history'), + 'website' ) self.history.hide() @@ -88,8 +90,8 @@ class WebsiteMode(Mode): # Toggle history self.toggle_history = ToggleHistory( self.common, self, self.history, - QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle.png')), - QtGui.QIcon(self.common.get_resource_path('images/downloads_toggle_selected.png')) + QtGui.QIcon(self.common.get_resource_path('images/share_icon_toggle.png')), + QtGui.QIcon(self.common.get_resource_path('images/share_icon_toggle_selected.png')) ) # Top bar @@ -113,31 +115,27 @@ class WebsiteMode(Mode): # Wrapper layout self.wrapper_layout = QtWidgets.QHBoxLayout() self.wrapper_layout.addLayout(self.main_layout) - self.wrapper_layout.addWidget(self.history) + self.wrapper_layout.addWidget(self.history, stretch=1) self.setLayout(self.wrapper_layout) # Always start with focus on file selection self.file_selection.setFocus() - def get_stop_server_shutdown_timeout_text(self): + def get_stop_server_autostop_timer_text(self): """ - Return the string to put on the stop server button, if there's a shutdown timeout + Return the string to put on the stop server button, if there's an auto-stop timer """ - return strings._('gui_share_stop_server_shutdown_timeout') + return strings._('gui_share_stop_server_autostop_timer') - def timeout_finished_should_stop_server(self): + def autostop_timer_finished_should_stop_server(self): """ - The shutdown timer expired, should we stop the server? Returns a bool + The auto-stop timer expired, should we stop the server? Returns a bool """ - # If there were no attempts to download the share, or all downloads are done, we can stop - if self.web.website_mode.visit_count == 0 or self.web.done: - self.server_status.stop_server() - self.server_status_label.setText(strings._('close_on_timeout')) - return True - # A download is probably still running - hold off on stopping the share - else: - self.server_status_label.setText(strings._('timeout_download_still_running')) - return False + + self.server_status.stop_server() + self.server_status_label.setText(strings._('close_on_autostop_timer')) + return True + def start_server_custom(self): """ @@ -194,9 +192,7 @@ class WebsiteMode(Mode): """ self.filesize_warning.hide() - self.history.in_progress_count = 0 self.history.completed_count = 0 - self.history.update_in_progress() self.file_selection.file_list.adjustSize() def cancel_server_custom(self): @@ -222,14 +218,17 @@ class WebsiteMode(Mode): """ Handle REQUEST_STARTED event. """ + if ( (event["path"] == '') or (event["path"].find(".htm") != -1 ) ): + filesize = self.web.website_mode.download_filesize + item = VisitHistoryItem(self.common, event["data"]["id"], filesize) - filesize = self.web.website_mode.download_filesize + 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')) - item = VisitHistoryItem(self.common, event["data"]["id"], filesize) - 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 on_reload_settings(self): """ diff --git a/share/locale/en.json b/share/locale/en.json index de6639a6..0c26a9d5 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -157,6 +157,8 @@ "systray_share_canceled_message": "Someone canceled receiving your files", "systray_receive_started_title": "Receiving Started", "systray_receive_started_message": "Someone is sending files to you", + "systray_website_started_title": "Starting sharing website", + "systray_website_started_message": "Someone is visiting your website", "gui_all_modes_history": "History", "gui_all_modes_clear_history": "Clear All", "gui_all_modes_transfer_started": "Started {}", @@ -169,6 +171,7 @@ "gui_all_modes_progress_eta": "{0:s}, ETA: {1:s}, %p%", "gui_share_mode_no_files": "No Files Sent Yet", "gui_share_mode_autostop_timer_waiting": "Waiting to finish sending", + "gui_website_mode_no_files": "No Website Shared Yet", "gui_receive_mode_no_files": "No Files Received Yet", "gui_receive_mode_autostop_timer_waiting": "Waiting to finish receiving", "gui_visit_started": "Someone has visited your website {}", diff --git a/stdeb.cfg b/stdeb.cfg index 0adbac43..451520af 100644 --- a/stdeb.cfg +++ b/stdeb.cfg @@ -1,6 +1,6 @@ [DEFAULT] Package3: onionshare -Depends3: python3, python3-flask, python3-stem, python3-pyqt5, python3-crypto, python3-socks, python-nautilus, tor, obfs4proxy -Build-Depends: python3, python3-pytest, python3-flask, python3-stem, python3-pyqt5, python3-crypto, python3-socks, python3-requests, python-nautilus, tor, obfs4proxy +Depends3: python3, python3-flask, python3-flask-httpauth, python3-stem, python3-pyqt5, python3-crypto, python3-socks, python-nautilus, tor, obfs4proxy +Build-Depends: python3, python3-pytest, python3-flask, python3-flask-httpauth, python3-stem, python3-pyqt5, python3-crypto, python3-socks, python3-requests, python-nautilus, tor, obfs4proxy Suite: cosmic X-Python3-Version: >= 3.5.3