diff options
53 files changed, 575 insertions, 284 deletions
diff --git a/cli/onionshare_cli/web/send_base_mode.py b/cli/onionshare_cli/web/send_base_mode.py index 9913996e..ad4459fe 100644 --- a/cli/onionshare_cli/web/send_base_mode.py +++ b/cli/onionshare_cli/web/send_base_mode.py @@ -24,6 +24,8 @@ import tempfile import mimetypes import gzip from flask import Response, request, render_template, make_response +from unidecode import unidecode +from werkzeug.urls import url_quote class SendBaseModeWeb: @@ -262,7 +264,11 @@ class SendBaseModeWeb: if use_gzip: r.headers.set("Content-Encoding", "gzip") r.headers.set("Content-Length", filesize) - r.headers.set("Content-Disposition", "inline", filename=basename) + filename_dict = { + 'filename': unidecode(basename), + 'filename*': "UTF-8''%s" % url_quote(basename) + } + r.headers.set("Content-Disposition", "inline", **filename_dict) r = self.web.add_security_headers(r) (content_type, _) = mimetypes.guess_type(basename, strict=False) if content_type is not None: diff --git a/cli/onionshare_cli/web/share_mode.py b/cli/onionshare_cli/web/share_mode.py index 87f35eaa..6d29eaff 100644 --- a/cli/onionshare_cli/web/share_mode.py +++ b/cli/onionshare_cli/web/share_mode.py @@ -24,6 +24,8 @@ import tempfile import zipfile import mimetypes from flask import Response, request, render_template, make_response +from unidecode import unidecode +from werkzeug.urls import url_quote from .send_base_mode import SendBaseModeWeb @@ -197,7 +199,11 @@ class ShareModeWeb(SendBaseModeWeb): if use_gzip: r.headers.set("Content-Encoding", "gzip") r.headers.set("Content-Length", self.filesize) - r.headers.set("Content-Disposition", "attachment", filename=basename) + filename_dict = { + 'filename': unidecode(basename), + 'filename*': "UTF-8''%s" % url_quote(basename) + } + r.headers.set("Content-Disposition", "inline", **filename_dict) r = self.web.add_security_headers(r) # guess content type (content_type, _) = mimetypes.guess_type(basename, strict=False) @@ -292,12 +298,8 @@ class ShareModeWeb(SendBaseModeWeb): info["size"] = self.common.dir_size(filename) info["size_human"] = self.common.human_readable_filesize(info["size"]) self.file_info["dirs"].append(info) - self.file_info["files"] = sorted( - self.file_info["files"], key=lambda k: k["basename"] - ) - self.file_info["dirs"] = sorted( - self.file_info["dirs"], key=lambda k: k["basename"] - ) + self.file_info["files"].sort(key=lambda k: k["basename"]) + self.file_info["dirs"].sort(key=lambda k: k["basename"]) # Check if there's only 1 file and no folders if len(self.file_info["files"]) == 1 and len(self.file_info["dirs"]) == 0: diff --git a/cli/onionshare_cli/web/web.py b/cli/onionshare_cli/web/web.py index 14d780c3..010df3eb 100644 --- a/cli/onionshare_cli/web/web.py +++ b/cli/onionshare_cli/web/web.py @@ -115,7 +115,7 @@ class Web: if self.mode == "receive": # Use custom WSGI middleware, to modify environ self.app.wsgi_app = ReceiveModeWSGIMiddleware(self.app.wsgi_app, self) - # Use a custom Request class to track upload progess + # Use a custom Request class to track upload progress self.app.request_class = ReceiveModeRequest # Starting in Flask 0.11, render_template_string autoescapes template variables diff --git a/cli/poetry.lock b/cli/poetry.lock index cdac8565..e1672272 100644 --- a/cli/poetry.lock +++ b/cli/poetry.lock @@ -1,76 +1,93 @@ [[package]] -name = "atomicwrites" -version = "1.4.0" -description = "Atomic file writes." category = "dev" +description = "Atomic file writes." +marker = "sys_platform == \"win32\"" +name = "atomicwrites" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.4.0" [[package]] -name = "attrs" -version = "20.3.0" -description = "Classes Without Boilerplate" category = "dev" +description = "Classes Without Boilerplate" +name = "attrs" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "20.3.0" [package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] +dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] docs = ["furo", "sphinx", "zope.interface"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] +tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] +tests_no_zope = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] [[package]] -name = "certifi" -version = "2020.11.8" -description = "Python package for providing Mozilla's CA Bundle." category = "main" +description = "The bidirectional mapping library for Python." +name = "bidict" optional = false -python-versions = "*" +python-versions = ">=3.6" +version = "0.21.2" + +[package.extras] +coverage = ["coverage (<6)", "pytest-cov (<3)"] +dev = ["setuptools-scm", "hypothesis (<6)", "py (<2)", "pytest (<7)", "pytest-benchmark (>=3.2.0,<4)", "sortedcollections (<2)", "sortedcontainers (<3)", "Sphinx (<4)", "sphinx-autodoc-typehints (<2)", "coverage (<6)", "pytest-cov (<3)", "pre-commit (<3)", "tox (<4)"] +docs = ["Sphinx (<4)", "sphinx-autodoc-typehints (<2)"] +precommit = ["pre-commit (<3)"] +test = ["hypothesis (<6)", "py (<2)", "pytest (<7)", "pytest-benchmark (>=3.2.0,<4)", "sortedcollections (<2)", "sortedcontainers (<3)", "Sphinx (<4)", "sphinx-autodoc-typehints (<2)"] [[package]] -name = "chardet" -version = "3.0.4" -description = "Universal encoding detector for Python 2 and 3" category = "main" +description = "Python package for providing Mozilla's CA Bundle." +name = "certifi" optional = false python-versions = "*" +version = "2020.12.5" [[package]] -name = "click" -version = "7.1.2" -description = "Composable command line interface toolkit" category = "main" +description = "Universal encoding detector for Python 2 and 3" +name = "chardet" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "4.0.0" + +[[package]] +category = "main" +description = "Composable command line interface toolkit" +name = "click" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "7.1.2" [[package]] -name = "colorama" -version = "0.4.4" -description = "Cross-platform colored terminal text." category = "dev" +description = "Cross-platform colored terminal text." +marker = "sys_platform == \"win32\"" +name = "colorama" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "0.4.4" [[package]] -name = "dnspython" -version = "1.16.0" -description = "DNS toolkit" category = "main" +description = "DNS toolkit" +name = "dnspython" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.16.0" [package.extras] DNSSEC = ["pycryptodome", "ecdsa (>=0.13)"] IDNA = ["idna (>=2.1)"] [[package]] -name = "eventlet" -version = "0.29.1" -description = "Highly concurrent networking library" category = "main" +description = "Highly concurrent networking library" +name = "eventlet" optional = false python-versions = "*" +version = "0.30.0" [package.dependencies] dnspython = ">=1.15.0,<2.0.0" @@ -78,18 +95,18 @@ greenlet = ">=0.3" six = ">=1.10.0" [[package]] -name = "flask" -version = "1.1.2" -description = "A simple framework for building complex web applications." category = "main" +description = "A simple framework for building complex web applications." +name = "flask" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "1.1.2" [package.dependencies] -click = ">=5.1" -itsdangerous = ">=0.24" Jinja2 = ">=2.10.1" Werkzeug = ">=0.15" +click = ">=5.1" +itsdangerous = ">=0.24" [package.extras] dev = ["pytest", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx-issues"] @@ -97,82 +114,90 @@ docs = ["sphinx", "pallets-sphinx-themes", "sphinxcontrib-log-cabinet", "sphinx- dotenv = ["python-dotenv"] [[package]] -name = "flask-httpauth" -version = "4.2.0" -description = "Basic and Digest HTTP authentication for Flask routes" category = "main" +description = "Basic and Digest HTTP authentication for Flask routes" +name = "flask-httpauth" optional = false python-versions = "*" +version = "4.2.0" [package.dependencies] Flask = "*" [[package]] -name = "flask-socketio" -version = "4.3.1" -description = "Socket.IO integration for Flask applications" category = "main" +description = "Socket.IO integration for Flask applications" +name = "flask-socketio" optional = false python-versions = "*" +version = "5.0.1" [package.dependencies] Flask = ">=0.9" -python-socketio = ">=4.3.0" +python-socketio = ">=5.0.2" [[package]] -name = "greenlet" -version = "0.4.17" -description = "Lightweight in-process concurrent programming" category = "main" +description = "Lightweight in-process concurrent programming" +name = "greenlet" optional = false -python-versions = "*" +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" +version = "1.0.0" + +[package.extras] +docs = ["sphinx"] [[package]] -name = "idna" -version = "2.10" -description = "Internationalized Domain Names in Applications (IDNA)" category = "main" +description = "Internationalized Domain Names in Applications (IDNA)" +name = "idna" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.10" [[package]] -name = "importlib-metadata" -version = "2.0.0" -description = "Read metadata from Python packages" category = "dev" +description = "Read metadata from Python packages" +marker = "python_version < \"3.8\"" +name = "importlib-metadata" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.6" +version = "3.4.0" [package.dependencies] zipp = ">=0.5" +[package.dependencies.typing-extensions] +python = "<3.8" +version = ">=3.6.4" + [package.extras] -docs = ["sphinx", "rst.linker"] -testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] +docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] -name = "iniconfig" -version = "1.1.1" -description = "iniconfig: brain-dead simple config-ini parsing" category = "dev" +description = "iniconfig: brain-dead simple config-ini parsing" +name = "iniconfig" optional = false python-versions = "*" +version = "1.1.1" [[package]] -name = "itsdangerous" -version = "1.1.0" -description = "Various helpers to pass data to untrusted environments and back." category = "main" +description = "Various helpers to pass data to untrusted environments and back." +name = "itsdangerous" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.1.0" [[package]] -name = "jinja2" -version = "2.11.2" -description = "A very fast and expressive template engine." category = "main" +description = "A very fast and expressive template engine." +name = "jinja2" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.11.2" [package.dependencies] MarkupSafe = ">=0.23" @@ -181,219 +206,236 @@ MarkupSafe = ">=0.23" i18n = ["Babel (>=0.8)"] [[package]] -name = "markupsafe" -version = "1.1.1" -description = "Safely add untrusted strings to HTML/XML markup." category = "main" +description = "Safely add untrusted strings to HTML/XML markup." +name = "markupsafe" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "1.1.1" [[package]] -name = "packaging" -version = "20.4" -description = "Core utilities for Python packages" category = "dev" +description = "Core utilities for Python packages" +name = "packaging" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "20.9" [package.dependencies] pyparsing = ">=2.0.2" -six = "*" [[package]] -name = "pluggy" -version = "0.13.1" -description = "plugin and hook calling mechanisms for python" category = "dev" +description = "plugin and hook calling mechanisms for python" +name = "pluggy" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "0.13.1" [package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" [package.extras] dev = ["pre-commit", "tox"] [[package]] -name = "psutil" -version = "5.7.3" -description = "Cross-platform lib for process and system monitoring in Python." category = "main" +description = "Cross-platform lib for process and system monitoring in Python." +name = "psutil" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "5.8.0" [package.extras] test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] [[package]] -name = "py" -version = "1.9.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" category = "dev" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "py" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.10.0" [[package]] -name = "pycryptodome" -version = "3.9.9" -description = "Cryptographic library for Python" category = "main" +description = "Cryptographic library for Python" +name = "pycryptodome" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.9.9" [[package]] -name = "pyparsing" -version = "2.4.7" -description = "Python parsing module" category = "dev" +description = "Python parsing module" +name = "pyparsing" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +version = "2.4.7" [[package]] -name = "pysocks" -version = "1.7.1" -description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." category = "main" +description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." +name = "pysocks" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.7.1" [[package]] -name = "pytest" -version = "6.1.2" -description = "pytest: simple powerful testing with Python" category = "dev" +description = "pytest: simple powerful testing with Python" +name = "pytest" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" +version = "6.2.2" [package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=17.4.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} +atomicwrites = ">=1.0" +attrs = ">=19.2.0" +colorama = "*" iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<1.0" +pluggy = ">=0.12,<1.0.0a1" py = ">=1.8.2" toml = "*" +[package.dependencies.importlib-metadata] +python = "<3.8" +version = ">=0.12" + [package.extras] -checkqa_mypy = ["mypy (==0.780)"] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] [[package]] -name = "python-engineio" -version = "3.13.2" -description = "Engine.IO server" category = "main" +description = "Engine.IO server" +name = "python-engineio" optional = false python-versions = "*" - -[package.dependencies] -six = ">=1.9.0" +version = "4.0.0" [package.extras] asyncio_client = ["aiohttp (>=3.4)"] client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] [[package]] -name = "python-socketio" -version = "4.6.0" -description = "Socket.IO server" category = "main" +description = "Socket.IO server" +name = "python-socketio" optional = false python-versions = "*" +version = "5.0.4" [package.dependencies] -python-engineio = ">=3.13.0" -six = ">=1.9.0" +bidict = ">=0.21.0" +python-engineio = ">=4" [package.extras] asyncio_client = ["aiohttp (>=3.4)", "websockets (>=7.0)"] client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"] [[package]] -name = "requests" -version = "2.25.0" -description = "Python HTTP for Humans." category = "main" +description = "Python HTTP for Humans." +name = "requests" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.25.1" [package.dependencies] certifi = ">=2017.4.17" -chardet = ">=3.0.2,<4" +chardet = ">=3.0.2,<5" idna = ">=2.5,<3" urllib3 = ">=1.21.1,<1.27" [package.extras] security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] -socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7)", "win-inet-pton"] [[package]] -name = "six" -version = "1.15.0" -description = "Python 2 and 3 compatibility utilities" category = "main" +description = "Python 2 and 3 compatibility utilities" +name = "six" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +version = "1.15.0" [[package]] -name = "stem" -version = "1.8.0" -description = "Stem is a Python controller library that allows applications to interact with Tor (https://www.torproject.org/)." category = "main" +description = "Stem is a Python controller library that allows applications to interact with Tor (https://www.torproject.org/)." +name = "stem" optional = false python-versions = "*" +version = "1.8.0" [[package]] +category = "dev" +description = "Python Library for Tom's Obvious, Minimal Language" name = "toml" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" + +[[package]] category = "dev" +description = "Backported and Experimental Type Hints for Python 3.5+" +marker = "python_version < \"3.8\"" +name = "typing-extensions" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = "*" +version = "3.7.4.3" + +[[package]] +category = "main" +description = "ASCII transliterations of Unicode text" +name = "unidecode" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.1.2" [[package]] -name = "urllib3" -version = "1.26.2" -description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" +description = "HTTP library with thread-safe connection pooling, file post, and more." +name = "urllib3" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +version = "1.26.3" [package.extras] brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +socks = ["PySocks (>=1.5.6,<1.5.7 || >1.5.7,<2.0)"] [[package]] -name = "werkzeug" -version = "1.0.1" -description = "The comprehensive WSGI web application library." category = "main" +description = "The comprehensive WSGI web application library." +name = "werkzeug" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "1.0.1" [package.extras] dev = ["pytest", "pytest-timeout", "coverage", "tox", "sphinx", "pallets-sphinx-themes", "sphinx-issues"] watchdog = ["watchdog"] [[package]] -name = "zipp" -version = "3.4.0" -description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" +description = "Backport of pathlib-compatible object wrapper for zip files" +marker = "python_version < \"3.8\"" +name = "zipp" optional = false python-versions = ">=3.6" +version = "3.4.0" [package.extras] docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] +testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "jaraco.test (>=3.2.0)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [metadata] -lock-version = "1.1" +content-hash = "f69ea4d5b4e409cfe082f8b14503967609add515991cc778b3f2ec4e311dcd1c" python-versions = "^3.6" -content-hash = "38f69a7cfa72b1da17d995e8c33dcceb0568ebfb065439927a5a007f3c8bd873" [metadata.files] atomicwrites = [ @@ -404,13 +446,17 @@ attrs = [ {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, ] +bidict = [ + {file = "bidict-0.21.2-py2.py3-none-any.whl", hash = "sha256:929d056e8d0d9b17ceda20ba5b24ac388e2a4d39802b87f9f4d3f45ecba070bf"}, + {file = "bidict-0.21.2.tar.gz", hash = "sha256:4fa46f7ff96dc244abfc437383d987404ae861df797e2fd5b190e233c302be09"}, +] certifi = [ - {file = "certifi-2020.11.8-py2.py3-none-any.whl", hash = "sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd"}, - {file = "certifi-2020.11.8.tar.gz", hash = "sha256:f05def092c44fbf25834a51509ef6e631dc19765ab8a57b4e7ab85531f0a9cf4"}, + {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, + {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, ] chardet = [ - {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, + {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, + {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, ] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, @@ -425,8 +471,8 @@ dnspython = [ {file = "dnspython-1.16.0.zip", hash = "sha256:36c5e8e38d4369a08b6780b7f27d790a292b2b08eea01607865bf0936c558e01"}, ] eventlet = [ - {file = "eventlet-0.29.1-py2.py3-none-any.whl", hash = "sha256:a07b8c8e1f43bc4c44a255baeb066a4edce783dcfacae213bcabb95fdcd02d8c"}, - {file = "eventlet-0.29.1.tar.gz", hash = "sha256:9faff63631b01277c463ae91cd4ab3f25a2f0f5abe3219d43a386ef1daa6159a"}, + {file = "eventlet-0.30.0-py2.py3-none-any.whl", hash = "sha256:b33f31ae8d87eb2838dcb8467449211852374ee6dea97113c158fc84d9acff9b"}, + {file = "eventlet-0.30.0.tar.gz", hash = "sha256:19d6f3aa9525221ba60d0ec31b570508021af7ad5497fb77f77501fe9a7c34d3"}, ] flask = [ {file = "Flask-1.1.2-py2.py3-none-any.whl", hash = "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"}, @@ -437,36 +483,61 @@ flask-httpauth = [ {file = "Flask_HTTPAuth-4.2.0-py2.py3-none-any.whl", hash = "sha256:3fcedb99a03985915335a38c35bfee6765cbd66d7f46440fa3b42ae94a90fac7"}, ] flask-socketio = [ - {file = "Flask-SocketIO-4.3.1.tar.gz", hash = "sha256:36c1d5765010d1f4e4f05b4cc9c20c289d9dc70698c88d1addd0afcfedc5b062"}, - {file = "Flask_SocketIO-4.3.1-py2.py3-none-any.whl", hash = "sha256:3668675bf7763c5b5f56689d439f07356e89c0a52e0c9e9cd3cc08563c07b252"}, + {file = "Flask-SocketIO-5.0.1.tar.gz", hash = "sha256:5c4319f5214ada20807857dc8fdf3dc7d2afe8d6dd38f5c516c72e2be47d2227"}, + {file = "Flask_SocketIO-5.0.1-py2.py3-none-any.whl", hash = "sha256:5d9a4438bafd806c5a3b832e74b69758781a8ee26fb6c9b1dbdda9b4fced432e"}, ] greenlet = [ - {file = "greenlet-0.4.17-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:75e4c27188f28149b74e7685809f9227410fd15432a4438fc48627f518577fa5"}, - {file = "greenlet-0.4.17-cp27-cp27m-win32.whl", hash = "sha256:3af587e9813f9bd8be9212722321a5e7be23b2bc37e6323a90e592ab0c2ef117"}, - {file = "greenlet-0.4.17-cp27-cp27m-win_amd64.whl", hash = "sha256:ccd62f09f90b2730150d82f2f2ffc34d73c6ce7eac234aed04d15dc8a3023994"}, - {file = "greenlet-0.4.17-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:13037e2d7ab2145300676852fa069235512fdeba4ed1e3bb4b0677a04223c525"}, - {file = "greenlet-0.4.17-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:e495096e3e2e8f7192afb6aaeba19babc4fb2bdf543d7b7fed59e00c1df7f170"}, - {file = "greenlet-0.4.17-cp35-cp35m-win32.whl", hash = "sha256:124a3ae41215f71dc91d1a3d45cbf2f84e46b543e5d60b99ecc20e24b4c8f272"}, - {file = "greenlet-0.4.17-cp35-cp35m-win_amd64.whl", hash = "sha256:5494e3baeacc371d988345fbf8aa4bd15555b3077c40afcf1994776bb6d77eaf"}, - {file = "greenlet-0.4.17-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bee111161420f341a346731279dd976be161b465c1286f82cc0779baf7b729e8"}, - {file = "greenlet-0.4.17-cp36-cp36m-win32.whl", hash = "sha256:ac85db59aa43d78547f95fc7b6fd2913e02b9e9b09e2490dfb7bbdf47b2a4914"}, - {file = "greenlet-0.4.17-cp36-cp36m-win_amd64.whl", hash = "sha256:4481002118b2f1588fa3d821936ffdc03db80ef21186b62b90c18db4ba5e743b"}, - {file = "greenlet-0.4.17-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:be7a79988b8fdc5bbbeaed69e79cfb373da9759242f1565668be4fb7f3f37552"}, - {file = "greenlet-0.4.17-cp37-cp37m-win32.whl", hash = "sha256:97f2b01ab622a4aa4b3724a3e1fba66f47f054c434fbaa551833fa2b41e3db51"}, - {file = "greenlet-0.4.17-cp37-cp37m-win_amd64.whl", hash = "sha256:d3436110ca66fe3981031cc6aff8cc7a40d8411d173dde73ddaa5b8445385e2d"}, - {file = "greenlet-0.4.17-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:a34023b9eabb3525ee059f3bf33a417d2e437f7f17e341d334987d4091ae6072"}, - {file = "greenlet-0.4.17-cp38-cp38-win32.whl", hash = "sha256:e66a824f44892bc4ec66c58601a413419cafa9cec895e63d8da889c8a1a4fa4a"}, - {file = "greenlet-0.4.17-cp38-cp38-win_amd64.whl", hash = "sha256:47825c3a109f0331b1e54c1173d4e57fa000aa6c96756b62852bfa1af91cd652"}, - {file = "greenlet-0.4.17-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:1023d7b43ca11264ab7052cb09f5635d4afdb43df55e0854498fc63070a0b206"}, - {file = "greenlet-0.4.17.tar.gz", hash = "sha256:41d8835c69a78de718e466dd0e6bfd4b46125f21a67c3ff6d76d8d8059868d6b"}, + {file = "greenlet-1.0.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:1d1d4473ecb1c1d31ce8fd8d91e4da1b1f64d425c1dc965edc4ed2a63cfa67b2"}, + {file = "greenlet-1.0.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:cfd06e0f0cc8db2a854137bd79154b61ecd940dce96fad0cba23fe31de0b793c"}, + {file = "greenlet-1.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:eb333b90036358a0e2c57373f72e7648d7207b76ef0bd00a4f7daad1f79f5203"}, + {file = "greenlet-1.0.0-cp27-cp27m-win32.whl", hash = "sha256:1a1ada42a1fd2607d232ae11a7b3195735edaa49ea787a6d9e6a53afaf6f3476"}, + {file = "greenlet-1.0.0-cp27-cp27m-win_amd64.whl", hash = "sha256:f6f65bf54215e4ebf6b01e4bb94c49180a589573df643735107056f7a910275b"}, + {file = "greenlet-1.0.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:f59eded163d9752fd49978e0bab7a1ff21b1b8d25c05f0995d140cc08ac83379"}, + {file = "greenlet-1.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:875d4c60a6299f55df1c3bb870ebe6dcb7db28c165ab9ea6cdc5d5af36bb33ce"}, + {file = "greenlet-1.0.0-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:1bb80c71de788b36cefb0c3bb6bfab306ba75073dbde2829c858dc3ad70f867c"}, + {file = "greenlet-1.0.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b5f1b333015d53d4b381745f5de842f19fe59728b65f0fbb662dafbe2018c3a5"}, + {file = "greenlet-1.0.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:5352c15c1d91d22902582e891f27728d8dac3bd5e0ee565b6a9f575355e6d92f"}, + {file = "greenlet-1.0.0-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:2c65320774a8cd5fdb6e117c13afa91c4707548282464a18cf80243cf976b3e6"}, + {file = "greenlet-1.0.0-cp35-cp35m-manylinux2014_ppc64le.whl", hash = "sha256:111cfd92d78f2af0bc7317452bd93a477128af6327332ebf3c2be7df99566683"}, + {file = "greenlet-1.0.0-cp35-cp35m-win32.whl", hash = "sha256:cdb90267650c1edb54459cdb51dab865f6c6594c3a47ebd441bc493360c7af70"}, + {file = "greenlet-1.0.0-cp35-cp35m-win_amd64.whl", hash = "sha256:eac8803c9ad1817ce3d8d15d1bb82c2da3feda6bee1153eec5c58fa6e5d3f770"}, + {file = "greenlet-1.0.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:c93d1a71c3fe222308939b2e516c07f35a849c5047f0197442a4d6fbcb4128ee"}, + {file = "greenlet-1.0.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:122c63ba795fdba4fc19c744df6277d9cfd913ed53d1a286f12189a0265316dd"}, + {file = "greenlet-1.0.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:c5b22b31c947ad8b6964d4ed66776bcae986f73669ba50620162ba7c832a6b6a"}, + {file = "greenlet-1.0.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:4365eccd68e72564c776418c53ce3c5af402bc526fe0653722bc89efd85bf12d"}, + {file = "greenlet-1.0.0-cp36-cp36m-manylinux2014_ppc64le.whl", hash = "sha256:da7d09ad0f24270b20f77d56934e196e982af0d0a2446120cb772be4e060e1a2"}, + {file = "greenlet-1.0.0-cp36-cp36m-win32.whl", hash = "sha256:647ba1df86d025f5a34043451d7c4a9f05f240bee06277a524daad11f997d1e7"}, + {file = "greenlet-1.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:e6e9fdaf6c90d02b95e6b0709aeb1aba5affbbb9ccaea5502f8638e4323206be"}, + {file = "greenlet-1.0.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:62afad6e5fd70f34d773ffcbb7c22657e1d46d7fd7c95a43361de979f0a45aef"}, + {file = "greenlet-1.0.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d3789c1c394944084b5e57c192889985a9f23bd985f6d15728c745d380318128"}, + {file = "greenlet-1.0.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f5e2d36c86c7b03c94b8459c3bd2c9fe2c7dab4b258b8885617d44a22e453fb7"}, + {file = "greenlet-1.0.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:292e801fcb3a0b3a12d8c603c7cf340659ea27fd73c98683e75800d9fd8f704c"}, + {file = "greenlet-1.0.0-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:f3dc68272990849132d6698f7dc6df2ab62a88b0d36e54702a8fd16c0490e44f"}, + {file = "greenlet-1.0.0-cp37-cp37m-win32.whl", hash = "sha256:7cd5a237f241f2764324396e06298b5dee0df580cf06ef4ada0ff9bff851286c"}, + {file = "greenlet-1.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:0ddd77586553e3daf439aa88b6642c5f252f7ef79a39271c25b1d4bf1b7cbb85"}, + {file = "greenlet-1.0.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:90b6a25841488cf2cb1c8623a53e6879573010a669455046df5f029d93db51b7"}, + {file = "greenlet-1.0.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ed1d1351f05e795a527abc04a0d82e9aecd3bdf9f46662c36ff47b0b00ecaf06"}, + {file = "greenlet-1.0.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:94620ed996a7632723a424bccb84b07e7b861ab7bb06a5aeb041c111dd723d36"}, + {file = "greenlet-1.0.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:f97d83049715fd9dec7911860ecf0e17b48d8725de01e45de07d8ac0bd5bc378"}, + {file = "greenlet-1.0.0-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:0a77691f0080c9da8dfc81e23f4e3cffa5accf0f5b56478951016d7cfead9196"}, + {file = "greenlet-1.0.0-cp38-cp38-win32.whl", hash = "sha256:e1128e022d8dce375362e063754e129750323b67454cac5600008aad9f54139e"}, + {file = "greenlet-1.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d4030b04061fdf4cbc446008e238e44936d77a04b2b32f804688ad64197953c"}, + {file = "greenlet-1.0.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:f8450d5ef759dbe59f84f2c9f77491bb3d3c44bc1a573746daf086e70b14c243"}, + {file = "greenlet-1.0.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:df8053867c831b2643b2c489fe1d62049a98566b1646b194cc815f13e27b90df"}, + {file = "greenlet-1.0.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:df3e83323268594fa9755480a442cabfe8d82b21aba815a71acf1bb6c1776218"}, + {file = "greenlet-1.0.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:181300f826625b7fd1182205b830642926f52bd8cdb08b34574c9d5b2b1813f7"}, + {file = "greenlet-1.0.0-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:58ca0f078d1c135ecf1879d50711f925ee238fe773dfe44e206d7d126f5bc664"}, + {file = "greenlet-1.0.0-cp39-cp39-win32.whl", hash = "sha256:5f297cb343114b33a13755032ecf7109b07b9a0020e841d1c3cedff6602cc139"}, + {file = "greenlet-1.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:5d69bbd9547d3bc49f8a545db7a0bd69f407badd2ff0f6e1a163680b5841d2b0"}, + {file = "greenlet-1.0.0.tar.gz", hash = "sha256:719e169c79255816cdcf6dccd9ed2d089a72a9f6c42273aae12d55e8d35bdcf8"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] importlib-metadata = [ - {file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"}, - {file = "importlib_metadata-2.0.0.tar.gz", hash = "sha256:77a540690e24b0305878c37ffd421785a6f7e53c8b5720d211b211de8d0e95da"}, + {file = "importlib_metadata-3.4.0-py3-none-any.whl", hash = "sha256:ace61d5fc652dc280e7b6b4ff732a9c2d40db2c0f92bc6cb74e07b73d53a1771"}, + {file = "importlib_metadata-3.4.0.tar.gz", hash = "sha256:fa5daa4477a7414ae34e95942e4dd07f62adf589143c875c133c1e53c4eff38d"}, ] iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, @@ -516,29 +587,46 @@ markupsafe = [ {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] packaging = [ - {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, - {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, + {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, + {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, ] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] psutil = [ - {file = "psutil-5.7.3-cp27-none-win32.whl", hash = "sha256:1cd6a0c9fb35ece2ccf2d1dd733c1e165b342604c67454fd56a4c12e0a106787"}, - {file = "psutil-5.7.3-cp27-none-win_amd64.whl", hash = "sha256:e02c31b2990dcd2431f4524b93491941df39f99619b0d312dfe1d4d530b08b4b"}, - {file = "psutil-5.7.3-cp35-cp35m-win32.whl", hash = "sha256:56c85120fa173a5d2ad1d15a0c6e0ae62b388bfb956bb036ac231fbdaf9e4c22"}, - {file = "psutil-5.7.3-cp35-cp35m-win_amd64.whl", hash = "sha256:fa38ac15dbf161ab1e941ff4ce39abd64b53fec5ddf60c23290daed2bc7d1157"}, - {file = "psutil-5.7.3-cp36-cp36m-win32.whl", hash = "sha256:01bc82813fbc3ea304914581954979e637bcc7084e59ac904d870d6eb8bb2bc7"}, - {file = "psutil-5.7.3-cp36-cp36m-win_amd64.whl", hash = "sha256:6a3e1fd2800ca45083d976b5478a2402dd62afdfb719b30ca46cd28bb25a2eb4"}, - {file = "psutil-5.7.3-cp37-cp37m-win32.whl", hash = "sha256:fbcac492cb082fa38d88587d75feb90785d05d7e12d4565cbf1ecc727aff71b7"}, - {file = "psutil-5.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:5d9106ff5ec2712e2f659ebbd112967f44e7d33f40ba40530c485cc5904360b8"}, - {file = "psutil-5.7.3-cp38-cp38-win32.whl", hash = "sha256:ade6af32eb80a536eff162d799e31b7ef92ddcda707c27bbd077238065018df4"}, - {file = "psutil-5.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:2cb55ef9591b03ef0104bedf67cc4edb38a3edf015cf8cf24007b99cb8497542"}, - {file = "psutil-5.7.3.tar.gz", hash = "sha256:af73f7bcebdc538eda9cc81d19db1db7bf26f103f91081d780bbacfcb620dee2"}, + {file = "psutil-5.8.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:0066a82f7b1b37d334e68697faba68e5ad5e858279fd6351c8ca6024e8d6ba64"}, + {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0ae6f386d8d297177fd288be6e8d1afc05966878704dad9847719650e44fc49c"}, + {file = "psutil-5.8.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:12d844996d6c2b1d3881cfa6fa201fd635971869a9da945cf6756105af73d2df"}, + {file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:02b8292609b1f7fcb34173b25e48d0da8667bc85f81d7476584d889c6e0f2131"}, + {file = "psutil-5.8.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6ffe81843131ee0ffa02c317186ed1e759a145267d54fdef1bc4ea5f5931ab60"}, + {file = "psutil-5.8.0-cp27-none-win32.whl", hash = "sha256:ea313bb02e5e25224e518e4352af4bf5e062755160f77e4b1767dd5ccb65f876"}, + {file = "psutil-5.8.0-cp27-none-win_amd64.whl", hash = "sha256:5da29e394bdedd9144c7331192e20c1f79283fb03b06e6abd3a8ae45ffecee65"}, + {file = "psutil-5.8.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:74fb2557d1430fff18ff0d72613c5ca30c45cdbfcddd6a5773e9fc1fe9364be8"}, + {file = "psutil-5.8.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:74f2d0be88db96ada78756cb3a3e1b107ce8ab79f65aa885f76d7664e56928f6"}, + {file = "psutil-5.8.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:99de3e8739258b3c3e8669cb9757c9a861b2a25ad0955f8e53ac662d66de61ac"}, + {file = "psutil-5.8.0-cp36-cp36m-win32.whl", hash = "sha256:36b3b6c9e2a34b7d7fbae330a85bf72c30b1c827a4366a07443fc4b6270449e2"}, + {file = "psutil-5.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:52de075468cd394ac98c66f9ca33b2f54ae1d9bff1ef6b67a212ee8f639ec06d"}, + {file = "psutil-5.8.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c6a5fd10ce6b6344e616cf01cc5b849fa8103fbb5ba507b6b2dee4c11e84c935"}, + {file = "psutil-5.8.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:61f05864b42fedc0771d6d8e49c35f07efd209ade09a5afe6a5059e7bb7bf83d"}, + {file = "psutil-5.8.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:0dd4465a039d343925cdc29023bb6960ccf4e74a65ad53e768403746a9207023"}, + {file = "psutil-5.8.0-cp37-cp37m-win32.whl", hash = "sha256:1bff0d07e76114ec24ee32e7f7f8d0c4b0514b3fae93e3d2aaafd65d22502394"}, + {file = "psutil-5.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:fcc01e900c1d7bee2a37e5d6e4f9194760a93597c97fee89c4ae51701de03563"}, + {file = "psutil-5.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6223d07a1ae93f86451d0198a0c361032c4c93ebd4bf6d25e2fb3edfad9571ef"}, + {file = "psutil-5.8.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:d225cd8319aa1d3c85bf195c4e07d17d3cd68636b8fc97e6cf198f782f99af28"}, + {file = "psutil-5.8.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:28ff7c95293ae74bf1ca1a79e8805fcde005c18a122ca983abf676ea3466362b"}, + {file = "psutil-5.8.0-cp38-cp38-win32.whl", hash = "sha256:ce8b867423291cb65cfc6d9c4955ee9bfc1e21fe03bb50e177f2b957f1c2469d"}, + {file = "psutil-5.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:90f31c34d25b1b3ed6c40cdd34ff122b1887a825297c017e4cbd6796dd8b672d"}, + {file = "psutil-5.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6323d5d845c2785efb20aded4726636546b26d3b577aded22492908f7c1bdda7"}, + {file = "psutil-5.8.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:245b5509968ac0bd179287d91210cd3f37add77dad385ef238b275bad35fa1c4"}, + {file = "psutil-5.8.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:90d4091c2d30ddd0a03e0b97e6a33a48628469b99585e2ad6bf21f17423b112b"}, + {file = "psutil-5.8.0-cp39-cp39-win32.whl", hash = "sha256:ea372bcc129394485824ae3e3ddabe67dc0b118d262c568b4d2602a7070afdb0"}, + {file = "psutil-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:f4634b033faf0d968bb9220dd1c793b897ab7f1189956e1aa9eae752527127d3"}, + {file = "psutil-5.8.0.tar.gz", hash = "sha256:0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6"}, ] py = [ - {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, - {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, + {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, + {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, ] pycryptodome = [ {file = "pycryptodome-3.9.9-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:5598dc6c9dbfe882904e54584322893eff185b98960bbe2cdaaa20e8a437b6e5"}, @@ -587,20 +675,20 @@ pysocks = [ {file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"}, ] pytest = [ - {file = "pytest-6.1.2-py3-none-any.whl", hash = "sha256:4288fed0d9153d9646bfcdf0c0428197dba1ecb27a33bb6e031d002fa88653fe"}, - {file = "pytest-6.1.2.tar.gz", hash = "sha256:c0a7e94a8cdbc5422a51ccdad8e6f1024795939cc89159a0ae7f0b316ad3823e"}, + {file = "pytest-6.2.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, + {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, ] python-engineio = [ - {file = "python-engineio-3.13.2.tar.gz", hash = "sha256:36b33c6aa702d9b6a7f527eec6387a2da1a9a24484ec2f086d76576413cef04b"}, - {file = "python_engineio-3.13.2-py2.py3-none-any.whl", hash = "sha256:cfded18156862f94544a9f8ef37f56727df731c8552d7023f5afee8369be2db6"}, + {file = "python-engineio-4.0.0.tar.gz", hash = "sha256:9f34afa4170f5ba6e3d9ff158752ccf8fbb2145f16554b2f0fc84646675be99a"}, + {file = "python_engineio-4.0.0-py2.py3-none-any.whl", hash = "sha256:33f7a214be5db35c867e97027bfe63676cb003d82aa17a607612b25ba5d84e5b"}, ] python-socketio = [ - {file = "python-socketio-4.6.0.tar.gz", hash = "sha256:358d8fbbc029c4538ea25bcaa283e47f375be0017fcba829de8a3a731c9df25a"}, - {file = "python_socketio-4.6.0-py2.py3-none-any.whl", hash = "sha256:d437f797c44b6efba2f201867cf02b8c96b97dff26d4e4281ac08b45817cd522"}, + {file = "python-socketio-5.0.4.tar.gz", hash = "sha256:f53fd0d5bd9f75a70492062f4ae6195ab5d34d67a29024d740f25e468392893e"}, + {file = "python_socketio-5.0.4-py2.py3-none-any.whl", hash = "sha256:870f8b00a63ef7c9a1f85fd70028624867bf246115e82625f28ef79def8847bb"}, ] requests = [ - {file = "requests-2.25.0-py2.py3-none-any.whl", hash = "sha256:e786fa28d8c9154e6a4de5d46a1d921b8749f8b74e28bde23768e5e16eece998"}, - {file = "requests-2.25.0.tar.gz", hash = "sha256:7f1a0b932f4a60a1a65caa4263921bb7d9ee911957e0ae4a23a6dd08185ad5f8"}, + {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, + {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, ] six = [ {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, @@ -613,9 +701,18 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +typing-extensions = [ + {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, + {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, + {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, +] +unidecode = [ + {file = "Unidecode-1.1.2-py2.py3-none-any.whl", hash = "sha256:4c9d15d2f73eb0d2649a151c566901f80a030da1ccb0a2043352e1dbf647586b"}, + {file = "Unidecode-1.1.2.tar.gz", hash = "sha256:a039f89014245e0cad8858976293e23501accc9ff5a7bdbc739a14a2b7b85cdc"}, +] urllib3 = [ - {file = "urllib3-1.26.2-py2.py3-none-any.whl", hash = "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"}, - {file = "urllib3-1.26.2.tar.gz", hash = "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08"}, + {file = "urllib3-1.26.3-py2.py3-none-any.whl", hash = "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80"}, + {file = "urllib3-1.26.3.tar.gz", hash = "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73"}, ] werkzeug = [ {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, diff --git a/cli/pyproject.toml b/cli/pyproject.toml index 84c9656a..eb5db684 100644 --- a/cli/pyproject.toml +++ b/cli/pyproject.toml @@ -26,6 +26,7 @@ pycryptodome = "*" pysocks = "*" requests = "*" stem = "*" +unidecode = "*" urllib3 = "*" eventlet = "*" setuptools = "*" diff --git a/desktop/package/macos/ChildEntitlements.plist b/desktop/package/macos/ChildEntitlements.plist deleted file mode 100644 index 06d88f66..00000000 --- a/desktop/package/macos/ChildEntitlements.plist +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>com.apple.security.app-sandbox</key> - <true/> - <key>com.apple.security.inherit</key> - <true/> -</dict> -</plist> diff --git a/desktop/package/macos/Entitlements.plist b/desktop/package/macos/Entitlements.plist index 8b9ac949..8c5c4268 100644 --- a/desktop/package/macos/Entitlements.plist +++ b/desktop/package/macos/Entitlements.plist @@ -2,9 +2,9 @@ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> - <!-- Enable app sandbox --> + <!-- Disable app sandbox :( --> <key>com.apple.security.app-sandbox</key> - <true/> + <false/> <!-- Required for running PyInstaller python code with hardened runtime --> <key>com.apple.security.cs.allow-unsigned-executable-memory</key> diff --git a/desktop/package/macos/build.py b/desktop/package/macos/build.py index 0ba23129..ea1e90c9 100755 --- a/desktop/package/macos/build.py +++ b/desktop/package/macos/build.py @@ -5,6 +5,7 @@ import subprocess import argparse import shutil import glob +import itertools root = os.path.dirname( os.path.dirname( @@ -15,6 +16,24 @@ root = os.path.dirname( ) +def codesign(path, entitlements, identity): + run( + [ + "codesign", + "--sign", + identity, + "--entitlements", + str(entitlements), + "--timestamp", + "--deep", + str(path), + "--force", + "--options", + "runtime", + ] + ) + + def run(cmd, cwd=None): subprocess.run(cmd, cwd=cwd, check=True) @@ -39,7 +58,7 @@ def main(): if os.path.exists(os.path.join(desktop_dir, "macOS")): shutil.rmtree(os.path.join(desktop_dir, "macOS")) - print("○ Building onionshare-cli") + print("○ Build onionshare-cli") run(["poetry", "install"], cli_dir) run(["poetry", "build"], cli_dir) whl_filename = glob.glob(os.path.join(cli_dir, "dist", "*.whl"))[0] @@ -49,50 +68,163 @@ def main(): print("○ Create app bundle") run(["briefcase", "create"], desktop_dir) app_path = os.path.join(desktop_dir, "macOS", "OnionShare", "OnionShare.app") + + print("○ Delete unused Qt5 frameworks from app bundle") + for framework in [ + "Qt3DAnimation", + "Qt3DCore", + "Qt3DExtras", + "Qt3DInput", + "Qt3DLogic", + "Qt3DQuick", + "Qt3DQuickAnimation", + "Qt3DQuickExtras", + "Qt3DQuickInput", + "Qt3DQuickRender", + "Qt3DQuickScene2D", + "Qt3DRender", + "QtBluetooth", + "QtBodymovin", + "QtCharts", + "QtConcurrent", + "QtDataVisualization", + "QtDesigner", + "QtDesignerComponents", + "QtGamepad", + "QtHelp", + "QtLocation", + "QtMultimedia", + "QtMultimediaQuick", + "QtMultimediaWidgets", + "QtNfc", + "QtOpenGL", + "QtPdf", + "QtPdfWidgets", + "QtPositioning", + "QtPositioningQuick", + "QtPurchasing", + "QtQuick", + "QtQuick3D", + "QtQuick3DAssetImport", + "QtQuick3DRender", + "QtQuick3DRuntimeRender", + "QtQuick3DUtils", + "QtQuickControls2", + "QtQuickParticles", + "QtQuickShapes", + "QtQuickTemplates2", + "QtQuickTest", + "QtQuickWidgets", + "QtRemoteObjects", + "QtRepParser", + "QtScript", + "QtScriptTools", + "QtScxml", + "QtSensors", + "QtSerialBus", + "QtSerialPort", + "QtSql", + "QtSvg", + "QtTest", + "QtTextToSpeech", + "QtUiPlugin", + "QtVirtualKeyboard", + "QtWebChannel", + "QtWebEngine", + "QtWebEngineCore", + "QtWebEngineWidgets", + "QtWebSockets", + "QtWebView", + "QtXml", + "QtXmlPatterns", + ]: + shutil.rmtree( + os.path.join( + app_path, + "Contents", + "Resources", + "app_packages", + "PySide2", + "Qt", + "lib", + f"{framework}.framework", + ) + ) + try: + os.remove( + os.path.join( + app_path, + "Contents", + "Resources", + "app_packages", + "PySide2", + f"{framework}.abi3.so", + ) + ) + os.remove( + os.path.join( + app_path, + "Contents", + "Resources", + "app_packages", + "PySide2", + f"{framework}.pyi", + ) + ) + except FileNotFoundError: + pass + shutil.rmtree( + os.path.join( + app_path, + "Contents", + "Resources", + "app_packages", + "PySide2", + "Designer.app", + ) + ) + print(f"○ Unsigned app bundle: {app_path}") if args.with_codesign: identity_name_application = "Developer ID Application: Micah Lee (N9B95FDWH4)" - entitlements_child_filename = os.path.join( - desktop_dir, "package", "macos", "ChildEntitlements.plist" - ) - entitlements_filename = os.path.join( + entitlements_plist_path = os.path.join( desktop_dir, "package", "macos", "Entitlements.plist" ) - print("○ Code signing app bundle") - run( + print("○ Code sign app bundle") + for path in itertools.chain( + glob.glob( + f"{app_path}/Contents/Resources/app_packages/**/*.dylib", recursive=True + ), + glob.glob( + f"{app_path}/Contents/Resources/app_packages/**/*.so", recursive=True + ), + glob.glob( + f"{app_path}/Contents/Resources/Support/**/*.dylib", recursive=True + ), + glob.glob(f"{app_path}/Contents/Resources/Support/**/*.so", recursive=True), + glob.glob( + f"{app_path}/Contents/Resources/app_packages/PySide2/Qt/lib/**/Versions/5/*", + recursive=True, + ), [ - "codesign", - "--deep", - "-s", - identity_name_application, - "--force", - "--entitlements", - entitlements_child_filename, - "--timestamp", + f"{app_path}/Contents/Resources/app_packages/PySide2/pyside2-lupdate", + f"{app_path}/Contents/Resources/app_packages/PySide2/rcc", + f"{app_path}/Contents/Resources/app_packages/PySide2/uic", + f"{app_path}/Contents/Resources/Support/bin/python3", app_path, - ] - ) - run( - [ - "codesign", - "-s", - identity_name_application, - "--force", - "--entitlements", - entitlements_filename, - "--timestamp", - app_path, - ] - ) + ], + ): + codesign(path, entitlements_plist_path, identity_name_application) + codesign(app_path, entitlements_plist_path, identity_name_application) print(f"○ Signed app bundle: {app_path}") if not os.path.exists("/usr/local/bin/create-dmg"): print("○ Error: create-dmg is not installed") return - print("○ Creating DMG") + print("○ Create DMG") dmg_path = os.path.join(desktop_dir, "macOS", "OnionShare.dmg") run( [ @@ -128,4 +260,4 @@ def main(): if __name__ == "__main__": - main()
\ No newline at end of file + main() diff --git a/desktop/scripts/get-tor-osx.py b/desktop/scripts/get-tor-osx.py index 67aac51a..5cdc72b8 100755 --- a/desktop/scripts/get-tor-osx.py +++ b/desktop/scripts/get-tor-osx.py @@ -37,10 +37,10 @@ import requests def main(): - dmg_url = "https://archive.torproject.org/tor-package-archive/torbrowser/10.0.2/TorBrowser-10.0.2-osx64_en-US.dmg" - dmg_filename = "TorBrowser-10.0.2-osx64_en-US.dmg" + dmg_url = "https://archive.torproject.org/tor-package-archive/torbrowser/10.0.10/TorBrowser-10.0.10-osx64_en-US.dmg" + dmg_filename = "TorBrowser-10.0.10-osx64_en-US.dmg" expected_dmg_sha256 = ( - "ac8d28f6f8d92e220f72ef7b0cb2bba45d5e0d4b243dc50806e33e08278e7730" + "7ed73e94ccdfab76b8d96ddbac7828d3a7c77dd73b54c34e55666f3b6274d12a" ) # Build paths diff --git a/desktop/scripts/get-tor-windows.py b/desktop/scripts/get-tor-windows.py index 16841c60..07656480 100644 --- a/desktop/scripts/get-tor-windows.py +++ b/desktop/scripts/get-tor-windows.py @@ -34,10 +34,10 @@ import requests def main(): - exe_url = "https://archive.torproject.org/tor-package-archive/torbrowser/10.0.2/torbrowser-install-10.0.2_en-US.exe" + exe_url = "https://archive.torproject.org/tor-package-archive/torbrowser/10.0.10/torbrowser-install-10.0.10_en-US.exe" exe_filename = "torbrowser-install-10.0.2_en-US.exe" expected_exe_sha256 = ( - "c685c550fc420c39cbe40e453f2201789af5f64e7b024c9339c2a3bd01e61c2d" + "6cbd14a7232e4ae7f2718d9b7f377e1a7bb96506da21f1ac6f689a22fc5e53fe" ) # Build paths root_path = os.path.dirname( diff --git a/desktop/src/onionshare/__init__.py b/desktop/src/onionshare/__init__.py index f66c5a28..b1275a90 100644 --- a/desktop/src/onionshare/__init__.py +++ b/desktop/src/onionshare/__init__.py @@ -27,7 +27,7 @@ import signal import json import psutil import getpass -from PySide2 import QtCore, QtWidgets +from PySide2 import QtCore, QtWidgets, QtGui from onionshare_cli.common import Common @@ -46,6 +46,9 @@ class Application(QtWidgets.QApplication): if common.platform == "Linux" or common.platform == "BSD": self.setAttribute(QtCore.Qt.AA_X11InitThreads, True) QtWidgets.QApplication.__init__(self, sys.argv) + + # Check color mode on starting the app + self.color_mode = self.get_color_mode() self.installEventFilter(self) def eventFilter(self, obj, event): @@ -57,6 +60,15 @@ class Application(QtWidgets.QApplication): self.quit() return False + def is_dark_mode(self): + baseColor = QtGui.QPalette().color(QtGui.QPalette.Base) + if baseColor.name().lower() == "#ffffff": + return False + return True + + def get_color_mode(self): + return "dark" if self.is_dark_mode() else "light" + def main(): """ diff --git a/desktop/src/onionshare/gui_common.py b/desktop/src/onionshare/gui_common.py index 7d367b99..16e0e6f5 100644 --- a/desktop/src/onionshare/gui_common.py +++ b/desktop/src/onionshare/gui_common.py @@ -78,7 +78,19 @@ class GuiCommon: os.makedirs(self.events_dir, 0o700, True) self.events_filename = os.path.join(self.events_dir, "events") - self.css = { + self.css = self.get_css(qtapp.color_mode) + self.color_mode = qtapp.color_mode + + def get_css(self, color_mode): + header_color = "#4E064F" # purple in light + title_color = "#333333" # dark gray color in main window + stop_button_color = "#d0011b" # red button color for stopping server + if color_mode == "dark": + header_color = "#F2F2F2" + title_color = "#F2F2F2" + stop_button_color = "#C32F2F" + + return { # OnionShareGui styles "tab_widget": """ QTabBar::tab { width: 170px; height: 30px; } @@ -96,7 +108,9 @@ class GuiCommon: }""", "mode_header_label": """ QLabel { - color: #4E064F; + color: """ + + header_color + + """; font-size: 48px; margin-bottom: 16px; }""", @@ -143,15 +157,8 @@ class GuiCommon: """, "server_status_url_buttons": """ QPushButton { - border: 1px solid #d3d3d3; - border-radius: 4px; - background-color: #ffffff; - padding: 8px 16px; + padding: 4px 8px; text-align: center; - color: #4e0d4e; - } - QPushButton:pressed { - background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(239, 239, 240, 255)) } """, "server_status_button_stopped": """ @@ -173,7 +180,9 @@ class GuiCommon: }""", "server_status_button_started": """ QPushButton { - background-color: #d0011b; + background-color: """ + + stop_button_color + + """; color: #ffffff; padding: 10px 30px 10px 30px; border: 0; @@ -218,14 +227,18 @@ class GuiCommon: }""", "downloads_uploads_progress_bar": """ QProgressBar { - border: 1px solid #4e064f; + border: 1px solid """ + + header_color + + """; background-color: #ffffff !important; text-align: center; color: #9b9b9b; font-size: 14px; } QProgressBar::chunk { - background-color: #4e064f; + background-color: """ + + header_color + + """; width: 10px; }""", "history_individual_file_timestamp_label": """ @@ -259,7 +272,9 @@ class GuiCommon: "new_tab_title_text": """ QLabel { text-align: center; - color: #333333; + color: """ + + title_color + + """; font-size: 25px; } """, @@ -271,33 +286,39 @@ class GuiCommon: """, "share_zip_progess_bar": """ QProgressBar { - border: 1px solid #4e064f; + border: 1px solid """ + + header_color + + """; background-color: #ffffff !important; text-align: center; color: #9b9b9b; } QProgressBar::chunk { border: 0px; - background-color: #4e064f; + background-color: """ + + header_color + + """; width: 10px; }""", "share_filesize_warning": """ QLabel { padding: 10px 0; font-weight: bold; - color: #333333; + color: """ + + title_color + + """; } """, "share_file_selection_drop_here_header_label": """ QLabel { - color: #4E064F; + color: """ + + header_color + + """; font-size: 48px; - margin-bottom: 72px; }""", "share_file_selection_drop_here_label": """ QLabel { color: #666666; - margin-bottom: 48px; }""", "share_file_selection_drop_count_label": """ QLabel { diff --git a/desktop/src/onionshare/main_window.py b/desktop/src/onionshare/main_window.py index a1b44032..f4f333d9 100644 --- a/desktop/src/onionshare/main_window.py +++ b/desktop/src/onionshare/main_window.py @@ -113,7 +113,11 @@ class MainWindow(QtWidgets.QMainWindow): self.settings_button.setDefault(False) self.settings_button.setFixedSize(40, 50) self.settings_button.setIcon( - QtGui.QIcon(GuiCommon.get_resource_path("images/settings.png")) + QtGui.QIcon( + GuiCommon.get_resource_path( + "images/{}_settings.png".format(self.common.gui.color_mode) + ) + ) ) self.settings_button.clicked.connect(self.open_settings) self.settings_button.setStyleSheet(self.common.gui.css["settings_button"]) @@ -285,6 +289,20 @@ class MainWindow(QtWidgets.QMainWindow): self.system_tray.hide() e.accept() + def event(self, event): + # Check if color mode switched while onionshare was open, if so, ask user to restart + if event.type() == QtCore.QEvent.Type.ApplicationPaletteChange: + QtCore.QTimer.singleShot(1, self.color_mode_warning) + return True + return QtWidgets.QMainWindow.event(self, event) + + def color_mode_warning(self): + """ + Open the color mode warning alert. + """ + notice = strings._("gui_color_mode_changed_notice") + Alert(self.common, notice, QtWidgets.QMessageBox.Information) + def cleanup(self): self.common.log("MainWindow", "cleanup") self.tabs.cleanup() diff --git a/desktop/src/onionshare/resources/images/dark_icon-add.png b/desktop/src/onionshare/resources/images/dark_icon-add.png Binary files differnew file mode 100644 index 00000000..5b8600c9 --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_icon-add.png diff --git a/desktop/src/onionshare/resources/images/dark_icon-close.png b/desktop/src/onionshare/resources/images/dark_icon-close.png Binary files differnew file mode 100644 index 00000000..b9efb45d --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_icon-close.png diff --git a/desktop/src/onionshare/resources/images/dark_logo_text.png b/desktop/src/onionshare/resources/images/dark_logo_text.png Binary files differnew file mode 100644 index 00000000..6568ee0d --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_logo_text.png diff --git a/desktop/src/onionshare/resources/images/dark_mode_chat.png b/desktop/src/onionshare/resources/images/dark_mode_chat.png Binary files differnew file mode 100644 index 00000000..fe58d384 --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_mode_chat.png diff --git a/desktop/src/onionshare/resources/images/dark_mode_new_tab_chat.png b/desktop/src/onionshare/resources/images/dark_mode_new_tab_chat.png Binary files differnew file mode 100644 index 00000000..e496a63a --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_mode_new_tab_chat.png diff --git a/desktop/src/onionshare/resources/images/dark_mode_new_tab_receive.png b/desktop/src/onionshare/resources/images/dark_mode_new_tab_receive.png Binary files differnew file mode 100644 index 00000000..6912ff24 --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_mode_new_tab_receive.png diff --git a/desktop/src/onionshare/resources/images/dark_mode_new_tab_share.png b/desktop/src/onionshare/resources/images/dark_mode_new_tab_share.png Binary files differnew file mode 100644 index 00000000..3d8ae81f --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_mode_new_tab_share.png diff --git a/desktop/src/onionshare/resources/images/dark_mode_new_tab_website.png b/desktop/src/onionshare/resources/images/dark_mode_new_tab_website.png Binary files differnew file mode 100644 index 00000000..5eef2a2e --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_mode_new_tab_website.png diff --git a/desktop/src/onionshare/resources/images/dark_mode_receive.png b/desktop/src/onionshare/resources/images/dark_mode_receive.png Binary files differnew file mode 100644 index 00000000..60795631 --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_mode_receive.png diff --git a/desktop/src/onionshare/resources/images/dark_mode_share.png b/desktop/src/onionshare/resources/images/dark_mode_share.png Binary files differnew file mode 100644 index 00000000..b6ea7202 --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_mode_share.png diff --git a/desktop/src/onionshare/resources/images/dark_mode_website.png b/desktop/src/onionshare/resources/images/dark_mode_website.png Binary files differnew file mode 100644 index 00000000..52bae58c --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_mode_website.png diff --git a/desktop/src/onionshare/resources/images/dark_settings.png b/desktop/src/onionshare/resources/images/dark_settings.png Binary files differnew file mode 100644 index 00000000..8bb96f8a --- /dev/null +++ b/desktop/src/onionshare/resources/images/dark_settings.png diff --git a/desktop/src/onionshare/resources/images/light_logo_text.png b/desktop/src/onionshare/resources/images/light_logo_text.png Binary files differnew file mode 100644 index 00000000..4b05d0b2 --- /dev/null +++ b/desktop/src/onionshare/resources/images/light_logo_text.png diff --git a/desktop/src/onionshare/resources/images/light_mode_chat.png b/desktop/src/onionshare/resources/images/light_mode_chat.png Binary files differnew file mode 100644 index 00000000..cd3a4432 --- /dev/null +++ b/desktop/src/onionshare/resources/images/light_mode_chat.png diff --git a/desktop/src/onionshare/resources/images/light_mode_new_tab_chat.png b/desktop/src/onionshare/resources/images/light_mode_new_tab_chat.png Binary files differnew file mode 100644 index 00000000..ec1e29cb --- /dev/null +++ b/desktop/src/onionshare/resources/images/light_mode_new_tab_chat.png diff --git a/desktop/src/onionshare/resources/images/light_mode_new_tab_receive.png b/desktop/src/onionshare/resources/images/light_mode_new_tab_receive.png Binary files differnew file mode 100644 index 00000000..722fe3df --- /dev/null +++ b/desktop/src/onionshare/resources/images/light_mode_new_tab_receive.png diff --git a/desktop/src/onionshare/resources/images/light_mode_new_tab_share.png b/desktop/src/onionshare/resources/images/light_mode_new_tab_share.png Binary files differnew file mode 100644 index 00000000..17569fc2 --- /dev/null +++ b/desktop/src/onionshare/resources/images/light_mode_new_tab_share.png diff --git a/desktop/src/onionshare/resources/images/light_mode_new_tab_website.png b/desktop/src/onionshare/resources/images/light_mode_new_tab_website.png Binary files differnew file mode 100644 index 00000000..e88f344e --- /dev/null +++ b/desktop/src/onionshare/resources/images/light_mode_new_tab_website.png diff --git a/desktop/src/onionshare/resources/images/light_mode_receive.png b/desktop/src/onionshare/resources/images/light_mode_receive.png Binary files differnew file mode 100644 index 00000000..277ec487 --- /dev/null +++ b/desktop/src/onionshare/resources/images/light_mode_receive.png diff --git a/desktop/src/onionshare/resources/images/light_mode_share.png b/desktop/src/onionshare/resources/images/light_mode_share.png Binary files differnew file mode 100644 index 00000000..2339f69f --- /dev/null +++ b/desktop/src/onionshare/resources/images/light_mode_share.png diff --git a/desktop/src/onionshare/resources/images/light_mode_website.png b/desktop/src/onionshare/resources/images/light_mode_website.png Binary files differnew file mode 100644 index 00000000..56e492a3 --- /dev/null +++ b/desktop/src/onionshare/resources/images/light_mode_website.png diff --git a/desktop/src/onionshare/resources/images/settings.png b/desktop/src/onionshare/resources/images/light_settings.png Binary files differindex b6f8fa55..b6f8fa55 100644 --- a/desktop/src/onionshare/resources/images/settings.png +++ b/desktop/src/onionshare/resources/images/light_settings.png diff --git a/desktop/src/onionshare/resources/images/logo_text.png b/desktop/src/onionshare/resources/images/logo_text.png Binary files differdeleted file mode 100644 index 3b584acd..00000000 --- a/desktop/src/onionshare/resources/images/logo_text.png +++ /dev/null diff --git a/desktop/src/onionshare/resources/images/mode_chat.png b/desktop/src/onionshare/resources/images/mode_chat.png Binary files differdeleted file mode 100644 index 33114364..00000000 --- a/desktop/src/onionshare/resources/images/mode_chat.png +++ /dev/null diff --git a/desktop/src/onionshare/resources/images/mode_new_tab_chat.png b/desktop/src/onionshare/resources/images/mode_new_tab_chat.png Binary files differdeleted file mode 100644 index 50759d64..00000000 --- a/desktop/src/onionshare/resources/images/mode_new_tab_chat.png +++ /dev/null diff --git a/desktop/src/onionshare/resources/images/mode_new_tab_receive.png b/desktop/src/onionshare/resources/images/mode_new_tab_receive.png Binary files differdeleted file mode 100644 index 9db809be..00000000 --- a/desktop/src/onionshare/resources/images/mode_new_tab_receive.png +++ /dev/null diff --git a/desktop/src/onionshare/resources/images/mode_new_tab_share.png b/desktop/src/onionshare/resources/images/mode_new_tab_share.png Binary files differdeleted file mode 100644 index 92973175..00000000 --- a/desktop/src/onionshare/resources/images/mode_new_tab_share.png +++ /dev/null diff --git a/desktop/src/onionshare/resources/images/mode_new_tab_website.png b/desktop/src/onionshare/resources/images/mode_new_tab_website.png Binary files differdeleted file mode 100644 index 86b45f66..00000000 --- a/desktop/src/onionshare/resources/images/mode_new_tab_website.png +++ /dev/null diff --git a/desktop/src/onionshare/resources/images/mode_receive.png b/desktop/src/onionshare/resources/images/mode_receive.png Binary files differdeleted file mode 100644 index d57aa409..00000000 --- a/desktop/src/onionshare/resources/images/mode_receive.png +++ /dev/null diff --git a/desktop/src/onionshare/resources/images/mode_share.png b/desktop/src/onionshare/resources/images/mode_share.png Binary files differdeleted file mode 100644 index ec287db4..00000000 --- a/desktop/src/onionshare/resources/images/mode_share.png +++ /dev/null diff --git a/desktop/src/onionshare/resources/images/mode_website.png b/desktop/src/onionshare/resources/images/mode_website.png Binary files differdeleted file mode 100644 index 37a556d9..00000000 --- a/desktop/src/onionshare/resources/images/mode_website.png +++ /dev/null diff --git a/desktop/src/onionshare/resources/locale/en.json b/desktop/src/onionshare/resources/locale/en.json index 502fe13e..f7b8f7bb 100644 --- a/desktop/src/onionshare/resources/locale/en.json +++ b/desktop/src/onionshare/resources/locale/en.json @@ -111,6 +111,7 @@ "gui_open_folder_error": "Failed to open folder with xdg-open. The file is here: {}", "gui_settings_language_label": "Preferred language", "gui_settings_language_changed_notice": "Restart OnionShare for the new language to be applied.", + "gui_color_mode_changed_notice": "Restart OnionShare for the new color mode to be applied.", "systray_menu_exit": "Quit", "systray_page_loaded_title": "Page Loaded", "systray_page_loaded_message": "OnionShare address loaded", diff --git a/desktop/src/onionshare/tab/mode/__init__.py b/desktop/src/onionshare/tab/mode/__init__.py index 0bef7628..c48f20c0 100644 --- a/desktop/src/onionshare/tab/mode/__init__.py +++ b/desktop/src/onionshare/tab/mode/__init__.py @@ -356,10 +356,12 @@ class Mode(QtWidgets.QWidget): self.startup_thread.quit() if self.onion_thread: self.common.log("Mode", "cancel_server: quitting onion thread") - self.onion_thread.quit() + self.onion_thread.terminate() + self.onion_thread.wait() if self.web_thread: self.common.log("Mode", "cancel_server: quitting web thread") - self.web_thread.quit() + self.web_thread.terminate() + self.web_thread.wait() self.stop_server() def cancel_server_custom(self): diff --git a/desktop/src/onionshare/tab/mode/chat_mode/__init__.py b/desktop/src/onionshare/tab/mode/chat_mode/__init__.py index a7c2929b..440a97c5 100644 --- a/desktop/src/onionshare/tab/mode/chat_mode/__init__.py +++ b/desktop/src/onionshare/tab/mode/chat_mode/__init__.py @@ -53,7 +53,11 @@ class ChatMode(Mode): self.image_label = QtWidgets.QLabel() self.image_label.setPixmap( QtGui.QPixmap.fromImage( - QtGui.QImage(GuiCommon.get_resource_path("images/mode_chat.png")) + QtGui.QImage( + GuiCommon.get_resource_path( + "images/{}_mode_chat.png".format(self.common.gui.color_mode) + ) + ) ) ) self.image_label.setFixedSize(300, 300) diff --git a/desktop/src/onionshare/tab/mode/file_selection.py b/desktop/src/onionshare/tab/mode/file_selection.py index 54d9ea83..fed4e4c5 100644 --- a/desktop/src/onionshare/tab/mode/file_selection.py +++ b/desktop/src/onionshare/tab/mode/file_selection.py @@ -72,8 +72,8 @@ class DropHereWidget(QtWidgets.QWidget): def resize(self, w, h): self.setGeometry(0, 0, w, h) self.image_label.setGeometry(0, 0, w, h - 100) - self.header_label.setGeometry(0, 340, w, h - 340) - self.text_label.setGeometry(0, 410, w, h - 410) + self.header_label.setGeometry(0, 310, w, h - 380) + self.text_label.setGeometry(0, 360, w, h - 400) class DropCountLabel(QtWidgets.QLabel): diff --git a/desktop/src/onionshare/tab/mode/receive_mode/__init__.py b/desktop/src/onionshare/tab/mode/receive_mode/__init__.py index 95a68dcb..b54c1168 100644 --- a/desktop/src/onionshare/tab/mode/receive_mode/__init__.py +++ b/desktop/src/onionshare/tab/mode/receive_mode/__init__.py @@ -46,7 +46,11 @@ class ReceiveMode(Mode): self.image_label = QtWidgets.QLabel() self.image_label.setPixmap( QtGui.QPixmap.fromImage( - QtGui.QImage(GuiCommon.get_resource_path("images/mode_receive.png")) + QtGui.QImage( + GuiCommon.get_resource_path( + "images/{}_mode_receive.png".format(self.common.gui.color_mode) + ) + ) ) ) self.image_label.setFixedSize(250, 250) diff --git a/desktop/src/onionshare/tab/mode/share_mode/__init__.py b/desktop/src/onionshare/tab/mode/share_mode/__init__.py index bf1498d5..b9e01f5d 100644 --- a/desktop/src/onionshare/tab/mode/share_mode/__init__.py +++ b/desktop/src/onionshare/tab/mode/share_mode/__init__.py @@ -69,7 +69,7 @@ class ShareMode(Mode): # File selection self.file_selection = FileSelection( self.common, - "images/mode_share.png", + "images/{}_mode_share.png".format(self.common.gui.color_mode), strings._("gui_new_tab_share_button"), self, ) diff --git a/desktop/src/onionshare/tab/mode/website_mode/__init__.py b/desktop/src/onionshare/tab/mode/website_mode/__init__.py index 6df6ff02..0c323b1c 100644 --- a/desktop/src/onionshare/tab/mode/website_mode/__init__.py +++ b/desktop/src/onionshare/tab/mode/website_mode/__init__.py @@ -69,7 +69,7 @@ class WebsiteMode(Mode): # File selection self.file_selection = FileSelection( self.common, - "images/mode_website.png", + "images/{}_mode_website.png".format(self.common.gui.color_mode), strings._("gui_new_tab_website_button"), self, ) diff --git a/desktop/src/onionshare/tab/server_status.py b/desktop/src/onionshare/tab/server_status.py index 2e8dc4f0..42f60cd3 100644 --- a/desktop/src/onionshare/tab/server_status.py +++ b/desktop/src/onionshare/tab/server_status.py @@ -93,7 +93,6 @@ class ServerStatus(QtWidgets.QWidget): ) self.copy_url_button = QtWidgets.QPushButton(strings._("gui_copy_url")) - self.copy_url_button.setFlat(True) self.copy_url_button.setStyleSheet( self.common.gui.css["server_status_url_buttons"] ) @@ -108,12 +107,10 @@ class ServerStatus(QtWidgets.QWidget): self.show_url_qr_code_button.clicked.connect( self.show_url_qr_code_button_clicked ) - self.show_url_qr_code_button.setFlat(True) self.show_url_qr_code_button.setStyleSheet( self.common.gui.css["server_status_url_buttons"] ) - self.copy_hidservauth_button.setFlat(True) self.copy_hidservauth_button.setStyleSheet( self.common.gui.css["server_status_url_buttons"] ) diff --git a/desktop/src/onionshare/tab/tab.py b/desktop/src/onionshare/tab/tab.py index 8cbddfed..aea81e82 100644 --- a/desktop/src/onionshare/tab/tab.py +++ b/desktop/src/onionshare/tab/tab.py @@ -121,10 +121,14 @@ class Tab(QtWidgets.QWidget): self.image_label = QtWidgets.QLabel() self.image_label.setPixmap( QtGui.QPixmap.fromImage( - QtGui.QImage(GuiCommon.get_resource_path("images/logo_text.png")) + QtGui.QImage( + GuiCommon.get_resource_path( + "images/{}_logo_text.png".format(self.common.gui.color_mode) + ) + ) ) ) - self.image_label.setFixedSize(160, 40) + self.image_label.setFixedSize(180, 40) image_layout = QtWidgets.QVBoxLayout() image_layout.addWidget(self.image_label) image_layout.addStretch() @@ -134,7 +138,7 @@ class Tab(QtWidgets.QWidget): # New tab buttons self.share_button = NewTabButton( self.common, - "images/mode_new_tab_share.png", + "images/{}_mode_new_tab_share.png".format(self.common.gui.color_mode), strings._("gui_new_tab_share_button"), strings._("gui_main_page_share_button"), ) @@ -142,7 +146,7 @@ class Tab(QtWidgets.QWidget): self.receive_button = NewTabButton( self.common, - "images/mode_new_tab_receive.png", + "images/{}_mode_new_tab_receive.png".format(self.common.gui.color_mode), strings._("gui_new_tab_receive_button"), strings._("gui_main_page_receive_button"), ) @@ -150,7 +154,7 @@ class Tab(QtWidgets.QWidget): self.website_button = NewTabButton( self.common, - "images/mode_new_tab_website.png", + "images/{}_mode_new_tab_website.png".format(self.common.gui.color_mode), strings._("gui_new_tab_website_button"), strings._("gui_main_page_website_button"), ) @@ -158,7 +162,7 @@ class Tab(QtWidgets.QWidget): self.chat_button = NewTabButton( self.common, - "images/mode_new_tab_chat.png", + "images/{}_mode_new_tab_chat.png".format(self.common.gui.color_mode), strings._("gui_new_tab_chat_button"), strings._("gui_main_page_chat_button"), ) |