diff --git a/.circleci/config.yml b/.circleci/config.yml index b9938c28..59eafc34 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -50,16 +50,11 @@ jobs: sudo apt-get update sudo apt-get install -y tor obfs4proxy gcc python3-dev python3-pyside2.qtcore python3-pyside2.qtwidgets python3-pyside2.qtgui sudo apt-get install -y xvfb x11-utils libxkbcommon-x11-0 libxcb-randr0-dev libxcb-xtest0-dev libxcb-xinerama0-dev libxcb-shape0-dev libxcb-xkb-dev libxcb-render-util0 libxcb-icccm4 libxcb-keysyms1 libxcb-image0 - cd ~/repo/cli - poetry install - poetry build - cp dist/onionshare_cli-*.whl ~/repo/desktop cd ~/repo/desktop - pip install briefcase pytest pytest-briefcase pytest-faulthandler pytest-qt pytest-xvfb - pip install $(python -c 'import toml; print(" ".join(toml.loads(open("pyproject.toml").read())["tool"]["briefcase"]["app"]["onionshare"]["requires"]))') + poetry install - run: name: Run tests command: | cd ~/repo/desktop - ./tests/run.sh + poetry run ./tests/run.sh diff --git a/desktop/README.md b/desktop/README.md index 9c55f343..06ca9067 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -9,58 +9,44 @@ git clone https://github.com/onionshare/onionshare.git cd onionshare/desktop ``` +Make sure you have Python 3 installed. If you're using Windows or macOS, install version 3.10.1 [from python.org](https://www.python.org/downloads/release/python-3101/). For Windows, make sure to install the 32-bit (x86) version, and to check the box to add python to the path on the first page of the installer. + +Make sure you have [poetry installed](https://python-poetry.org/docs/#installation), and then install the dependencies: + +```sh +poetry install +``` + ### Install platform-specific dependencies #### Linux In Ubuntu 20.04 you need the `libxcb-xinerama0` package installed. -Install python dependencies: - -```sh -pip3 install --user poetry requests -``` - Download Tor Browser and extract the binaries: ```sh -./scripts/get-tor-linux.py +poetry run ./scripts/get-tor-linux.py ``` #### macOS -Download and install Python 3.8.6 from https://www.python.org/downloads/release/python-386/. I downloaded `python-3.8.6-macosx10.9.pkg`. (You may need to also run `/Applications/Python\ 3.8/Install\ Certificates.command`.) - -Install python dependencies: - -```sh -pip3 install --user poetry requests -``` - Download Tor Browser and extract the binaries: ```sh -./scripts/get-tor-osx.py +poetry run ./scripts/get-tor-osx.py ``` #### Windows These instructions include adding folders to the path in Windows. To do this, go to Start and type "advanced system settings", and open "View advanced system settings" in the Control Panel. Click Environment Variables. Under "System variables" double-click on Path. From there you can add and remove folders that are available in the PATH. -Download Python 3.8.6, 32-bit (x86) from https://www.python.org/downloads/release/python-386/. I downloaded `python-3.8.6.exe`. When installing it, make sure to check the "Add Python 3.8 to PATH" checkbox on the first page of the installer. - Download and install 7-Zip from https://7-zip.org/download.html. I downloaded `7z1900.exe`. Add `C:\Program Files (x86)\7-Zip` to your path. -Install python dependencies: - -``` -pip install poetry requests -``` - Download Tor Browser and extract the binaries: -``` -python scripts\get-tor-windows.py +```sh +poetry run python scripts\get-tor-windows.py ``` ### Compile dependencies @@ -69,75 +55,31 @@ Install Go. The simplest way to make sure everything works is to install Go by f Download and compile `meek-client`: -``` -./scripts/build-meek-client.py -``` - -### Prepare the virtual environment - -OnionShare uses [Briefcase](https://briefcase.readthedocs.io/en/latest/). - -Install Briefcase dependencies by following [these instructions](https://docs.beeware.org/en/latest/tutorial/tutorial-0.html#install-dependencies). - -Now create and/or activate a virtual environment. - -* Linux and macOS - ``` - python3 -m venv venv - . venv/bin/activate - ``` -* Windows - ``` - python -m venv venv - venv\Scripts\activate.bat - ``` - -While your virtual environment is active, install briefcase from pip. - -``` -pip install briefcase -``` - -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 +./scripts/build-meek-client.py ``` ### Running OnionShare from the source code tree -Inside the virtual environment, run OnionShare like this to install all of the dependencies: +To run OnionShare from the source tree: +```sh +poetry run onionshare +poetry run onionshare --help +poetry run onionshare -v +poetry run onionshare -v --local-only ``` -briefcase dev -d -``` - -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`: - -``` -./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: +Run the tests: ```sh -pip install pytest pytest-briefcase pytest-faulthandler pytest-qt -``` - -Then run the tests: - -```sh -./tests/run.sh +poetry run ./tests/run.sh ``` If you want to run tests while hiding the GUI, you must have the `xvfb` package installed, and then: ```sh -xvfb-run ./tests/run.sh +xvfb-run poetry run ./tests/run.sh ``` diff --git a/desktop/poetry.lock b/desktop/poetry.lock index c3aaabe0..164c455b 100644 --- a/desktop/poetry.lock +++ b/desktop/poetry.lock @@ -1,3 +1,25 @@ +[[package]] +name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "attrs" +version = "21.2.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] +docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] + [[package]] name = "bidict" version = "0.21.4" @@ -197,6 +219,14 @@ docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] perf = ["ipython"] testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "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" +optional = false +python-versions = "*" + [[package]] name = "itsdangerous" version = "1.1.0" @@ -262,6 +292,17 @@ urllib3 = "*" type = "directory" url = "../cli" +[[package]] +name = "packaging" +version = "21.3" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" + [[package]] name = "pathspec" version = "0.9.0" @@ -282,6 +323,18 @@ python-versions = ">=3.6" docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] +[[package]] +name = "pluggy" +version = "1.0.0" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + [[package]] name = "psutil" version = "5.8.0" @@ -293,6 +346,14 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "pycparser" version = "2.21" @@ -317,6 +378,17 @@ six = "*" docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] tests = ["pytest (>=3.2.1,!=3.3.0)", "hypothesis (>=3.27.0)"] +[[package]] +name = "pyparsing" +version = "3.0.6" +description = "Python parsing module" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + [[package]] name = "pyside2" version = "5.15.2" @@ -336,6 +408,53 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pytest" +version = "6.2.5" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +py = ">=1.8.2" +toml = "*" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +name = "pytest-faulthandler" +version = "2.0.1" +description = "py.test plugin that activates the fault handler module for tests (dummy package)" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +pytest = ">=5.0" + +[[package]] +name = "pytest-qt" +version = "4.0.2" +description = "pytest support for PyQt and PySide applications" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pytest = ">=3.0.0" + +[package.extras] +dev = ["pre-commit", "tox"] +doc = ["sphinx", "sphinx-rtd-theme"] + [[package]] name = "python-engineio" version = "4.3.0" @@ -417,6 +536,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + [[package]] name = "tomli" version = "1.2.3" @@ -481,9 +608,17 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = ">=3.9,<3.10" -content-hash = "fef2babd1d9cc50bdb8c183a72619123e66ea02c88b20257653ad31ac2c9b7ee" +content-hash = "1248f936dce04a72a33d9d6cc5b3e2222662f0a95712443fe8709bef82a06c8a" [metadata.files] +atomicwrites = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] +attrs = [ + {file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, + {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, +] bidict = [ {file = "bidict-0.21.4-py3-none-any.whl", hash = "sha256:3ac67daa353ecf853a1df9d3e924f005e729227a60a8dbada31a4c31aba7f654"}, {file = "bidict-0.21.4.tar.gz", hash = "sha256:42c84ffbe6f8de898af6073b4be9ea7ccedcd78d3474aa844c54e49d5a079f6f"}, @@ -667,6 +802,10 @@ importlib-metadata = [ {file = "importlib_metadata-4.9.0-py3-none-any.whl", hash = "sha256:e8b45564028bc25f8c99f546616112a6df5de6655893d7eb74c9a99680dc9751"}, {file = "importlib_metadata-4.9.0.tar.gz", hash = "sha256:ee50794eccb0ec340adbc838344ebb9a6ff2bcba78f752d31fc716497e2149d6"}, ] +iniconfig = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] itsdangerous = [ {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, @@ -736,6 +875,10 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] onionshare-cli = [] +packaging = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] pathspec = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, @@ -744,6 +887,10 @@ platformdirs = [ {file = "platformdirs-2.4.0-py3-none-any.whl", hash = "sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d"}, {file = "platformdirs-2.4.0.tar.gz", hash = "sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2"}, ] +pluggy = [ + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] psutil = [ {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"}, @@ -774,6 +921,10 @@ psutil = [ {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.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] pycparser = [ {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, @@ -798,6 +949,10 @@ pynacl = [ {file = "PyNaCl-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420"}, {file = "PyNaCl-1.4.0.tar.gz", hash = "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505"}, ] +pyparsing = [ + {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, + {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, +] pyside2 = [ {file = "PySide2-5.15.2-5.15.2-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:4f17a0161995678110447711d685fcd7b15b762810e8f00f6dc239bffb70a32e"}, {file = "PySide2-5.15.2-5.15.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:0558ced3bcd7f9da638fa8b7709dba5dae82a38728e481aac8b9058ea22fcdd9"}, @@ -811,6 +966,18 @@ pysocks = [ {file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"}, {file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"}, ] +pytest = [ + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, +] +pytest-faulthandler = [ + {file = "pytest-faulthandler-2.0.1.tar.gz", hash = "sha256:ed72bbce87ac344da81eb7d882196a457d4a1026a3da4a57154dacd85cd71ae5"}, + {file = "pytest_faulthandler-2.0.1-py2.py3-none-any.whl", hash = "sha256:236430ba962fd1c910d670922be55fe5b25ea9bc3fc6561a0cafbb8759e7504d"}, +] +pytest-qt = [ + {file = "pytest-qt-4.0.2.tar.gz", hash = "sha256:dfc5240dec7eb43b76bcb5f9a87eecae6ef83592af49f3af5f1d5d093acaa93e"}, + {file = "pytest_qt-4.0.2-py2.py3-none-any.whl", hash = "sha256:e03847ac02a890ccaac0fde1748855b9dce425aceba62005c6cfced6cf7d5456"}, +] python-engineio = [ {file = "python-engineio-4.3.0.tar.gz", hash = "sha256:fed35eeacfa21f53f1fc05ef0cadd65a50780364da3a2be7650eb92f928fdb11"}, {file = "python_engineio-4.3.0-py3-none-any.whl", hash = "sha256:ad06a975f7e14cb3bb7137cbf70fd883804484d29acd58004d1db1e2a7fc0ad3"}, @@ -838,6 +1005,10 @@ six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] +toml = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] tomli = [ {file = "tomli-1.2.3-py3-none-any.whl", hash = "sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"}, {file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"}, diff --git a/desktop/pyproject.toml b/desktop/pyproject.toml index 580994a6..977554f9 100644 --- a/desktop/pyproject.toml +++ b/desktop/pyproject.toml @@ -14,6 +14,9 @@ cx_freeze = {version = "*", platform = "win32"} [tool.poetry.dev-dependencies] black = "*" +pytest = "*" +pytest-faulthandler = "*" +pytest-qt = "*" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/desktop/scripts/build-meek-client.py b/desktop/scripts/build-meek-client.py index ee4d28ee..563e9a01 100755 --- a/desktop/scripts/build-meek-client.py +++ b/desktop/scripts/build-meek-client.py @@ -48,12 +48,10 @@ def main(): os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) ) if platform.system() == "Windows": - dist_path = os.path.join( - root_path, "src", "onionshare", "resources", "tor", "Tor" - ) + dist_path = os.path.join(root_path, "onionshare", "resources", "tor", "Tor") bin_filename = "meek-client.exe" else: - dist_path = os.path.join(root_path, "src", "onionshare", "resources", "tor") + dist_path = os.path.join(root_path, "onionshare", "resources", "tor") bin_filename = "meek-client" bin_path = os.path.join(os.path.expanduser("~"), "go", "bin", bin_filename) diff --git a/desktop/scripts/check_lacked_trans.py b/desktop/scripts/check_lacked_trans.py deleted file mode 100755 index 2456c995..00000000 --- a/desktop/scripts/check_lacked_trans.py +++ /dev/null @@ -1,154 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -""" -Check translation lacked or disused. - -Example: -in OnionShare directory -$ check_lacked_trans.py -de disused choose_file -de disused gui_starting_server -de lacked gui_canceled -de lacked gui_starting_server1 -de lacked gui_starting_server2 -de lacked gui_starting_server3 -en disused choose_file -es disused choose_file -es disused gui_starting_server -... - - -1. search `{{strings.translation_key}}` and `strings._('translation_key')` - from .py or .html files. -2. load translation key from locale/*.json. -3. compare these. - -""" - - -import argparse -import re -import os -import codecs -import json -import sys - - -def arg_parser(): - desc = __doc__.strip().splitlines()[0] - p = argparse.ArgumentParser(description=desc) - p.add_argument( - "-d", - default=".", - help="onionshare directory", - metavar="ONIONSHARE_DIR", - dest="onionshare_dir", - ) - p.add_argument( - "--show-all-keys", - action="store_true", - help="show translation key in source and exit", - ), - p.add_argument( - "-l", - default="all", - help="language code (default: all)", - metavar="LANG_CODE", - dest="lang_code", - ) - return p - - -def files_in(*dirs): - dir = os.path.join(*dirs) - files = os.listdir(dir) - return [os.path.join(dir, f) for f in files] - - -def main(): - parser = arg_parser() - args = parser.parse_args() - - dir = args.onionshare_dir - - src = ( - files_in(dir, "onionshare_gui") - + files_in(dir, "onionshare_gui/tab") - + files_in(dir, "onionshare_gui/tab/mode") - + files_in(dir, "onionshare_gui/tab/mode/chat_mode") - + files_in(dir, "onionshare_gui/tab/mode/receive_mode") - + files_in(dir, "onionshare_gui/tab/mode/share_mode") - + files_in(dir, "onionshare_gui/tab/mode/website_mode") - + files_in(dir, "install/scripts") - ) - filenames = [p for p in src if p.endswith(".py")] - - lang_code = args.lang_code - - translate_keys = set() - for filename in filenames: - # load translate key from python source - with open(filename) as f: - src = f.read() - - # find all the starting strings - start_substr = "strings._\(" - starting_indices = [m.start() for m in re.finditer(start_substr, src)] - - for starting_i in starting_indices: - # are we dealing with single quotes or double quotes? - quote = None - inc = 0 - while True: - quote_i = starting_i + len("strings._(") + inc - if src[quote_i] == '"': - quote = '"' - break - if src[quote_i] == "'": - quote = "'" - break - inc += 1 - - # find the starting quote - starting_i = src.find(quote, starting_i) - if starting_i: - starting_i += 1 - # find the ending quote - ending_i = src.find(quote, starting_i) - if ending_i: - key = src[starting_i:ending_i] - translate_keys.add(key) - - if args.show_all_keys: - for k in sorted(translate_keys): - print(k) - sys.exit() - - if lang_code == "all": - locale_files = [f for f in files_in(dir, "share/locale") if f.endswith(".json")] - else: - locale_files = [ - f - for f in files_in(dir, "share/locale") - if f.endswith("%s.json" % lang_code) - ] - for locale_file in locale_files: - with codecs.open(locale_file, "r", encoding="utf-8") as f: - trans = json.load(f) - # trans -> {"key1": "translate-text1", "key2": "translate-text2", ...} - locale_keys = set(trans.keys()) - - disused = locale_keys - translate_keys - lacked = translate_keys - locale_keys - - locale, ext = os.path.splitext(os.path.basename(locale_file)) - for k in sorted(disused): - print(locale, "disused", k) - - for k in sorted(lacked): - print(locale, "lacked", k) - - -if __name__ == "__main__": - main() diff --git a/desktop/scripts/dev.bat b/desktop/scripts/dev.bat deleted file mode 100644 index 9b537a90..00000000 --- a/desktop/scripts/dev.bat +++ /dev/null @@ -1,3 +0,0 @@ -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 deleted file mode 100755 index 18fade68..00000000 --- a/desktop/scripts/dev.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/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()" $@ diff --git a/desktop/scripts/get-tor-linux.py b/desktop/scripts/get-tor-linux.py index 1f5e36fd..a911713d 100755 --- a/desktop/scripts/get-tor-linux.py +++ b/desktop/scripts/get-tor-linux.py @@ -47,7 +47,7 @@ def main(): ) working_path = os.path.join(root_path, "build", "tor") tarball_path = os.path.join(working_path, tarball_filename) - dist_path = os.path.join(root_path, "src", "onionshare", "resources", "tor") + dist_path = os.path.join(root_path, "onionshare", "resources", "tor") # Make sure dirs exist if not os.path.exists(working_path): diff --git a/desktop/scripts/get-tor-osx.py b/desktop/scripts/get-tor-osx.py index c5c01836..2f2d2959 100755 --- a/desktop/scripts/get-tor-osx.py +++ b/desktop/scripts/get-tor-osx.py @@ -51,7 +51,7 @@ def main(): "/Volumes", "Tor Browser", "Tor Browser.app", "Contents" ) dmg_path = os.path.join(working_path, dmg_filename) - dist_path = os.path.join(root_path, "src", "onionshare", "resources", "tor") + dist_path = os.path.join(root_path, "onionshare", "resources", "tor") if not os.path.exists(dist_path): os.makedirs(dist_path, exist_ok=True) diff --git a/desktop/scripts/get-tor-windows.py b/desktop/scripts/get-tor-windows.py index 69c98a1b..4bd89ec4 100644 --- a/desktop/scripts/get-tor-windows.py +++ b/desktop/scripts/get-tor-windows.py @@ -46,7 +46,7 @@ def main(): ) working_path = os.path.join(root_path, "build", "tor") exe_path = os.path.join(working_path, exe_filename) - dist_path = os.path.join(root_path, "src", "onionshare", "resources", "tor") + dist_path = os.path.join(root_path, "onionshare", "resources", "tor") # Make sure the working folder exists if not os.path.exists(working_path): diff --git a/desktop/scripts/rebuild-cli.py b/desktop/scripts/rebuild-cli.py deleted file mode 100755 index f9a43554..00000000 --- a/desktop/scripts/rebuild-cli.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/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 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)]) - subprocess.call(["pip", "install", "typing-extensions"]) - - -if __name__ == "__main__": - main()