diff options
author | Micah Lee <micah@micahflee.com> | 2020-12-13 11:40:25 -0800 |
---|---|---|
committer | Micah Lee <micah@micahflee.com> | 2020-12-13 11:40:25 -0800 |
commit | b96b83905ba5b62c332a6c8946218ddae4c61517 (patch) | |
tree | f5a8fb5ade60583e12d07c657fde007c8ffe4ce0 /desktop | |
parent | ae621b4001dc44d7f07a9fad43376439b855ccd8 (diff) | |
parent | a520057bf4bd0956f03b763bfacdb8145cb5f977 (diff) | |
download | onionshare-b96b83905ba5b62c332a6c8946218ddae4c61517.tar.gz onionshare-b96b83905ba5b62c332a6c8946218ddae4c61517.zip |
Merge branch 'develop' into 929_download_errors
Diffstat (limited to 'desktop')
-rw-r--r-- | desktop/README.md | 31 | ||||
-rw-r--r-- | desktop/scripts/dev.bat | 3 | ||||
-rwxr-xr-x | desktop/scripts/dev.sh | 9 | ||||
-rwxr-xr-x | desktop/scripts/rebuild-cli.py | 45 | ||||
-rw-r--r-- | desktop/src/onionshare/gui_common.py | 53 | ||||
-rw-r--r-- | desktop/src/onionshare/resources/locale/en.json | 3 | ||||
-rw-r--r-- | desktop/src/onionshare/settings_dialog.py | 40 | ||||
-rw-r--r-- | desktop/src/onionshare/tab/mode/__init__.py | 3 | ||||
-rw-r--r-- | desktop/src/onionshare/tab/tab.py | 14 | ||||
-rw-r--r-- | desktop/src/onionshare/threads.py | 14 | ||||
-rw-r--r-- | desktop/src/onionshare/tor_connection_dialog.py | 41 |
11 files changed, 218 insertions, 38 deletions
diff --git a/desktop/README.md b/desktop/README.md index 039124fe..97d0fd30 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -51,17 +51,7 @@ Download Tor Browser and extract the binaries: python scripts\get-tor-windows.py ``` -### Prepare the code - -In order to work with the desktop app, you'll need to build a wheel of the CLI package first, and copy it into the `desktop` folder: - -```sh -cd ../cli -poetry install -poetry build -cp dist/onionshare_cli-*.whl ../desktop -cd ../desktop -``` +### Prepare the virtual environment OnionShare uses [Briefcase](https://briefcase.readthedocs.io/en/latest/). @@ -86,19 +76,30 @@ While your virtual environment is active, install briefcase from pip. pip install briefcase ``` -Run OnionShare from the source tree like this (`-d` re-installs dependencies, which you'll have to do each time you update the `onionshare-cli` wheel): +In order to work with the desktop app, you'll need to build a wheel of the CLI package first, and copy it into the `desktop` folder. You'll need to re-run this script each time you change the CLI code. + +```sh +python scripts/rebuild-cli.py +``` + +### Running OnionShare from the source code tree + +Inside the virtual environment, run OnionShare like this to install all of the dependencies: ``` briefcase dev -d ``` -If you want to pass arguments into `onionshare`, such as to use verbose mode: +Once you have the dependencies installed, you can run it using the `dev.sh` script, which lets you use command line arguments, such as to `--verbose` or `--local-only`: ``` -cd src -python -c "import onionshare; onionshare.main()" --help +./scripts/dev.sh --help +./scripts/dev.sh -v +./scripts/dev.sh -v --local-only ``` +Windows uses `scripts\dev.bat` instead. + ## Running tests Install these packages inside your virtual environment: diff --git a/desktop/scripts/dev.bat b/desktop/scripts/dev.bat new file mode 100644 index 00000000..9b537a90 --- /dev/null +++ b/desktop/scripts/dev.bat @@ -0,0 +1,3 @@ +cd src +python -c "import onionshare; onionshare.main()" %* +cd ..
\ No newline at end of file diff --git a/desktop/scripts/dev.sh b/desktop/scripts/dev.sh new file mode 100755 index 00000000..6ce5e796 --- /dev/null +++ b/desktop/scripts/dev.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Run OnionShare desktop, allowing you to use command-line arguments + +SCRIPTS_DIR="$( cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )" +cd $SCRIPTS_DIR + +cd ../src +python -c "import onionshare; onionshare.main()" $@
\ No newline at end of file diff --git a/desktop/scripts/rebuild-cli.py b/desktop/scripts/rebuild-cli.py new file mode 100755 index 00000000..c13461bc --- /dev/null +++ b/desktop/scripts/rebuild-cli.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +""" +This script builds the CLI python wheel, copies it to the desktop folder, +and installs it in the virtual environment. +""" + +import inspect +import os +import sys +import glob +import subprocess +import shutil + + +def main(): + # Build paths + root_path = os.path.dirname( + os.path.dirname( + os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + ) + ) + cli_path = os.path.join(root_path, "cli") + desktop_path = os.path.join(root_path, "desktop") + + # Delete old wheels + for filename in glob.glob(os.path.join(cli_path, "dist", "*.whl")): + os.remove(filename) + + # Build new wheel + subprocess.call(["poetry", "install"], cwd=cli_path) + subprocess.call(["poetry", "build"], cwd=cli_path) + wheel_filename = glob.glob(os.path.join(cli_path, "dist", "*.whl"))[0] + wheel_basename = os.path.basename(wheel_filename) + shutil.copyfile( + wheel_filename, + os.path.join(desktop_path, wheel_basename), + ) + + # Reinstall the new wheel + subprocess.call(["pip", "uninstall", "onionshare-cli", "-y"]) + subprocess.call(["pip", "install", os.path.join(desktop_path, wheel_basename)]) + + +if __name__ == "__main__": + main() diff --git a/desktop/src/onionshare/gui_common.py b/desktop/src/onionshare/gui_common.py index f488a740..7d367b99 100644 --- a/desktop/src/onionshare/gui_common.py +++ b/desktop/src/onionshare/gui_common.py @@ -24,7 +24,22 @@ import shutil from pkg_resources import resource_filename from . import strings -from onionshare_cli.onion import Onion +from onionshare_cli.onion import ( + Onion, + TorErrorInvalidSetting, + TorErrorAutomatic, + TorErrorSocketPort, + TorErrorSocketFile, + TorErrorMissingPassword, + TorErrorUnreadableCookieFile, + TorErrorAuthError, + TorErrorProtocolError, + BundledTorTimeout, + BundledTorBroken, + TorTooOldEphemeral, + TorTooOldStealth, + PortNotAvailable, +) class GuiCommon: @@ -245,7 +260,7 @@ class GuiCommon: QLabel { text-align: center; color: #333333; - font-size: 28px; + font-size: 25px; } """, # Share mode and child widget styles @@ -377,3 +392,37 @@ class GuiCommon: Returns the absolute path of a resource """ return resource_filename("onionshare", os.path.join("resources", filename)) + + @staticmethod + def get_translated_tor_error(e): + """ + Takes an exception defined in onion.py and returns a translated error message + """ + if type(e) is TorErrorInvalidSetting: + return strings._("settings_error_unknown") + elif type(e) is TorErrorAutomatic: + return strings._("settings_error_automatic") + elif type(e) is TorErrorSocketPort: + return strings._("settings_error_socket_port").format(e.args[0], e.args[1]) + elif type(e) is TorErrorSocketFile: + return strings._("settings_error_socket_file").format(e.args[0]) + elif type(e) is TorErrorMissingPassword: + return strings._("settings_error_missing_password") + elif type(e) is TorErrorUnreadableCookieFile: + return strings._("settings_error_unreadable_cookie_file") + elif type(e) is TorErrorAuthError: + return strings._("settings_error_auth").format(e.args[0], e.args[1]) + elif type(e) is TorErrorProtocolError: + return strings._("error_tor_protocol_error").format(e.args[0]) + elif type(e) is BundledTorTimeout: + return strings._("settings_error_bundled_tor_timeout") + elif type(e) is BundledTorBroken: + return strings._("settings_error_bundled_tor_broken").format(e.args[0]) + elif type(e) is TorTooOldEphemeral: + return strings._("error_ephemeral_not_supported") + elif type(e) is TorTooOldStealth: + return strings._("error_stealth_not_supported") + elif type(e) is PortNotAvailable: + return strings._("error_port_not_available") + + return None diff --git a/desktop/src/onionshare/resources/locale/en.json b/desktop/src/onionshare/resources/locale/en.json index 81984273..502fe13e 100644 --- a/desktop/src/onionshare/resources/locale/en.json +++ b/desktop/src/onionshare/resources/locale/en.json @@ -189,5 +189,6 @@ "settings_error_bundled_tor_timeout": "Taking too long to connect to Tor. Maybe you aren't connected to the Internet, or have an inaccurate system clock?", "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" + "gui_rendezvous_cleanup_quit_early": "Quit Early", + "error_port_not_available": "OnionShare port not available" }
\ No newline at end of file diff --git a/desktop/src/onionshare/settings_dialog.py b/desktop/src/onionshare/settings_dialog.py index 5f37bda1..974b7008 100644 --- a/desktop/src/onionshare/settings_dialog.py +++ b/desktop/src/onionshare/settings_dialog.py @@ -27,11 +27,31 @@ import os from onionshare_cli import common from onionshare_cli.settings import Settings -from onionshare_cli.onion import * +from onionshare_cli.onion import ( + Onion, + TorErrorInvalidSetting, + TorErrorAutomatic, + TorErrorSocketPort, + TorErrorSocketFile, + TorErrorMissingPassword, + TorErrorUnreadableCookieFile, + TorErrorAuthError, + TorErrorProtocolError, + BundledTorTimeout, + BundledTorBroken, + TorTooOldEphemeral, + TorTooOldStealth, + PortNotAvailable, +) from . import strings from .widgets import Alert -from .update_checker import * +from .update_checker import ( + UpdateCheckerCheckError, + UpdateCheckerInvalidLatestVersion, + UpdateChecker, + UpdateThread, +) from .tor_connection_dialog import TorConnectionDialog from .gui_common import GuiCommon @@ -142,7 +162,7 @@ class SettingsDialog(QtWidgets.QDialog): self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path, - ) = self.common.get_tor_paths() + ) = self.common.gui.get_tor_paths() if not self.obfs4proxy_file_path or not os.path.isfile( self.obfs4proxy_file_path ): @@ -165,7 +185,7 @@ class SettingsDialog(QtWidgets.QDialog): self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path, - ) = self.common.get_tor_paths() + ) = self.common.gui.get_tor_paths() if not self.obfs4proxy_file_path or not os.path.isfile( self.obfs4proxy_file_path ): @@ -698,10 +718,18 @@ class SettingsDialog(QtWidgets.QDialog): TorErrorUnreadableCookieFile, TorErrorAuthError, TorErrorProtocolError, - BundledTorNotSupported, BundledTorTimeout, + BundledTorBroken, + TorTooOldEphemeral, + TorTooOldStealth, + PortNotAvailable, ) as e: - Alert(self.common, e.args[0], QtWidgets.QMessageBox.Warning) + message = self.common.gui.get_translated_tor_error(e) + Alert( + self.common, + message, + QtWidgets.QMessageBox.Warning, + ) if settings.get("connection_type") == "bundled": self.tor_status.hide() self._enable_buttons() diff --git a/desktop/src/onionshare/tab/mode/__init__.py b/desktop/src/onionshare/tab/mode/__init__.py index 7738f567..0bef7628 100644 --- a/desktop/src/onionshare/tab/mode/__init__.py +++ b/desktop/src/onionshare/tab/mode/__init__.py @@ -183,8 +183,7 @@ class Mode(QtWidgets.QWidget): self.status_bar.clearMessage() if not self.app.autostop_timer_thread.is_alive(): - if self.autostop_timer_finished_should_stop_server(): - self.server_status.stop_server() + self.autostop_timer_finished_should_stop_server() def timer_callback_custom(self): """ diff --git a/desktop/src/onionshare/tab/tab.py b/desktop/src/onionshare/tab/tab.py index f474b9ba..8cbddfed 100644 --- a/desktop/src/onionshare/tab/tab.py +++ b/desktop/src/onionshare/tab/tab.py @@ -53,16 +53,22 @@ class NewTabButton(QtWidgets.QPushButton): ) self.image_label.setAlignment(QtCore.Qt.AlignCenter) self.image_label.setStyleSheet(self.common.gui.css["new_tab_button_image"]) - self.image_label.setGeometry(0, 0, self.width(), 200) + self.image_label.setGeometry(0, 0, self.width(), 190) self.image_label.show() # Title self.title_label = QtWidgets.QLabel(title, parent=self) + self.title_label.setWordWrap(True) self.title_label.setAlignment(QtCore.Qt.AlignCenter) self.title_label.setStyleSheet(self.common.gui.css["new_tab_title_text"]) - self.title_label.setGeometry( - (self.width() - 250) / 2, self.height() - 100, 250, 30 - ) + if self.title_label.sizeHint().width() >= 250: + self.title_label.setGeometry( + (self.width() - 250) / 2, self.height() - 120, 250, 60 + ) + else: + self.title_label.setGeometry( + (self.width() - 250) / 2, self.height() - 100, 250, 30 + ) self.title_label.show() # Text diff --git a/desktop/src/onionshare/threads.py b/desktop/src/onionshare/threads.py index 22e264e5..0c31a838 100644 --- a/desktop/src/onionshare/threads.py +++ b/desktop/src/onionshare/threads.py @@ -24,7 +24,6 @@ import os from PySide2 import QtCore from onionshare_cli.onion import ( - TorTooOld, TorErrorInvalidSetting, TorErrorAutomatic, TorErrorSocketPort, @@ -34,6 +33,10 @@ from onionshare_cli.onion import ( TorErrorAuthError, TorErrorProtocolError, BundledTorTimeout, + BundledTorBroken, + TorTooOldEphemeral, + TorTooOldStealth, + PortNotAvailable, ) from . import strings @@ -93,7 +96,6 @@ class OnionThread(QtCore.QThread): self.success.emit() except ( - TorTooOld, TorErrorInvalidSetting, TorErrorAutomatic, TorErrorSocketPort, @@ -103,9 +105,13 @@ class OnionThread(QtCore.QThread): TorErrorAuthError, TorErrorProtocolError, BundledTorTimeout, - OSError, + BundledTorBroken, + TorTooOldEphemeral, + TorTooOldStealth, + PortNotAvailable, ) as e: - self.error.emit(e.args[0]) + message = self.mode.common.gui.get_translated_tor_error(e) + self.error.emit(message) return diff --git a/desktop/src/onionshare/tor_connection_dialog.py b/desktop/src/onionshare/tor_connection_dialog.py index d5fa72a0..a9201aed 100644 --- a/desktop/src/onionshare/tor_connection_dialog.py +++ b/desktop/src/onionshare/tor_connection_dialog.py @@ -18,9 +18,25 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """ +import time from PySide2 import QtCore, QtWidgets, QtGui -from onionshare_cli.onion import * +from onionshare_cli.onion import ( + BundledTorCanceled, + TorErrorInvalidSetting, + TorErrorAutomatic, + TorErrorSocketPort, + TorErrorSocketFile, + TorErrorMissingPassword, + TorErrorUnreadableCookieFile, + TorErrorAuthError, + TorErrorProtocolError, + BundledTorTimeout, + BundledTorBroken, + TorTooOldEphemeral, + TorTooOldStealth, + PortNotAvailable, +) from . import strings from .gui_common import GuiCommon @@ -156,9 +172,26 @@ class TorConnectionThread(QtCore.QThread): ) self.canceled_connecting_to_tor.emit() - except Exception as e: - self.common.log("TorConnectionThread", "run", f"caught exception: {e}") - self.error_connecting_to_tor.emit(str(e)) + except ( + TorErrorInvalidSetting, + TorErrorAutomatic, + TorErrorSocketPort, + TorErrorSocketFile, + TorErrorMissingPassword, + TorErrorUnreadableCookieFile, + TorErrorAuthError, + TorErrorProtocolError, + BundledTorTimeout, + BundledTorBroken, + TorTooOldEphemeral, + TorTooOldStealth, + PortNotAvailable, + ) as e: + message = self.common.gui.get_translated_tor_error(e) + self.common.log( + "TorConnectionThread", "run", f"caught exception: {message}" + ) + self.error_connecting_to_tor.emit(message) def _tor_status_update(self, progress, summary): self.tor_status_update.emit(progress, summary) |