diff --git a/onionshare/__init__.py b/onionshare/__init__.py index dad092ed..a96f2fca 100644 --- a/onionshare/__init__.py +++ b/onionshare/__init__.py @@ -257,7 +257,7 @@ def main(cwd=None): if app.autostop_timer > 0: # if the auto-stop timer was set and has run out, stop the server if not app.autostop_timer_thread.is_alive(): - if mode == 'share': + if mode == 'share' or (mode == 'website'): # If there were no attempts to download the share, or all downloads are done, we can stop if web.share_mode.download_count == 0 or web.done: print("Stopped because auto-stop timer ran out") diff --git a/onionshare/web/website_mode.py b/onionshare/web/website_mode.py index 7b8429ae..51137183 100644 --- a/onionshare/web/website_mode.py +++ b/onionshare/web/website_mode.py @@ -38,25 +38,29 @@ class WebsiteModeWeb(object): def get_pw(username): self.users['onionshare'] = self.web.slug - if self.common.settings.get('public_mode'): - return True # let the request through, no questions asked! - elif username in self.users: + if username in self.users: return self.users.get(username) else: return None + @self.web.app.before_request + def conditional_auth_check(): + if not self.common.settings.get('public_mode'): + @self.auth.login_required + def _check_login(): + return None + + return _check_login() + @self.web.app.route('/download/') - @self.auth.login_required def path_download(page_path): return path_download(page_path) @self.web.app.route('/') - @self.auth.login_required def path_public(page_path): return path_logic(page_path) @self.web.app.route("/") - @self.auth.login_required def index_public(): return path_logic('') diff --git a/onionshare_gui/mode/share_mode/file_selection.py b/onionshare_gui/mode/file_selection.py similarity index 99% rename from onionshare_gui/mode/share_mode/file_selection.py rename to onionshare_gui/mode/file_selection.py index 0d4229fe..a7af61f8 100644 --- a/onionshare_gui/mode/share_mode/file_selection.py +++ b/onionshare_gui/mode/file_selection.py @@ -22,7 +22,7 @@ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings -from ...widgets import Alert, AddFileDialog +from ..widgets import Alert, AddFileDialog class DropHereLabel(QtWidgets.QLabel): """ diff --git a/onionshare_gui/mode/share_mode/__init__.py b/onionshare_gui/mode/share_mode/__init__.py index 6cb50b2b..1ee40ca3 100644 --- a/onionshare_gui/mode/share_mode/__init__.py +++ b/onionshare_gui/mode/share_mode/__init__.py @@ -25,7 +25,7 @@ from onionshare.onion import * from onionshare.common import Common from onionshare.web import Web -from .file_selection import FileSelection +from ..file_selection import FileSelection from .threads import CompressThread from .. import Mode from ..history import History, ToggleHistory, ShareHistoryItem diff --git a/onionshare_gui/mode/website_mode/__init__.py b/onionshare_gui/mode/website_mode/__init__.py new file mode 100644 index 00000000..e10da8b9 --- /dev/null +++ b/onionshare_gui/mode/website_mode/__init__.py @@ -0,0 +1,323 @@ +# -*- coding: utf-8 -*- +""" +OnionShare | https://onionshare.org/ + +Copyright (C) 2014-2018 Micah Lee + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +import os +from PyQt5 import QtCore, QtWidgets, QtGui + +from onionshare import strings +from onionshare.onion import * +from onionshare.common import Common +from onionshare.web import Web + +from ..file_selection import FileSelection +from .. import Mode +from ..history import History, ToggleHistory, DownloadHistoryItem +from ...widgets import Alert + +class WebsiteMode(Mode): + """ + Parts of the main window UI for sharing files. + """ + success = QtCore.pyqtSignal() + error = QtCore.pyqtSignal(str) + + def init(self): + """ + Custom initialization for ReceiveMode. + """ + # Threads start out as None + self.compress_thread = None + + # Create the Web object + self.web = Web(self.common, True, 'website') + + # File selection + self.file_selection = FileSelection(self.common, self) + if self.filenames: + for filename in self.filenames: + self.file_selection.file_list.add_file(filename) + + # Server status + self.server_status.set_mode('website', self.file_selection) + self.server_status.server_started.connect(self.file_selection.server_started) + self.server_status.server_stopped.connect(self.file_selection.server_stopped) + self.server_status.server_stopped.connect(self.update_primary_action) + self.server_status.server_canceled.connect(self.file_selection.server_stopped) + self.server_status.server_canceled.connect(self.update_primary_action) + self.file_selection.file_list.files_updated.connect(self.server_status.update) + self.file_selection.file_list.files_updated.connect(self.update_primary_action) + # Tell server_status about web, then update + self.server_status.web = self.web + self.server_status.update() + + # Filesize warning + self.filesize_warning = QtWidgets.QLabel() + self.filesize_warning.setWordWrap(True) + self.filesize_warning.setStyleSheet(self.common.css['share_filesize_warning']) + self.filesize_warning.hide() + + # Download history + self.history = History( + self.common, + QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/downloads_transparent.png'))), + strings._('gui_no_downloads'), + strings._('gui_downloads') + ) + self.history.hide() + + # Info label + self.info_label = QtWidgets.QLabel() + self.info_label.hide() + + # 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')) + ) + + # Top bar + top_bar_layout = QtWidgets.QHBoxLayout() + top_bar_layout.addWidget(self.info_label) + top_bar_layout.addStretch() + top_bar_layout.addWidget(self.toggle_history) + + # Primary action layout + self.primary_action_layout.addWidget(self.filesize_warning) + self.primary_action.hide() + self.update_primary_action() + + # Main layout + self.main_layout = QtWidgets.QVBoxLayout() + self.main_layout.addLayout(top_bar_layout) + self.main_layout.addLayout(self.file_selection) + self.main_layout.addWidget(self.primary_action) + self.main_layout.addWidget(self.min_width_widget) + + # Wrapper layout + self.wrapper_layout = QtWidgets.QHBoxLayout() + self.wrapper_layout.addLayout(self.main_layout) + self.wrapper_layout.addWidget(self.history) + self.setLayout(self.wrapper_layout) + + # Always start with focus on file selection + self.file_selection.setFocus() + + def get_stop_server_shutdown_timeout_text(self): + """ + Return the string to put on the stop server button, if there's a shutdown timeout + """ + return strings._('gui_share_stop_server_shutdown_timeout') + + def timeout_finished_should_stop_server(self): + """ + The shutdown 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.download_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 + + def start_server_custom(self): + """ + Starting the server. + """ + # Reset web counters + self.web.website_mode.download_count = 0 + self.web.error404_count = 0 + + # Hide and reset the downloads if we have previously shared + self.reset_info_counters() + + def start_server_step2_custom(self): + """ + Step 2 in starting the server. Zipping up files. + """ + self.filenames = [] + for index in range(self.file_selection.file_list.count()): + self.filenames.append(self.file_selection.file_list.item(index).filename) + + # Continue + self.starting_server_step3.emit() + self.start_server_finished.emit() + + + def start_server_step3_custom(self): + """ + Step 3 in starting the server. Display large filesize + warning, if applicable. + """ + + # Warn about sending large files over Tor + if self.web.website_mode.download_filesize >= 157286400: # 150mb + self.filesize_warning.setText(strings._("large_filesize")) + self.filesize_warning.show() + + if self.web.website_mode.set_file_info(self.filenames): + self.success.emit() + else: + # Cancelled + pass + + def start_server_error_custom(self): + """ + Start server error. + """ + if self._zip_progress_bar is not None: + self.status_bar.removeWidget(self._zip_progress_bar) + self._zip_progress_bar = None + + def stop_server_custom(self): + """ + Stop server. + """ + + 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): + """ + Stop the compression thread on cancel + """ + if self.compress_thread: + self.common.log('WebsiteMode', 'cancel_server: quitting compress thread') + self.compress_thread.quit() + + def handle_tor_broke_custom(self): + """ + Connection to Tor broke. + """ + 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_download_page_loaded_message')) + + def handle_request_started(self, event): + """ + Handle REQUEST_STARTED event. + """ + + filesize = self.web.website_mode.download_filesize + + item = DownloadHistoryItem(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() + + self.system_tray.showMessage(strings._('systray_download_started_title'), strings._('systray_download_started_message')) + + def handle_request_progress(self, event): + """ + Handle REQUEST_PROGRESS event. + """ + self.history.update(event["data"]["id"], event["data"]["bytes"]) + + # Is the download complete? + if event["data"]["bytes"] == self.web.website_mode.filesize: + self.system_tray.showMessage(strings._('systray_download_completed_title'), strings._('systray_download_completed_message')) + + # 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() + + # Close on finish? + if self.common.settings.get('close_after_first_download'): + self.server_status.stop_server() + self.status_bar.clearMessage() + self.server_status_label.setText(strings._('closing_automatically')) + 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_canceled(self, event): + """ + Handle REQUEST_CANCELED event. + """ + self.history.cancel(event["data"]["id"]) + + # Update in progress count + self.history.in_progress_count -= 1 + self.history.update_in_progress() + self.system_tray.showMessage(strings._('systray_download_canceled_title'), strings._('systray_download_canceled_message')) + + def on_reload_settings(self): + """ + If there were some files listed for sharing, we should be ok to re-enable + the 'Start Sharing' button now. + """ + if self.server_status.file_selection.get_num_files() > 0: + self.primary_action.show() + self.info_label.show() + + def update_primary_action(self): + self.common.log('WebsiteMode', 'update_primary_action') + + # Show or hide primary action layout + file_count = self.file_selection.file_list.count() + if file_count > 0: + self.primary_action.show() + self.info_label.show() + + # Update the file count in the info label + total_size_bytes = 0 + for index in range(self.file_selection.file_list.count()): + item = self.file_selection.file_list.item(index) + total_size_bytes += item.size_bytes + total_size_readable = self.common.human_readable_filesize(total_size_bytes) + + if file_count > 1: + self.info_label.setText(strings._('gui_file_info').format(file_count, total_size_readable)) + else: + self.info_label.setText(strings._('gui_file_info_single').format(file_count, total_size_readable)) + + else: + self.primary_action.hide() + self.info_label.hide() + + def reset_info_counters(self): + """ + Set the info counters back to zero. + """ + self.history.reset() + + @staticmethod + def _compute_total_size(filenames): + total_size = 0 + for filename in filenames: + if os.path.isfile(filename): + total_size += os.path.getsize(filename) + if os.path.isdir(filename): + total_size += Common.dir_size(filename) + return total_size diff --git a/onionshare_gui/onionshare_gui.py b/onionshare_gui/onionshare_gui.py index 17839669..9fdf9395 100644 --- a/onionshare_gui/onionshare_gui.py +++ b/onionshare_gui/onionshare_gui.py @@ -25,6 +25,7 @@ from onionshare.web import Web from .mode.share_mode import ShareMode from .mode.receive_mode import ReceiveMode +from .mode.website_mode import WebsiteMode from .tor_connection_dialog import TorConnectionDialog from .settings_dialog import SettingsDialog @@ -39,6 +40,7 @@ class OnionShareGui(QtWidgets.QMainWindow): """ MODE_SHARE = 'share' MODE_RECEIVE = 'receive' + MODE_WEBSITE = 'website' def __init__(self, common, onion, qtapp, app, filenames, config=False, local_only=False): super(OnionShareGui, self).__init__() @@ -92,6 +94,9 @@ class OnionShareGui(QtWidgets.QMainWindow): self.receive_mode_button = QtWidgets.QPushButton(strings._('gui_mode_receive_button')); self.receive_mode_button.setFixedHeight(50) self.receive_mode_button.clicked.connect(self.receive_mode_clicked) + self.website_mode_button = QtWidgets.QPushButton(strings._('gui_mode_website_button')); + self.website_mode_button.setFixedHeight(50) + self.website_mode_button.clicked.connect(self.website_mode_clicked) self.settings_button = QtWidgets.QPushButton() self.settings_button.setDefault(False) self.settings_button.setFixedWidth(40) @@ -103,6 +108,7 @@ class OnionShareGui(QtWidgets.QMainWindow): mode_switcher_layout.setSpacing(0) mode_switcher_layout.addWidget(self.share_mode_button) mode_switcher_layout.addWidget(self.receive_mode_button) + mode_switcher_layout.addWidget(self.website_mode_button) mode_switcher_layout.addWidget(self.settings_button) # Server status indicator on the status bar @@ -154,6 +160,20 @@ class OnionShareGui(QtWidgets.QMainWindow): self.receive_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth) self.receive_mode.set_server_active.connect(self.set_server_active) + # Website mode + self.website_mode = WebsiteMode(self.common, qtapp, app, self.status_bar, self.server_status_label, self.system_tray, filenames) + self.website_mode.init() + self.website_mode.server_status.server_started.connect(self.update_server_status_indicator) + self.website_mode.server_status.server_stopped.connect(self.update_server_status_indicator) + self.website_mode.start_server_finished.connect(self.update_server_status_indicator) + self.website_mode.stop_server_finished.connect(self.update_server_status_indicator) + self.website_mode.stop_server_finished.connect(self.stop_server_finished) + self.website_mode.start_server_finished.connect(self.clear_message) + self.website_mode.server_status.button_clicked.connect(self.clear_message) + self.website_mode.server_status.url_copied.connect(self.copy_url) + self.website_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth) + self.website_mode.set_server_active.connect(self.set_server_active) + self.update_mode_switcher() self.update_server_status_indicator() @@ -162,6 +182,7 @@ class OnionShareGui(QtWidgets.QMainWindow): contents_layout.setContentsMargins(10, 0, 10, 0) contents_layout.addWidget(self.receive_mode) contents_layout.addWidget(self.share_mode) + contents_layout.addWidget(self.website_mode) layout = QtWidgets.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) @@ -199,15 +220,27 @@ class OnionShareGui(QtWidgets.QMainWindow): if self.mode == self.MODE_SHARE: self.share_mode_button.setStyleSheet(self.common.css['mode_switcher_selected_style']) self.receive_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) + self.website_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) self.receive_mode.hide() self.share_mode.show() + self.website_mode.hide() + elif self.mode == self.MODE_WEBSITE: + self.share_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) + self.receive_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) + self.website_mode_button.setStyleSheet(self.common.css['mode_switcher_selected_style']) + + self.receive_mode.hide() + self.share_mode.hide() + self.website_mode.show() else: self.share_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) self.receive_mode_button.setStyleSheet(self.common.css['mode_switcher_selected_style']) + self.website_mode_button.setStyleSheet(self.common.css['mode_switcher_unselected_style']) self.share_mode.hide() self.receive_mode.show() + self.website_mode.hide() self.update_server_status_indicator() @@ -223,6 +256,12 @@ class OnionShareGui(QtWidgets.QMainWindow): self.mode = self.MODE_RECEIVE self.update_mode_switcher() + def website_mode_clicked(self): + if self.mode != self.MODE_WEBSITE: + self.common.log('OnionShareGui', 'website_mode_clicked') + self.mode = self.MODE_WEBSITE + self.update_mode_switcher() + def update_server_status_indicator(self): # Set the status image if self.mode == self.MODE_SHARE: @@ -239,6 +278,17 @@ class OnionShareGui(QtWidgets.QMainWindow): elif self.share_mode.server_status.status == ServerStatus.STATUS_STARTED: self.server_status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.server_status_image_started)) self.server_status_label.setText(strings._('gui_status_indicator_share_started')) + elif self.mode == self.MODE_WEBSITE: + # Website mode + if self.website_mode.server_status.status == ServerStatus.STATUS_STOPPED: + self.server_status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.server_status_image_stopped)) + self.server_status_label.setText(strings._('gui_status_indicator_share_stopped')) + elif self.website_mode.server_status.status == ServerStatus.STATUS_WORKING: + self.server_status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.server_status_image_working)) + self.server_status_label.setText(strings._('gui_status_indicator_share_working')) + elif self.website_mode.server_status.status == ServerStatus.STATUS_STARTED: + self.server_status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.server_status_image_started)) + self.server_status_label.setText(strings._('gui_status_indicator_share_started')) else: # Receive mode if self.receive_mode.server_status.status == ServerStatus.STATUS_STOPPED: @@ -317,6 +367,7 @@ class OnionShareGui(QtWidgets.QMainWindow): self.timer.start(500) self.share_mode.on_reload_settings() self.receive_mode.on_reload_settings() + self.website_mode.on_reload_settings() self.status_bar.clearMessage() # If we switched off the auto-stop timer setting, ensure the widget is hidden. @@ -337,6 +388,7 @@ class OnionShareGui(QtWidgets.QMainWindow): # When settings close, refresh the server status UI self.share_mode.server_status.update() self.receive_mode.server_status.update() + self.website_mode.server_status.update() def check_for_updates(self): """ @@ -367,10 +419,13 @@ class OnionShareGui(QtWidgets.QMainWindow): self.share_mode.handle_tor_broke() self.receive_mode.handle_tor_broke() + self.website_mode.handle_tor_broke() # Process events from the web object if self.mode == self.MODE_SHARE: mode = self.share_mode + elif self.mode == self.MODE_WEBSITE: + mode = self.website_mode else: mode = self.receive_mode @@ -450,13 +505,20 @@ class OnionShareGui(QtWidgets.QMainWindow): if self.mode == self.MODE_SHARE: self.share_mode_button.show() self.receive_mode_button.hide() + self.website_mode_button.hide() + elif self.mode == self.MODE_WEBSITE: + self.share_mode_button.hide() + self.receive_mode_button.hide() + self.website_mode_button.show() else: self.share_mode_button.hide() self.receive_mode_button.show() + self.website_mode_button.hide() else: self.settings_button.show() self.share_mode_button.show() self.receive_mode_button.show() + self.website_mode_button.show() # Disable settings menu action when server is active self.settings_action.setEnabled(not active) @@ -466,6 +528,8 @@ class OnionShareGui(QtWidgets.QMainWindow): try: if self.mode == OnionShareGui.MODE_SHARE: server_status = self.share_mode.server_status + if self.mode == OnionShareGui.MODE_WEBSITE: + server_status = self.website_mode.server_status else: server_status = self.receive_mode.server_status if server_status.status != server_status.STATUS_STOPPED: diff --git a/onionshare_gui/server_status.py b/onionshare_gui/server_status.py index 0c51119e..755904ea 100644 --- a/onionshare_gui/server_status.py +++ b/onionshare_gui/server_status.py @@ -39,6 +39,7 @@ class ServerStatus(QtWidgets.QWidget): MODE_SHARE = 'share' MODE_RECEIVE = 'receive' + MODE_WEBSITE = 'website' STATUS_STOPPED = 0 STATUS_WORKING = 1 @@ -159,7 +160,7 @@ class ServerStatus(QtWidgets.QWidget): """ self.mode = share_mode - if self.mode == ServerStatus.MODE_SHARE: + if (self.mode == ServerStatus.MODE_SHARE) or (self.mode == ServerStatus.MODE_WEBSITE): self.file_selection = file_selection self.update() @@ -207,6 +208,8 @@ class ServerStatus(QtWidgets.QWidget): if self.mode == ServerStatus.MODE_SHARE: self.url_description.setText(strings._('gui_share_url_description').format(info_image)) + elif self.mode == ServerStatus.MODE_WEBSITE: + self.url_description.setText(strings._('gui_share_url_description').format(info_image)) else: self.url_description.setText(strings._('gui_receive_url_description').format(info_image)) @@ -258,6 +261,8 @@ class ServerStatus(QtWidgets.QWidget): # Button if self.mode == ServerStatus.MODE_SHARE and self.file_selection.get_num_files() == 0: self.server_button.hide() + elif self.mode == ServerStatus.MODE_WEBSITE and self.file_selection.get_num_files() == 0: + self.server_button.hide() else: self.server_button.show() @@ -266,6 +271,8 @@ class ServerStatus(QtWidgets.QWidget): self.server_button.setEnabled(True) if self.mode == ServerStatus.MODE_SHARE: self.server_button.setText(strings._('gui_share_start_server')) + elif self.mode == ServerStatus.MODE_WEBSITE: + self.server_button.setText(strings._('gui_share_start_server')) else: self.server_button.setText(strings._('gui_receive_start_server')) self.server_button.setToolTip('') @@ -278,13 +285,27 @@ class ServerStatus(QtWidgets.QWidget): self.server_button.setEnabled(True) if self.mode == ServerStatus.MODE_SHARE: self.server_button.setText(strings._('gui_share_stop_server')) + if self.mode == ServerStatus.MODE_WEBSITE: + self.server_button.setText(strings._('gui_share_stop_server')) else: self.server_button.setText(strings._('gui_receive_stop_server')) +<<<<<<< HEAD if self.common.settings.get('autostart_timer'): self.autostart_timer_container.hide() if self.common.settings.get('autostop_timer'): self.autostop_timer_container.hide() self.server_button.setToolTip(strings._('gui_stop_server_autostop_timer_tooltip').format(self.autostop_timer_widget.dateTime().toString("h:mm AP, MMMM dd, yyyy"))) +======= + if self.common.settings.get('shutdown_timeout'): + self.shutdown_timeout_container.hide() + if self.mode == ServerStatus.MODE_SHARE: + self.server_button.setToolTip(strings._('gui_share_stop_server_shutdown_timeout_tooltip').format(self.timeout)) + if self.mode == ServerStatus.MODE_WEBSITE: + self.server_button.setToolTip(strings._('gui_share_stop_server_shutdown_timeout_tooltip').format(self.timeout)) + else: + self.server_button.setToolTip(strings._('gui_receive_stop_server_shutdown_timeout_tooltip').format(self.timeout)) + +>>>>>>> Add gui for website sharing and listing elif self.status == self.STATUS_WORKING: self.server_button.setStyleSheet(self.common.css['server_status_button_working']) self.server_button.setEnabled(True) @@ -411,6 +432,8 @@ class ServerStatus(QtWidgets.QWidget): """ if self.common.settings.get('public_mode'): url = 'http://{0:s}'.format(self.app.onion_host) + elif self.mode == ServerStatus.MODE_WEBSITE: + url = 'http://onionshare:{0:s}@{1:s}'.format(self.web.slug, self.app.onion_host) else: url = 'http://{0:s}/{1:s}'.format(self.app.onion_host, self.web.slug) return url diff --git a/setup.py b/setup.py index f482abb6..7d5d6620 100644 --- a/setup.py +++ b/setup.py @@ -89,6 +89,7 @@ setup( 'onionshare_gui.mode', 'onionshare_gui.mode.share_mode', 'onionshare_gui.mode.receive_mode' + 'onionshare_gui.mode.website_mode' ], include_package_data=True, scripts=['install/scripts/onionshare', 'install/scripts/onionshare-gui'], diff --git a/share/locale/en.json b/share/locale/en.json index 03e7ec1a..926f6f43 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -135,6 +135,7 @@ "gui_receive_mode_warning": "Receive mode lets people upload files to your computer.

Some files can potentially take control of your computer if you open them. Only open things from people you trust, or if you know what you are doing.", "gui_mode_share_button": "Share Files", "gui_mode_receive_button": "Receive Files", + "gui_mode_website_button": "Publish Website", "gui_settings_receiving_label": "Receiving settings", "gui_settings_data_dir_label": "Save files to", "gui_settings_data_dir_browse_button": "Browse",