From 4b23f660192cb8b2f602dfc7478ee3fdf9d59c41 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Mon, 2 Dec 2019 15:07:07 -0800 Subject: [PATCH 01/14] Update readme --- README.md | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index e5b9b9e..3553705 100644 --- a/README.md +++ b/README.md @@ -20,29 +20,21 @@ and then you forget about it. GPG Sync takes care of everything else. GPG Sync complies with the in-progress [Distributing OpenPGP Keys with Signed Keylist Subscriptions](https://datatracker.ietf.org/doc/draft-mccain-keylist/) internet standard draft. -### Important note about keyservers - -By default, GPG Sync downloads PGP public keys from [keys.openpgp.org](https://keys.openpgp.org/about), a modern abuse-resistent keyserver. (The old SKS keyserver pool is vulnerable to [certificate flooding](https://dkg.fifthhorseman.net/blog/openpgp-certificate-flooding.html) attacks, and it's based on unmaintained software that will likely never get fixed.) - -For this reason, **it's important that your authority key, as well as every key on your keylist, has a user ID that contains an email address** and that **all users must opt-in to allowing their email addresses** on this keyserver. You can opt-in by uploading your public key [here](https://keys.openpgp.org/upload), requesting to verify each email address on it, and then clicking the links you receive in those verification emails. - -If a member of your organization doesn't opt-in to allowing their email addresses on this keyserver, then when subscribers of your keylist refresh it, the public key that GPG Sync will import won't contain the information necessary to be able to send that member an encrypted email. GPG Sync still supports the legacy, vulnerable SKS keyserver network; this can be enabled in the advanced settings of each keylist. - ## Learn More To learn how GPG Sync works and how to use it, check out the [Wiki](https://github.com/firstlookmedia/gpgsync/wiki). ## Getting GPG Sync -Download macOS and Windows binaries from the [Releases](https://github.com/firstlookmedia/gpgsync/releases) page. +To install GPG Sync, follow [these instructions](https://github.com/firstlookmedia/gpgsync/wiki/Installing-GPG-Sync). -macOS users can also use [Homebrew](https://brew.sh/): +## Important note about keyservers -```sh -brew cask install gpg-sync -``` +By default, GPG Sync downloads PGP public keys from [keys.openpgp.org](https://keys.openpgp.org/about), a modern abuse-resistent keyserver. (The old SKS keyserver pool is vulnerable to [certificate flooding](https://dkg.fifthhorseman.net/blog/openpgp-certificate-flooding.html) attacks, and it's based on unmaintained software that will likely never get fixed.) -Linux users should follow these [simple instructions](https://github.com/firstlookmedia/gpgsync/blob/master/BUILD.md#linux-distributions) to build GPG Sync from source. +For this reason, **it's important that your authority key, as well as every key on your keylist, has a user ID that contains an email address** and that **all users must opt-in to allowing their email addresses** on this keyserver. You can opt-in by uploading your public key [here](https://keys.openpgp.org/upload), requesting to verify each email address on it, and then clicking the links you receive in those verification emails. + +If a member of your organization doesn't opt-in to allowing their email addresses on this keyserver, then when subscribers of your keylist refresh it, the public key that GPG Sync will import won't contain the information necessary to be able to send that member an encrypted email. GPG Sync still supports the legacy, vulnerable SKS keyserver network; this can be enabled in the advanced settings of each keylist. ## Test Status From 866ed6129f51d14224ad9302cae59ea180580710 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Mon, 2 Dec 2019 16:26:00 -0800 Subject: [PATCH 02/14] Build instruction fixes, and Windows version fix, for 0.3.5 --- BUILD.md | 14 +++++++------- install/build_exe.bat | 2 +- install/gpgsync.nsi | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/BUILD.md b/BUILD.md index 92f6aef..7b8b26f 100644 --- a/BUILD.md +++ b/BUILD.md @@ -23,7 +23,7 @@ pipenv run ./dev_scripts/gpgsync Here's how you build an app bundle: ```sh -install/build_app.sh +pipenv run install/build_app.sh ``` Now you should have `dist/GPG Sync.app`. @@ -31,8 +31,8 @@ Now you should have `dist/GPG Sync.app`. To build a .pkg for distribution: ```sh -install/build_pkg.sh # this requires codesigning certificates -install/build_pkg.sh --without-codesign # this doesn't +pipenv run install/build_pkg.sh # this requires codesigning certificates +pipenv run install/build_pkg.sh --without-codesign # this doesn't ``` Now you should have `dist/GPGSync-{version}.pkg`. @@ -44,7 +44,7 @@ Download Python 3.8.0, 32-bit (x86) from https://www.python.org/downloads/releas Open a command prompt and cd to the gpgsync folder. If you don't have it already, install pipenv (`pip install pipenv`). Then install dependencies: ```cmd -pipenv install --dev +python -m pipenv install --dev ``` Install the Qt 5.13.2 from https://www.qt.io/offline-installers. I downloaded `qt-opensource-windows-x86-5.13.2.exe`. In the installer, you can skip making an account, and all you need `Qt` > `Qt 5.13.2` > `MSVC 2017 32-bit`. @@ -52,7 +52,7 @@ Install the Qt 5.13.2 from https://www.qt.io/offline-installers. I downloaded `q After that you can launch GPG Sync during development with: ``` -pipenv run python dev_scripts\gpgsync -v +python -m pipenv run python dev_scripts\gpgsync -v ``` ### To make a .exe: @@ -257,7 +257,7 @@ To make a macOS release, go to macOS build machine: - Build machine should be running macOS 10.13 - Verify and checkout the git tag for this release -- Run `./install/build_app.sh`; this will make `dist/GPG Sync.app` but won't codesign it +- Run `pipenv run ./install/build_app.sh`; this will make `dist/GPG Sync.app` but won't codesign it - Copy `dist/GPG Sync.app` from the build machine to the `dist` folder on the release machine Then move to the macOS release machine: @@ -266,7 +266,7 @@ Then move to the macOS release machine: - Apple-trusted `Developer ID Application: FIRST LOOK PRODUCTIONS, INC.` and `Developer ID Installer: FIRST LOOK PRODUCTIONS, INC.` code-signing certificates installed - An app-specific Apple ID password saved in the login keychain called `gpgsync-notarize` - Verify and checkout the git tag for this release -- Run `./install/build_pkg.sh`; this will make a codesigned installer package called `dist/GPGSync-$VERSION.pkg` +- Run `pipenv run ./install/build_pkg.sh`; this will make a codesigned installer package called `dist/GPGSync-$VERSION.pkg` - Notarize it: `xcrun altool --notarize-app --primary-bundle-id "org.firstlook.gpgsync" -u "micah@firstlook.org" -p "@keychain:gpgsync-notarize" --file GPGSync-$VERSION.pkg` - Wait for it to get approved, check status with: `xcrun altool --notarization-history 0 -u "micah@firstlook.org" -p "@keychain:gpgsync-notarize"` - After it's approved, staple the ticket: `xcrun stapler staple GPGSync-$VERSION.pkg` diff --git a/install/build_exe.bat b/install/build_exe.bat index bdede69..931ff84 100644 --- a/install/build_exe.bat +++ b/install/build_exe.bat @@ -2,7 +2,7 @@ REM delete old dist files rmdir /s /q dist REM build gpgsync.exe -pyinstaller install\pyinstaller.spec -y +python -m pipenv run pyinstaller install\pyinstaller.spec -y REM codesign gpgsync.exe signtool.exe sign /v /d "GPG Sync" /a /tr http://time.certum.pl/ dist\gpgsync\gpgsync.exe diff --git a/install/gpgsync.nsi b/install/gpgsync.nsi index 1c7c4eb..ef11267 100644 --- a/install/gpgsync.nsi +++ b/install/gpgsync.nsi @@ -7,7 +7,7 @@ !define INSTALLSIZE 76759 !define VERSIONMAJOR 0 !define VERSIONMINOR 3 -!define VERSIONSTRING "0.3.4" +!define VERSIONSTRING "0.3.5" RequestExecutionLevel admin From 9f82bf462582325caa89d6d26e2757ddb21eb4fd Mon Sep 17 00:00:00 2001 From: David Huerta Date: Wed, 26 Feb 2020 19:23:35 -0500 Subject: [PATCH 03/14] Adds README note on keylist JSON format --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3553705..ec8938a 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,11 @@ single trusted person in your organization. As a member of an organization, you install GPG Sync on your computer, configure it with a few settings, and then you forget about it. GPG Sync takes care of everything else. -GPG Sync complies with the in-progress [Distributing OpenPGP Keys with Signed Keylist Subscriptions](https://datatracker.ietf.org/doc/draft-mccain-keylist/) +A single keylist is used by GPG Sync to keep keys in sync. This keylist +must follow a specific JSON format, see [our example](https://github.com/firstlookmedia/gpgsync/blob/develop/example-keylist/keylist.json) +for guidance on creating one for your organization if it does not already +exist. GPG Sync complies with the in-progress +[Distributing OpenPGP Keys with Signed Keylist Subscriptions](https://datatracker.ietf.org/doc/draft-mccain-keylist/) internet standard draft. ## Learn More From f01fa04c5d3b32e4400858bd93a74c806d83ff26 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Mon, 27 Apr 2020 14:45:31 -0700 Subject: [PATCH 04/14] Build package for ubuntu 20.04 in CI --- .circleci/config.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 48ea990..95b2f4a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -94,6 +94,30 @@ jobs: package_cloud push firstlookmedia/code/ubuntu/eoan deb_dist/gpgsync_${VERSION}-1_all.deb package_cloud push firstlookmedia/code/ubuntu/eoan deb_dist/gpgsync_${VERSION}-1.dsc + build-ubuntu-focal: + docker: + - image: ubuntu:20.04 + steps: + - run: + name: Install dependencies + command: | + apt-get update + DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all python3-all dh-python python3-pyqt5 python3-stdeb python3-requests python3-socks python3-packaging python3-dateutil python3-pytest python3-pytest-runner gnupg2 + gem install --no-ri --no-rdoc rake + gem install --no-ri --no-rdoc package_cloud + - checkout + - run: + name: Create the .deb package + command: | + ./install/build_deb.sh + dpkg -i deb_dist/gpgsync_*.deb + - run: + name: Deploy to packagecloud.io + command: | + VERSION=$(cat share/version |cut -dv -f2) + package_cloud push firstlookmedia/code/ubuntu/focal deb_dist/gpgsync_${VERSION}-1_all.deb + package_cloud push firstlookmedia/code/ubuntu/focal deb_dist/gpgsync_${VERSION}-1.dsc + build-debian-buster: docker: - image: debian:buster @@ -211,6 +235,12 @@ workflows: only: /^v.*/ branches: ignore: /.*/ + - build-ubuntu-focal: + filters: + tags: + only: /^v.*/ + branches: + ignore: /.*/ - build-debian-buster: filters: tags: From b820f934575a0db4b190a2675e13a1cae6eabc42 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 4 Feb 2021 13:23:16 -0800 Subject: [PATCH 05/14] Switch from pipenv to poetry --- BUILD.md | 28 +++--- Pipfile | 22 ----- Pipfile.lock | 260 ------------------------------------------------- poetry.lock | 255 ++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 24 +++++ 5 files changed, 291 insertions(+), 298 deletions(-) delete mode 100644 Pipfile delete mode 100644 Pipfile.lock create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/BUILD.md b/BUILD.md index 7b8b26f..13e1438 100644 --- a/BUILD.md +++ b/BUILD.md @@ -2,28 +2,24 @@ ## Mac OS X -Install Xcode from the Mac App Store. Once it's installed, run it for the first time to set it up. Also, run this to make sure command line tools are installed: `xcode-select --install`. And finally, open Xcode, go to Preferences > Locations, and make sure under Command Line Tools you select an installed version from the dropdown. (This is required for installing Qt5.) +Download and install Python 3.9.1 from https://www.python.org/downloads/release/python-391/. I downloaded `python-3.9.1-macosx10.9.pkg`. -Download and install Python 3.8.0 from https://www.python.org/downloads/release/python-380/. I downloaded `python-3.8.0-macosx10.9.pkg`. - -Install Qt 5.13.2 for macOS from https://www.qt.io/offline-installers. I downloaded `qt-opensource-mac-x64-5.13.2.dmg`. In the installer, you can skip making an account, and all you need is `Qt` > `Qt 5.13.2` > `macOS`. (The Qt installer has not been notarized yet, so if you're running macOS Catalina, it will take a very long time to open the first time and you'll see an error. To get past it you'll need to right-click on the dmg file, choose Open, and when you see the popup saying the software can't be authenticated, click Open again.) - -If you don't have it already, install pipenv (`pip3 install --user pipenv`). Then install dependencies: +Make sure you have `poetry` installed (`pip3 install --user poetry`), then install dependencies: ```sh -pipenv install --dev +poetry install ``` Here's how you run GPG Sync, without having to build an app bundle: ```sh -pipenv run ./dev_scripts/gpgsync +poetry run ./dev_scripts/gpgsync ``` Here's how you build an app bundle: ```sh -pipenv run install/build_app.sh +poetry run install/build_app.sh ``` Now you should have `dist/GPG Sync.app`. @@ -31,8 +27,8 @@ Now you should have `dist/GPG Sync.app`. To build a .pkg for distribution: ```sh -pipenv run install/build_pkg.sh # this requires codesigning certificates -pipenv run install/build_pkg.sh --without-codesign # this doesn't +poetry run install/build_pkg.sh # this requires codesigning certificates +poetry run install/build_pkg.sh --without-codesign # this doesn't ``` Now you should have `dist/GPGSync-{version}.pkg`. @@ -41,10 +37,10 @@ Now you should have `dist/GPGSync-{version}.pkg`. Download Python 3.8.0, 32-bit (x86) from https://www.python.org/downloads/release/python-380/. I downloaded `python-3.8.0.exe`. When installing it, make sure to check the "Add Python 3.8 to PATH" checkbox on the first page of the installer. -Open a command prompt and cd to the gpgsync folder. If you don't have it already, install pipenv (`pip install pipenv`). Then install dependencies: +Open a command prompt and cd to the gpgsync folder. If you don't have it already, install poetry (`pip install poetry`). Then install dependencies: ```cmd -python -m pipenv install --dev +python -m poetry install ``` Install the Qt 5.13.2 from https://www.qt.io/offline-installers. I downloaded `qt-opensource-windows-x86-5.13.2.exe`. In the installer, you can skip making an account, and all you need `Qt` > `Qt 5.13.2` > `MSVC 2017 32-bit`. @@ -52,7 +48,7 @@ Install the Qt 5.13.2 from https://www.qt.io/offline-installers. I downloaded `q After that you can launch GPG Sync during development with: ``` -python -m pipenv run python dev_scripts\gpgsync -v +python -m poetry run python dev_scripts\gpgsync -v ``` ### To make a .exe: @@ -257,7 +253,7 @@ To make a macOS release, go to macOS build machine: - Build machine should be running macOS 10.13 - Verify and checkout the git tag for this release -- Run `pipenv run ./install/build_app.sh`; this will make `dist/GPG Sync.app` but won't codesign it +- Run `poetry run ./install/build_app.sh`; this will make `dist/GPG Sync.app` but won't codesign it - Copy `dist/GPG Sync.app` from the build machine to the `dist` folder on the release machine Then move to the macOS release machine: @@ -266,7 +262,7 @@ Then move to the macOS release machine: - Apple-trusted `Developer ID Application: FIRST LOOK PRODUCTIONS, INC.` and `Developer ID Installer: FIRST LOOK PRODUCTIONS, INC.` code-signing certificates installed - An app-specific Apple ID password saved in the login keychain called `gpgsync-notarize` - Verify and checkout the git tag for this release -- Run `pipenv run ./install/build_pkg.sh`; this will make a codesigned installer package called `dist/GPGSync-$VERSION.pkg` +- Run `poetry run ./install/build_pkg.sh`; this will make a codesigned installer package called `dist/GPGSync-$VERSION.pkg` - Notarize it: `xcrun altool --notarize-app --primary-bundle-id "org.firstlook.gpgsync" -u "micah@firstlook.org" -p "@keychain:gpgsync-notarize" --file GPGSync-$VERSION.pkg` - Wait for it to get approved, check status with: `xcrun altool --notarization-history 0 -u "micah@firstlook.org" -p "@keychain:gpgsync-notarize"` - After it's approved, staple the ticket: `xcrun stapler staple GPGSync-$VERSION.pkg` diff --git a/Pipfile b/Pipfile deleted file mode 100644 index 52e7dae..0000000 --- a/Pipfile +++ /dev/null @@ -1,22 +0,0 @@ -[[source]] -name = "pypi" -url = "https://pypi.org/simple" -verify_ssl = true - -[dev-packages] -pytest = "*" -pytest-runner = "*" -pyinstaller = { version = "*", platform_system = "== 'Darwin'" } - -[packages] -pyqt5 = "*" -pysocks = "*" -python-dateutil = "*" -requests = "*" -pyobjc-core = { version = "*", platform_system = "== 'Darwin'" } -pyobjc-framework-cocoa = { version = "*", platform_system = "== 'Darwin'" } -pyobjc-framework-quartz = { version = "*", platform_system = "== 'Darwin'" } -pywin32 = { version = "*", platform_system = "== 'Windows'" } - -[requires] -python_version = "3" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index c106ca8..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,260 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "cc7924d0109a6c4554a30b526cce1da7fa622759ca72fa2143541dab8adcf118" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "certifi": { - "hashes": [ - "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", - "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f" - ], - "version": "==2019.11.28" - }, - "chardet": { - "hashes": [ - "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", - "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" - ], - "version": "==3.0.4" - }, - "idna": { - "hashes": [ - "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", - "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" - ], - "version": "==2.8" - }, - "pyobjc-core": { - "hashes": [ - "sha256:1a0fbf012fb575e0adf8c18cfd4453e657cc2c0deb2660c529bf524ba4c9149a", - "sha256:470ccd754efb468a59426942673dfc3c5c59f33a5b8cae8a7fc1be975c2d4128", - "sha256:751cdeb436cb181af2e2413015b072075590577c410c7f345080a38dd028b8ec", - "sha256:8ccf44511cbe438fa6562c423c0c5f1dad7cfc0eadd6d8f112840f8845b44fda" - ], - "index": "pypi", - "markers": "platform_system == 'Darwin'", - "version": "==6.1" - }, - "pyobjc-framework-cocoa": { - "hashes": [ - "sha256:1dc428f867d35007ddf9de5b24eff5bfdf65c58b1d610abcb08bebd94c343312", - "sha256:245e19156739f8068db474ad9561079cc698f08ef525e299b8eedc5531e02801", - "sha256:32ba4d0ce811e2088bf0fc360c9545c06586934e895f7133655b8f2182e7019a", - "sha256:c4077d2e6f96e4f3fd9780d66778cf51d27f414822498b24410e9df7a6a4d531" - ], - "index": "pypi", - "markers": "platform_system == 'Darwin'", - "version": "==6.1" - }, - "pyobjc-framework-quartz": { - "hashes": [ - "sha256:033d1f207d7f59fabe98fff71f472bd9b9286a2cfecbc9e732006df4bdbed417", - "sha256:089676c603527350dcff9701c22335335e3f3112b471996cdc57939b9c542932", - "sha256:dc96a7c8b22264579f5438e2f9fc6c7f905412c5b297a750acce00f50aa87ca5", - "sha256:f9f251d0572a0b8b643c990dcbed2b55127cebaf8102487189cbffaedb2bd696" - ], - "index": "pypi", - "markers": "platform_system == 'Darwin'", - "version": "==6.1" - }, - "pyqt5": { - "hashes": [ - "sha256:14737bb4673868d15fa91dad79fe293d7a93d76c56d01b3757b350b8dcb32b2d", - "sha256:1936c321301f678d4e6703d52860e1955e5c4964e6fd00a1f86725ce5c29083c", - "sha256:3f79de6e9f29e858516cc36ffc2b992e262af841f3799246aec282b76a3eccdf", - "sha256:509daab1c5aca22e3cf9508128abf38e6e5ae311d7426b21f4189ffd66b196e9" - ], - "index": "pypi", - "version": "==5.13.2" - }, - "pyqt5-sip": { - "hashes": [ - "sha256:02d94786bada670ab17a2b62ce95b3cf8e3b40c99d36007593a6334d551840bb", - "sha256:06bc66b50556fb949f14875a4c224423dbf03f972497ccb883fb19b7b7c3b346", - "sha256:091fbbe10a7aebadc0e8897a9449cda08d3c3f663460d812eca3001ca1ed3526", - "sha256:0a067ade558befe4d46335b13d8b602b5044363bfd601419b556d4ec659bca18", - "sha256:1910c1cb5a388d4e59ebb2895d7015f360f3f6eeb1700e7e33e866c53137eb9e", - "sha256:1c7ad791ec86247f35243bbbdd29cd59989afbe0ab678e0a41211f4407f21dd8", - "sha256:3c330ff1f70b3eaa6f63dce9274df996dffea82ad9726aa8e3d6cbe38e986b2f", - "sha256:482a910fa73ee0e36c258d7646ef38f8061774bbc1765a7da68c65056b573341", - "sha256:7695dfafb4f5549ce1290ae643d6508dfc2646a9003c989218be3ce42a1aa422", - "sha256:8274ed50f4ffbe91d0f4cc5454394631edfecd75dc327aa01be8bc5818a57e88", - "sha256:9047d887d97663790d811ac4e0d2e895f1bf2ecac4041691487de40c30239480", - "sha256:9f6ab1417ecfa6c1ce6ce941e0cebc03e3ec9cd9925058043229a5f003ae5e40", - "sha256:b43ba2f18999d41c3df72f590348152e14cd4f6dcea2058c734d688dfb1ec61f", - "sha256:c3ab9ea1bc3f4ce8c57ebc66fb25cd044ef92ed1ca2afa3729854ecc59658905", - "sha256:da69ba17f6ece9a85617743cb19de689f2d63025bf8001e2facee2ec9bcff18f", - "sha256:ef3c7a0bf78674b0dda86ff5809d8495019903a096c128e1f160984b37848f73", - "sha256:fabff832046643cdb93920ddaa8f77344df90768930fbe6bb33d211c4dcd0b5e" - ], - "version": "==12.7.0" - }, - "pysocks": { - "hashes": [ - "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299", - "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5", - "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0" - ], - "index": "pypi", - "version": "==1.7.1" - }, - "python-dateutil": { - "hashes": [ - "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", - "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" - ], - "index": "pypi", - "version": "==2.8.1" - }, - "pywin32": { - "hashes": [ - "sha256:300a2db938e98c3e7e2093e4491439e62287d0d493fe07cce110db070b54c0be", - "sha256:31f88a89139cb2adc40f8f0e65ee56a8c585f629974f9e07622ba80199057511", - "sha256:371fcc39416d736401f0274dd64c2302728c9e034808e37381b5e1b22be4a6b0", - "sha256:47a3c7551376a865dd8d095a98deba954a98f326c6fe3c72d8726ca6e6b15507", - "sha256:4cdad3e84191194ea6d0dd1b1b9bdda574ff563177d2adf2b4efec2a244fa116", - "sha256:7c1ae32c489dc012930787f06244426f8356e129184a02c25aef163917ce158e", - "sha256:7f18199fbf29ca99dff10e1f09451582ae9e372a892ff03a28528a24d55875bc", - "sha256:9b31e009564fb95db160f154e2aa195ed66bcc4c058ed72850d047141b36f3a2", - "sha256:a929a4af626e530383a579431b70e512e736e9588106715215bf685a3ea508d4", - "sha256:c054c52ba46e7eb6b7d7dfae4dbd987a1bb48ee86debe3f245a2884ece46e295", - "sha256:f27cec5e7f588c3d1051651830ecc00294f90728d19c3bf6916e6dba93ea357c", - "sha256:f4c5be1a293bae0076d93c88f37ee8da68136744588bc5e2be2f299a34ceb7aa" - ], - "index": "pypi", - "markers": "platform_system == 'Windows'", - "version": "==227" - }, - "requests": { - "hashes": [ - "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", - "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" - ], - "index": "pypi", - "version": "==2.22.0" - }, - "six": { - "hashes": [ - "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", - "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" - ], - "version": "==1.13.0" - }, - "urllib3": { - "hashes": [ - "sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293", - "sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745" - ], - "version": "==1.25.7" - } - }, - "develop": { - "altgraph": { - "hashes": [ - "sha256:d6814989f242b2b43025cba7161fc1b8fb487a62cd49c49245d6fd01c18ac997", - "sha256:ddf5320017147ba7b810198e0b6619bd7b5563aa034da388cea8546b877f9b0c" - ], - "version": "==0.16.1" - }, - "attrs": { - "hashes": [ - "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", - "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" - ], - "version": "==19.3.0" - }, - "macholib": { - "hashes": [ - "sha256:ac02d29898cf66f27510d8f39e9112ae00590adb4a48ec57b25028d6962b1ae1", - "sha256:c4180ffc6f909bf8db6cd81cff4b6f601d575568f4d5dee148c830e9851eb9db" - ], - "version": "==1.11" - }, - "more-itertools": { - "hashes": [ - "sha256:53ff73f186307d9c8ef17a9600309154a6ae27f25579e80af4db8f047ba14bc2", - "sha256:a0ea684c39bc4315ba7aae406596ef191fd84f873d2d2751f84d64e81a7a2d45" - ], - "version": "==8.0.0" - }, - "packaging": { - "hashes": [ - "sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47", - "sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108" - ], - "version": "==19.2" - }, - "pluggy": { - "hashes": [ - "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", - "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" - ], - "version": "==0.13.1" - }, - "py": { - "hashes": [ - "sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa", - "sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53" - ], - "version": "==1.8.0" - }, - "pyinstaller": { - "hashes": [ - "sha256:ee7504022d1332a3324250faf2135ea56ac71fdb6309cff8cd235de26b1d0a96" - ], - "index": "pypi", - "markers": "platform_system == 'Darwin'", - "version": "==3.5" - }, - "pyparsing": { - "hashes": [ - "sha256:20f995ecd72f2a1f4bf6b072b63b22e2eb457836601e76d6e5dfcd75436acc1f", - "sha256:4ca62001be367f01bd3e92ecbb79070272a9d4964dce6a48a82ff0b8bc7e683a" - ], - "version": "==2.4.5" - }, - "pytest": { - "hashes": [ - "sha256:63344a2e3bce2e4d522fd62b4fdebb647c019f1f9e4ca075debbd13219db4418", - "sha256:f67403f33b2b1d25a6756184077394167fe5e2f9d8bdaab30707d19ccec35427" - ], - "index": "pypi", - "version": "==5.3.1" - }, - "pytest-runner": { - "hashes": [ - "sha256:5534b08b133ef9a5e2c22c7886a8f8508c95bb0b0bdc6cc13214f269c3c70d51", - "sha256:96c7e73ead7b93e388c5d614770d2bae6526efd997757d3543fe17b557a0942b" - ], - "index": "pypi", - "version": "==5.2" - }, - "six": { - "hashes": [ - "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", - "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" - ], - "version": "==1.13.0" - }, - "wcwidth": { - "hashes": [ - "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", - "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c" - ], - "version": "==0.1.7" - } - } -} diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..f7b1549 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,255 @@ +[[package]] +name = "certifi" +version = "2020.12.5" +description = "Python package for providing Mozilla's CA Bundle." +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "chardet" +version = "4.0.0" +description = "Universal encoding detector for Python 2 and 3" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "idna" +version = "2.10" +description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "packaging" +version = "20.9" +description = "Core utilities for Python packages" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.dependencies] +pyparsing = ">=2.0.2" + +[[package]] +name = "pyobjc-core" +version = "7.0.1" +description = "Python<->ObjC Interoperability Module" +category = "main" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pyobjc-framework-cocoa" +version = "7.0.1" +description = "Wrappers for the Cocoa frameworks on macOS" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyobjc-core = ">=7.0.1" + +[[package]] +name = "pyobjc-framework-quartz" +version = "7.0.1" +description = "Wrappers for the Quartz frameworks on macOS" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyobjc-core = ">=7.0.1" +pyobjc-framework-Cocoa = ">=7.0.1" + +[[package]] +name = "pyparsing" +version = "2.4.7" +description = "Python parsing module" +category = "main" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "pyside2" +version = "5.15.2" +description = "Python bindings for the Qt cross-platform application and UI framework" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <3.10" + +[package.dependencies] +shiboken2 = "5.15.2" + +[[package]] +name = "pysocks" +version = "1.7.1" +description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "python-dateutil" +version = "2.8.1" +description = "Extensions to the standard Python datetime module" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pywin32" +version = "300" +description = "Python for Window Extensions" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "requests" +version = "2.25.1" +description = "Python HTTP for Humans." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +certifi = ">=2017.4.17" +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"] + +[[package]] +name = "shiboken2" +version = "5.15.2" +description = "Python / C++ bindings helper module" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <3.10" + +[[package]] +name = "six" +version = "1.15.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "urllib3" +version = "1.26.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" + +[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)"] + +[metadata] +lock-version = "1.1" +python-versions = ">=3.8,<3.10" +content-hash = "cdb65fe6b80c79031014b1db3768e8e02f52591255daa5ab854d650803e8798e" + +[metadata.files] +certifi = [ + {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-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, + {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, +] +idna = [ + {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, + {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, +] +packaging = [ + {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, + {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, +] +pyobjc-core = [ + {file = "pyobjc-core-7.0.1.tar.gz", hash = "sha256:7213bfd48c49f5b4d479256924e0120d728ed449de8188cba9e204c434ed07f2"}, + {file = "pyobjc_core-7.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6f84a5744e44ec709daca1e66b95c3c010e4159bc2cfc442c27c0d28b0456eda"}, + {file = "pyobjc_core-7.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2fdba7997d5c9d518256f9d2e9f7780fcc6332b0371207374f38d7e9fad7bc8"}, + {file = "pyobjc_core-7.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:758cf96f3848c6e177d6ad94d44fec1b9ea5e32ca066513184d8f1e70d71ff6e"}, + {file = "pyobjc_core-7.0.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:61c756c9bd5c55e9137cf0549f1d931dd1e1bff30a1cc97e46e55b94d5dc5d97"}, +] +pyobjc-framework-cocoa = [ + {file = "pyobjc-framework-Cocoa-7.0.1.tar.gz", hash = "sha256:8a545b47b2021884bd8e5644ac32ee6d99a1f8e6a45cab3e6d1b999adf968630"}, + {file = "pyobjc_framework_Cocoa-7.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4675accc4720b42f456a35ba7cdd9e1cb44b9b84fcc600beef120ae05d2c5d27"}, + {file = "pyobjc_framework_Cocoa-7.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:42e106c3d688e66b1032b0819daa842a78eff6f7646b5af4be8774d0c8f5e200"}, + {file = "pyobjc_framework_Cocoa-7.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8aa715fa1ff367330fc58eadc1747e222bdf854b9ece6936487c9c4f4e2627d3"}, + {file = "pyobjc_framework_Cocoa-7.0.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:1d9de6b0612a5e24899522a797425c834405a536db41ba06a19df01b7008eeae"}, +] +pyobjc-framework-quartz = [ + {file = "pyobjc-framework-Quartz-7.0.1.tar.gz", hash = "sha256:8d76cabfbae38102301f44f1edb3ab4c959f18ed0c828cfff1693a3c559945ef"}, + {file = "pyobjc_framework_Quartz-7.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fbf8d816da04f0705707906fb751bd360d652914ace3989ed6e55ff6a7a79c62"}, + {file = "pyobjc_framework_Quartz-7.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a1854a0b8baea76e6c43812ecf26dd6fc5a11e9cada212b36bf35e23e670750c"}, + {file = "pyobjc_framework_Quartz-7.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:019982c0c1a74e68f29c9f961292d4c752a8fdd6d806197a73a41aa6c9fa00a9"}, + {file = "pyobjc_framework_Quartz-7.0.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:9be4d99d04abd9f9147cc9e83b87324efc0b832320caee310defc71798201816"}, +] +pyparsing = [ + {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, + {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, +] +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"}, + {file = "PySide2-5.15.2-5.15.2-cp35.cp36.cp37.cp38.cp39-abi3-macosx_10_13_intel.whl", hash = "sha256:976cacf01ef3b397a680f9228af7d3d6273b9254457ad4204731507c1f9e6c3c"}, + {file = "PySide2-5.15.2-5.15.2-cp35.cp36.cp37.cp38.cp39-abi3-manylinux1_x86_64.whl", hash = "sha256:081d8c8a6c65fb1392856a547814c0c014e25ac04b38b987d9a3483e879e9634"}, + {file = "PySide2-5.15.2-5.15.2-cp35.cp36.cp37.cp38.cp39-none-win32.whl", hash = "sha256:087a0b719bb967405ea85fd202757c761f1fc73d0e2397bc3a6a15376782ee75"}, + {file = "PySide2-5.15.2-5.15.2-cp35.cp36.cp37.cp38.cp39-none-win_amd64.whl", hash = "sha256:1316aa22dd330df096daf7b0defe9c00297a66e0b4907f057aaa3e88c53d1aff"}, +] +pysocks = [ + {file = "PySocks-1.7.1-py27-none-any.whl", hash = "sha256:08e69f092cc6dbe92a0fdd16eeb9b9ffbc13cadfe5ca4c7bd92ffb078b293299"}, + {file = "PySocks-1.7.1-py3-none-any.whl", hash = "sha256:2725bd0a9925919b9b51739eea5f9e2bae91e83288108a9ad338b2e3a4435ee5"}, + {file = "PySocks-1.7.1.tar.gz", hash = "sha256:3f8804571ebe159c380ac6de37643bb4685970655d3bba243530d6558b799aa0"}, +] +python-dateutil = [ + {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, + {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, +] +pywin32 = [ + {file = "pywin32-300-cp35-cp35m-win32.whl", hash = "sha256:1c204a81daed2089e55d11eefa4826c05e604d27fe2be40b6bf8db7b6a39da63"}, + {file = "pywin32-300-cp35-cp35m-win_amd64.whl", hash = "sha256:350c5644775736351b77ba68da09a39c760d75d2467ecec37bd3c36a94fbed64"}, + {file = "pywin32-300-cp36-cp36m-win32.whl", hash = "sha256:a3b4c48c852d4107e8a8ec980b76c94ce596ea66d60f7a697582ea9dce7e0db7"}, + {file = "pywin32-300-cp36-cp36m-win_amd64.whl", hash = "sha256:27a30b887afbf05a9cbb05e3ffd43104a9b71ce292f64a635389dbad0ed1cd85"}, + {file = "pywin32-300-cp37-cp37m-win32.whl", hash = "sha256:d7e8c7efc221f10d6400c19c32a031add1c4a58733298c09216f57b4fde110dc"}, + {file = "pywin32-300-cp37-cp37m-win_amd64.whl", hash = "sha256:8151e4d7a19262d6694162d6da85d99a16f8b908949797fd99c83a0bfaf5807d"}, + {file = "pywin32-300-cp38-cp38-win32.whl", hash = "sha256:fbb3b1b0fbd0b4fc2a3d1d81fe0783e30062c1abed1d17c32b7879d55858cfae"}, + {file = "pywin32-300-cp38-cp38-win_amd64.whl", hash = "sha256:60a8fa361091b2eea27f15718f8eb7f9297e8d51b54dbc4f55f3d238093d5190"}, + {file = "pywin32-300-cp39-cp39-win32.whl", hash = "sha256:638b68eea5cfc8def537e43e9554747f8dee786b090e47ead94bfdafdb0f2f50"}, + {file = "pywin32-300-cp39-cp39-win_amd64.whl", hash = "sha256:b1609ce9bd5c411b81f941b246d683d6508992093203d4eb7f278f4ed1085c3f"}, +] +requests = [ + {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, + {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, +] +shiboken2 = [ + {file = "shiboken2-5.15.2-5.15.2-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:03f41b0693b91c7f89627f1085a4ecbe8591c03f904118a034854d935e0e766c"}, + {file = "shiboken2-5.15.2-5.15.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ae8ca41274cfa057106268b6249674ca669c5b21009ec49b16d77665ab9619ed"}, + {file = "shiboken2-5.15.2-5.15.2-cp35.cp36.cp37.cp38.cp39-abi3-macosx_10_13_intel.whl", hash = "sha256:edc12a4df2b5be7ca1e762ab94e331ba9e2fbfe3932c20378d8aa3f73f90e0af"}, + {file = "shiboken2-5.15.2-5.15.2-cp35.cp36.cp37.cp38.cp39-abi3-manylinux1_x86_64.whl", hash = "sha256:4aee1b91e339578f9831e824ce2a1ec3ba3a463f41fda8946b4547c7eb3cba86"}, + {file = "shiboken2-5.15.2-5.15.2-cp35.cp36.cp37.cp38.cp39-none-win32.whl", hash = "sha256:89c157a0e2271909330e1655892e7039249f7b79a64a443d52c512337065cde0"}, + {file = "shiboken2-5.15.2-5.15.2-cp35.cp36.cp37.cp38.cp39-none-win_amd64.whl", hash = "sha256:14a33169cf1bd919e4c4c4408fffbcd424c919a3f702df412b8d72b694e4c1d5"}, +] +six = [ + {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, + {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, +] +urllib3 = [ + {file = "urllib3-1.26.3-py2.py3-none-any.whl", hash = "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80"}, + {file = "urllib3-1.26.3.tar.gz", hash = "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..5fce4bc --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[tool.poetry] +name = "gpgsync" +version = "0.3.6" +description = "GPG Sync is designed to let users always have up-to-date public keys for other members of their organization" +authors = ["Micah Lee "] +license = "GPLv3" + +[tool.poetry.dependencies] +python = ">=3.8,<3.10" +PySide2 = "^5.15.2" +PySocks = "^1.7.1" +python-dateutil = "^2.8.1" +requests = "^2.25.1" +pywin32 = {version = "^300", platform = "win32"} +pyobjc-core = {version = "7.0.1", platform = "darwin"} +pyobjc-framework-cocoa = {version = "7.0.1", platform = "darwin"} +pyobjc-framework-quartz = {version = "7.0.1", platform = "darwin"} +packaging = "^20.9" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" From fc1d7b2430918b7696e505eb5b5211cb052038ad Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 4 Feb 2021 13:35:07 -0800 Subject: [PATCH 06/14] Change from PyQt5 to PySide2 --- gpgsync/gui/__init__.py | 2 +- gpgsync/gui/gui_common.py | 2 +- gpgsync/gui/keylist_dialog.py | 6 +++--- gpgsync/gui/keylist_list.py | 6 +++--- gpgsync/gui/main_window.py | 2 +- gpgsync/gui/settings_dialog.py | 2 +- gpgsync/gui/systray.py | 14 +++++++------- gpgsync/gui/threads.py | 8 ++++---- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/gpgsync/gui/__init__.py b/gpgsync/gui/__init__.py index 1f861c7..5bffee9 100644 --- a/gpgsync/gui/__init__.py +++ b/gpgsync/gui/__init__.py @@ -19,7 +19,7 @@ along with this program. If not, see . """ import sys -from PyQt5 import QtCore, QtWidgets +from PySide2 import QtCore, QtWidgets from .gui_common import GuiCommon from .main_window import MainWindow diff --git a/gpgsync/gui/gui_common.py b/gpgsync/gui/gui_common.py index effd567..f9b80ba 100644 --- a/gpgsync/gui/gui_common.py +++ b/gpgsync/gui/gui_common.py @@ -19,7 +19,7 @@ along with this program. If not, see . """ import platform -from PyQt5 import QtCore, QtWidgets, QtGui +from PySide2 import QtCore, QtWidgets, QtGui # macOS only if platform.system() == 'Darwin': diff --git a/gpgsync/gui/keylist_dialog.py b/gpgsync/gui/keylist_dialog.py index 8c0ee0c..f46f9c6 100644 --- a/gpgsync/gui/keylist_dialog.py +++ b/gpgsync/gui/keylist_dialog.py @@ -19,14 +19,14 @@ along with this program. If not, see . """ import queue -from PyQt5 import QtCore, QtWidgets, QtGui +from PySide2 import QtCore, QtWidgets, QtGui from ..keylist import Keylist, ValidatorMessageQueue from .threads import AuthorityKeyValidatorThread class KeylistDialog(QtWidgets.QDialog): - saved = QtCore.pyqtSignal(Keylist) + saved = QtCore.Signal(Keylist) def __init__(self, common, keylist=None): super(KeylistDialog, self).__init__() @@ -201,7 +201,7 @@ def validated(self): class ValidatorDialog(QtWidgets.QDialog): - success = QtCore.pyqtSignal() + success = QtCore.Signal() def __init__(self, common, fingerprint, url, use_modern_keyserver, keyserver, use_proxy, proxy_host, proxy_port): super(ValidatorDialog, self).__init__() diff --git a/gpgsync/gui/keylist_list.py b/gpgsync/gui/keylist_list.py index fe7f9f6..de5c6bd 100644 --- a/gpgsync/gui/keylist_list.py +++ b/gpgsync/gui/keylist_list.py @@ -20,7 +20,7 @@ """ import queue import time -from PyQt5 import QtCore, QtWidgets, QtGui +from PySide2 import QtCore, QtWidgets, QtGui from .keylist_dialog import KeylistDialog from .threads import RefresherThread @@ -28,7 +28,7 @@ class KeylistList(QtWidgets.QWidget): - refresh = QtCore.pyqtSignal() + refresh = QtCore.Signal() def __init__(self, common): super(KeylistList, self).__init__() @@ -76,7 +76,7 @@ def update_keylist_widgets(self): class KeylistWidget(QtWidgets.QWidget): - refresh = QtCore.pyqtSignal() + refresh = QtCore.Signal() def __init__(self, common, keylist): super(KeylistWidget, self).__init__() diff --git a/gpgsync/gui/main_window.py b/gpgsync/gui/main_window.py index 3f10e31..0e79f08 100644 --- a/gpgsync/gui/main_window.py +++ b/gpgsync/gui/main_window.py @@ -20,7 +20,7 @@ """ import sys, platform, datetime, requests from packaging.version import parse -from PyQt5 import QtCore, QtWidgets, QtGui +from PySide2 import QtCore, QtWidgets, QtGui from .systray import SysTray from .settings_dialog import SettingsDialog diff --git a/gpgsync/gui/settings_dialog.py b/gpgsync/gui/settings_dialog.py index 5e00c56..af1bd54 100644 --- a/gpgsync/gui/settings_dialog.py +++ b/gpgsync/gui/settings_dialog.py @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . """ -from PyQt5 import QtCore, QtWidgets, QtGui +from PySide2 import QtCore, QtWidgets, QtGui class SettingsDialog(QtWidgets.QDialog): diff --git a/gpgsync/gui/systray.py b/gpgsync/gui/systray.py index ae69a3a..7345601 100644 --- a/gpgsync/gui/systray.py +++ b/gpgsync/gui/systray.py @@ -19,16 +19,16 @@ along with this program. If not, see . """ import queue -from PyQt5 import QtCore, QtWidgets +from PySide2 import QtCore, QtWidgets class SysTray(QtWidgets.QSystemTrayIcon): - show_signal = QtCore.pyqtSignal() - sync_now_signal = QtCore.pyqtSignal(bool) - check_updates_now_signal = QtCore.pyqtSignal(bool) - show_settings_window_signal = QtCore.pyqtSignal(bool) - quit_signal = QtCore.pyqtSignal() - clicked_applet_signal = QtCore.pyqtSignal() + show_signal = QtCore.Signal() + sync_now_signal = QtCore.Signal(bool) + check_updates_now_signal = QtCore.Signal(bool) + show_settings_window_signal = QtCore.Signal(bool) + quit_signal = QtCore.Signal() + clicked_applet_signal = QtCore.Signal() def __init__(self, common, version): super(SysTray, self).__init__(common.gui.systray_icon) diff --git a/gpgsync/gui/threads.py b/gpgsync/gui/threads.py index b5ae41e..955fbeb 100644 --- a/gpgsync/gui/threads.py +++ b/gpgsync/gui/threads.py @@ -20,7 +20,7 @@ """ import queue import datetime -from PyQt5 import QtCore, QtWidgets +from PySide2 import QtCore, QtWidgets from ..keylist import Keylist, ValidatorMessageQueue, RefresherMessageQueue @@ -30,8 +30,8 @@ class AuthorityKeyValidatorThread(QtCore.QThread): fetch the authority key from a keyserver. But in order to do that, we need to first download the keylist, to learn what keyserver we should be using. """ - alert_error = QtCore.pyqtSignal(str, str) - success = QtCore.pyqtSignal() + alert_error = QtCore.Signal(str, str) + success = QtCore.Signal() def __init__(self, common, fingerprint, url, use_modern_keyserver, keyserver, use_proxy, proxy_host, proxy_port): super(AuthorityKeyValidatorThread, self).__init__() @@ -80,7 +80,7 @@ def run(self): class RefresherThread(QtCore.QThread): - finished = QtCore.pyqtSignal() + finished = QtCore.Signal() def __init__(self, common, keylist, force=False): super(RefresherThread, self).__init__() From 8ebd3b0068484604efed92caf8ee8c7ea4960727 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 4 Feb 2021 13:38:06 -0800 Subject: [PATCH 07/14] Make Qt5 work in Big Sur --- gpgsync/gui/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gpgsync/gui/__init__.py b/gpgsync/gui/__init__.py index 5bffee9..1465300 100644 --- a/gpgsync/gui/__init__.py +++ b/gpgsync/gui/__init__.py @@ -19,6 +19,8 @@ along with this program. If not, see . """ import sys +import platform +import os from PySide2 import QtCore, QtWidgets from .gui_common import GuiCommon @@ -33,6 +35,10 @@ def __init__(self, os): def main(common): + # Required for macOS Big Sur: https://stackoverflow.com/a/64878899 + if platform.system() == "Darwin": + os.environ["QT_MAC_WANTS_LAYER"] = "1" + # Create the Qt app app = Application(common.os) From 192a2fb45f41c3cef788be6d4c8f20d068977e3e Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 4 Feb 2021 16:02:53 -0800 Subject: [PATCH 08/14] Make systray icon have color, because of difficult Big Sur changes --- BUILD.md | 2 +- gpgsync/gui/gui_common.py | 18 +----- poetry.lock | 128 ++++++++++++++++++++++++++------------ pyproject.toml | 7 +-- 4 files changed, 93 insertions(+), 62 deletions(-) diff --git a/BUILD.md b/BUILD.md index 13e1438..6cbaa97 100644 --- a/BUILD.md +++ b/BUILD.md @@ -2,7 +2,7 @@ ## Mac OS X -Download and install Python 3.9.1 from https://www.python.org/downloads/release/python-391/. I downloaded `python-3.9.1-macosx10.9.pkg`. +Download and install Python 3.8.7 from https://www.python.org/downloads/release/python-387/. I downloaded `python-3.8.7-macosx10.9.pkg`. Make sure you have `poetry` installed (`pip3 install --user poetry`), then install dependencies: diff --git a/gpgsync/gui/gui_common.py b/gpgsync/gui/gui_common.py index f9b80ba..01c554e 100644 --- a/gpgsync/gui/gui_common.py +++ b/gpgsync/gui/gui_common.py @@ -21,10 +21,6 @@ import platform from PySide2 import QtCore, QtWidgets, QtGui -# macOS only -if platform.system() == 'Darwin': - from Foundation import NSUserDefaults - class GuiCommon(object): """ @@ -35,18 +31,8 @@ def __init__(self, common): # Preload icons self.icon = QtGui.QIcon(self.c.get_resource_path('gpgsync.png')) - if self.c.os == 'Darwin': - # Detect dark mode in macOS Mojova - # See: https://stackoverflow.com/a/54701363 - if NSUserDefaults.standardUserDefaults().stringForKey_('AppleInterfaceStyle') == 'Dark': - self.systray_icon = QtGui.QIcon(self.c.get_resource_path('gpgsync-bw-dark.png')) - self.systray_syncing_icon = QtGui.QIcon(self.c.get_resource_path('syncing-bw-dark.png')) - else: - self.systray_icon = QtGui.QIcon(self.c.get_resource_path('gpgsync-bw-light.png')) - self.systray_syncing_icon = QtGui.QIcon(self.c.get_resource_path('syncing-bw-light.png')) - else: - self.systray_icon = QtGui.QIcon(self.c.get_resource_path('gpgsync.png')) - self.systray_syncing_icon = QtGui.QIcon(self.c.get_resource_path('syncing.png')) + self.systray_icon = QtGui.QIcon(self.c.get_resource_path('gpgsync.png')) + self.systray_syncing_icon = QtGui.QIcon(self.c.get_resource_path('syncing.png')) # Stylesheets self.css = { diff --git a/poetry.lock b/poetry.lock index f7b1549..a6d54bd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,11 @@ +[[package]] +name = "altgraph" +version = "0.17" +description = "Python graph (network) package" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "certifi" version = "2020.12.5" @@ -14,6 +22,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "future" +version = "0.18.2" +description = "Clean single-source support for Python 3 and 2" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + [[package]] name = "idna" version = "2.10" @@ -22,6 +38,17 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "macholib" +version = "1.14" +description = "Mach-O header analysis and editing" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +altgraph = ">=0.15" + [[package]] name = "packaging" version = "20.9" @@ -34,35 +61,42 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" pyparsing = ">=2.0.2" [[package]] -name = "pyobjc-core" -version = "7.0.1" -description = "Python<->ObjC Interoperability Module" -category = "main" +name = "pefile" +version = "2019.4.18" +description = "Python PE parsing module" +category = "dev" optional = false -python-versions = ">=3.6" +python-versions = "*" + +[package.dependencies] +future = "*" [[package]] -name = "pyobjc-framework-cocoa" -version = "7.0.1" -description = "Wrappers for the Cocoa frameworks on macOS" -category = "main" +name = "pyinstaller" +version = "4.2" +description = "PyInstaller bundles a Python application and all its dependencies into a single package." +category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.5" [package.dependencies] -pyobjc-core = ">=7.0.1" +altgraph = "*" +macholib = {version = ">=1.8", markers = "sys_platform == \"darwin\""} +pefile = {version = ">=2017.8.1", markers = "sys_platform == \"win32\""} +pyinstaller-hooks-contrib = ">=2020.6" +pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""} + +[package.extras] +encryption = ["tinyaes (>=1.0.0)"] +hook_testing = ["pytest (>=2.7.3)", "execnet (>=1.5.0)", "psutil"] [[package]] -name = "pyobjc-framework-quartz" -version = "7.0.1" -description = "Wrappers for the Quartz frameworks on macOS" -category = "main" +name = "pyinstaller-hooks-contrib" +version = "2020.11" +description = "Community maintained hooks for PyInstaller" +category = "dev" optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyobjc-core = ">=7.0.1" -pyobjc-framework-Cocoa = ">=7.0.1" +python-versions = "*" [[package]] name = "pyparsing" @@ -110,6 +144,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "pywin32-ctypes" +version = "0.2.0" +description = "" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "requests" version = "2.25.1" @@ -160,9 +202,13 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [metadata] lock-version = "1.1" python-versions = ">=3.8,<3.10" -content-hash = "cdb65fe6b80c79031014b1db3768e8e02f52591255daa5ab854d650803e8798e" +content-hash = "344bcb86793b8d2e9784ab50a9fba52b7b2d026fea54101b2337069b40852729" [metadata.files] +altgraph = [ + {file = "altgraph-0.17-py2.py3-none-any.whl", hash = "sha256:c623e5f3408ca61d4016f23a681b9adb100802ca3e3da5e718915a9e4052cebe"}, + {file = "altgraph-0.17.tar.gz", hash = "sha256:1f05a47122542f97028caf78775a095fbe6a2699b5089de8477eb583167d69aa"}, +] certifi = [ {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, @@ -171,34 +217,30 @@ chardet = [ {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, ] +future = [ + {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, +] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] +macholib = [ + {file = "macholib-1.14-py2.py3-none-any.whl", hash = "sha256:c500f02867515e6c60a27875b408920d18332ddf96b4035ef03beddd782d4281"}, + {file = "macholib-1.14.tar.gz", hash = "sha256:0c436bc847e7b1d9bda0560351bf76d7caf930fb585a828d13608839ef42c432"}, +] packaging = [ {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, ] -pyobjc-core = [ - {file = "pyobjc-core-7.0.1.tar.gz", hash = "sha256:7213bfd48c49f5b4d479256924e0120d728ed449de8188cba9e204c434ed07f2"}, - {file = "pyobjc_core-7.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6f84a5744e44ec709daca1e66b95c3c010e4159bc2cfc442c27c0d28b0456eda"}, - {file = "pyobjc_core-7.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2fdba7997d5c9d518256f9d2e9f7780fcc6332b0371207374f38d7e9fad7bc8"}, - {file = "pyobjc_core-7.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:758cf96f3848c6e177d6ad94d44fec1b9ea5e32ca066513184d8f1e70d71ff6e"}, - {file = "pyobjc_core-7.0.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:61c756c9bd5c55e9137cf0549f1d931dd1e1bff30a1cc97e46e55b94d5dc5d97"}, -] -pyobjc-framework-cocoa = [ - {file = "pyobjc-framework-Cocoa-7.0.1.tar.gz", hash = "sha256:8a545b47b2021884bd8e5644ac32ee6d99a1f8e6a45cab3e6d1b999adf968630"}, - {file = "pyobjc_framework_Cocoa-7.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4675accc4720b42f456a35ba7cdd9e1cb44b9b84fcc600beef120ae05d2c5d27"}, - {file = "pyobjc_framework_Cocoa-7.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:42e106c3d688e66b1032b0819daa842a78eff6f7646b5af4be8774d0c8f5e200"}, - {file = "pyobjc_framework_Cocoa-7.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8aa715fa1ff367330fc58eadc1747e222bdf854b9ece6936487c9c4f4e2627d3"}, - {file = "pyobjc_framework_Cocoa-7.0.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:1d9de6b0612a5e24899522a797425c834405a536db41ba06a19df01b7008eeae"}, -] -pyobjc-framework-quartz = [ - {file = "pyobjc-framework-Quartz-7.0.1.tar.gz", hash = "sha256:8d76cabfbae38102301f44f1edb3ab4c959f18ed0c828cfff1693a3c559945ef"}, - {file = "pyobjc_framework_Quartz-7.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fbf8d816da04f0705707906fb751bd360d652914ace3989ed6e55ff6a7a79c62"}, - {file = "pyobjc_framework_Quartz-7.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a1854a0b8baea76e6c43812ecf26dd6fc5a11e9cada212b36bf35e23e670750c"}, - {file = "pyobjc_framework_Quartz-7.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:019982c0c1a74e68f29c9f961292d4c752a8fdd6d806197a73a41aa6c9fa00a9"}, - {file = "pyobjc_framework_Quartz-7.0.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:9be4d99d04abd9f9147cc9e83b87324efc0b832320caee310defc71798201816"}, +pefile = [ + {file = "pefile-2019.4.18.tar.gz", hash = "sha256:a5d6e8305c6b210849b47a6174ddf9c452b2888340b8177874b862ba6c207645"}, +] +pyinstaller = [ + {file = "pyinstaller-4.2.tar.gz", hash = "sha256:f5c0eeb2aa663cce9a5404292c0195011fa500a6501c873a466b2e8cad3c950c"}, +] +pyinstaller-hooks-contrib = [ + {file = "pyinstaller-hooks-contrib-2020.11.tar.gz", hash = "sha256:fc3290a2ca337d1d58c579c223201360bfe74caed6454eaf5a2550b77dbda45c"}, + {file = "pyinstaller_hooks_contrib-2020.11-py2.py3-none-any.whl", hash = "sha256:fa8280b79d8a2b267a2e43ff44f73b3e4a68fc8d205b8d34e8e06c960f7c2fcf"}, ] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, @@ -233,6 +275,10 @@ pywin32 = [ {file = "pywin32-300-cp39-cp39-win32.whl", hash = "sha256:638b68eea5cfc8def537e43e9554747f8dee786b090e47ead94bfdafdb0f2f50"}, {file = "pywin32-300-cp39-cp39-win_amd64.whl", hash = "sha256:b1609ce9bd5c411b81f941b246d683d6508992093203d4eb7f278f4ed1085c3f"}, ] +pywin32-ctypes = [ + {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, + {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, +] requests = [ {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, diff --git a/pyproject.toml b/pyproject.toml index 5fce4bc..e5e71dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,13 +11,12 @@ PySide2 = "^5.15.2" PySocks = "^1.7.1" python-dateutil = "^2.8.1" requests = "^2.25.1" -pywin32 = {version = "^300", platform = "win32"} -pyobjc-core = {version = "7.0.1", platform = "darwin"} -pyobjc-framework-cocoa = {version = "7.0.1", platform = "darwin"} -pyobjc-framework-quartz = {version = "7.0.1", platform = "darwin"} packaging = "^20.9" +pywin32 = {version = "^300", platform = "win32"} [tool.poetry.dev-dependencies] +pip = "^21.0.1" +pyinstaller = "^4.2" [build-system] requires = ["poetry-core>=1.0.0"] From 948df5ccdfe2cc1f52d09336688f0608d55b9763 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 4 Feb 2021 16:11:48 -0800 Subject: [PATCH 09/14] Update some of Windows build instructions --- BUILD.md | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/BUILD.md b/BUILD.md index 6cbaa97..a8acdaa 100644 --- a/BUILD.md +++ b/BUILD.md @@ -35,7 +35,7 @@ Now you should have `dist/GPGSync-{version}.pkg`. ## Windows -Download Python 3.8.0, 32-bit (x86) from https://www.python.org/downloads/release/python-380/. I downloaded `python-3.8.0.exe`. When installing it, make sure to check the "Add Python 3.8 to PATH" checkbox on the first page of the installer. +Download Python 3.8.7, 32-bit (x86) from https://www.python.org/downloads/release/python-387/. I downloaded `python-3.8.7.exe`. When installing it, make sure to check the "Add Python 3.8 to PATH" checkbox on the first page of the installer. Open a command prompt and cd to the gpgsync folder. If you don't have it already, install poetry (`pip install poetry`). Then install dependencies: @@ -43,8 +43,6 @@ Open a command prompt and cd to the gpgsync folder. If you don't have it already python -m poetry install ``` -Install the Qt 5.13.2 from https://www.qt.io/offline-installers. I downloaded `qt-opensource-windows-x86-5.13.2.exe`. In the installer, you can skip making an account, and all you need `Qt` > `Qt 5.13.2` > `MSVC 2017 32-bit`. - After that you can launch GPG Sync during development with: ``` @@ -87,7 +85,7 @@ vcvars32.bat Make sure you have a new enough `setuptools`: ``` -pip install setuptools==40.6.3 +pip install --upgrade setuptools ``` Now make sure you don't have PyInstaller installed from pip: @@ -101,25 +99,7 @@ Change to a folder where you keep source code, and clone the PyInstaller git rep ``` git clone https://github.com/pyinstaller/pyinstaller.git -``` - -To verify the git tag, you first need the signing key's PGP key, which means you need `gpg`. If you installed git from git-scm.com, you can run this from Git Bash: - -``` -gpg --keyserver hkps://keyserver.ubuntu.com:443 --recv-key 0xD4AD8B9C167B757C4F08E8777B752811BF773B65 -``` - -And now verify the tag: - -``` -cd pyinstaller -git tag -v v3.4 -``` - -It should say `Good signature from "Hartmut Goebel `. If it verified successfully, checkout the tag: - -``` -git checkout v3.4 +git checkout v4.2 ``` And compile the bootloader, following [these instructions](https://pythonhosted.org/PyInstaller/bootloader-building.html). To compile, run this: From dfb5e75030e5fd34d8942d594196a78cbf390280 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 4 Feb 2021 17:14:51 -0800 Subject: [PATCH 10/14] Update linux build instructions --- BUILD.md | 8 ++++---- install/build_rpm.sh | 2 +- stdeb.cfg | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/BUILD.md b/BUILD.md index a8acdaa..948ecd4 100644 --- a/BUILD.md +++ b/BUILD.md @@ -149,14 +149,14 @@ This will prompt you to codesign three binaries and execute one unsigned binary. Install dependencies: ```sh -sudo apt install -y python3-pyqt5 python3-pytest python3-pytest-runner python3-stdeb python3-requests python3-socks python3-packaging python3-dateutil gnupg2 +sudo apt install -y python-all dh-python python3-pytest python3-pytest-runner python3-stdeb python3-pyside2.qtcore python3-pyside2.qtwidgets python3-pyside2.qtgui python3-requests python3-socks python3-packaging python3-dateutil gnupg2 ``` Make and install a .deb: ```sh ./install/build_deb.sh -sudo dpkg -i deb_dist/gpgsync_*.deb +sudo apt install deb_dist/gpgsync_*.deb ``` *Fedora* @@ -164,14 +164,14 @@ sudo dpkg -i deb_dist/gpgsync_*.deb Install dependencies: ```sh -sudo dnf install -y rpm-build python3-qt5 python3-requests python3-pytest-runner python3-packaging python3-dateutil gnupg2 +sudo dnf install -y rpm-build python3-pytest-runner python3-pyside2 python3-requests python3-packaging python3-dateutil gnupg2 ``` Make and install a .rpm: ```sh ./install/build_rpm.sh -sudo dnf install dist/gpgsync_*.rpm +sudo dnf install dist/gpgsync-*-1.noarch.rpm ``` ## Alternatively utilize Docker to build the relevant debian/rpm diff --git a/install/build_rpm.sh b/install/build_rpm.sh index fb056e8..3b3eeac 100755 --- a/install/build_rpm.sh +++ b/install/build_rpm.sh @@ -10,7 +10,7 @@ VERSION=${VERSION:1} rm -r build dist >/dev/null 2>&1 # build binary package -python3 setup.py bdist_rpm --requires="python3-qt5, python3-requests, python3-packaging, python3-dateutil, gnupg2" +python3 setup.py bdist_rpm --requires="python3-pyside2, python3-requests, python3-packaging, python3-dateutil, gnupg2" # return install instructions if build succeeds if [[ $? -eq 0 ]]; then diff --git a/stdeb.cfg b/stdeb.cfg index 5f2fa97..6ec083b 100644 --- a/stdeb.cfg +++ b/stdeb.cfg @@ -1,4 +1,4 @@ [DEFAULT] Package3: gpgsync -Depends3: python3-pyqt5, python3-requests, python3-socks, python3-packaging, python3-dateutil, gnupg2 -Build-Depends3: python3-stdeb, python3-pytest, python3-pytest-runner +Depends3: python3-pyside2.qtcore, python3-pyside2.qtwidgets, python3-pyside2.qtgui, python3-requests, python3-socks, python3-packaging, python3-dateutil, gnupg2 +Build-Depends3: python3-stdeb, python3-pytest, python3-pytest-runner, python-all, dh-python From 28417a0eea17fb03bbcdf8e6d6c3cec6e7786b48 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 4 Feb 2021 17:18:12 -0800 Subject: [PATCH 11/14] Fix tests for PySide2 --- test/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/conftest.py b/test/conftest.py index ee08420..9dabe8e 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -2,7 +2,7 @@ import pytest import sys import tempfile -from PyQt5 import QtWidgets +from PySide2 import QtWidgets from gpgsync.common import Common from gpgsync.gnupg import GnuPG From a110a75167308c64fc3bcee97004cb27e5e44ef7 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Thu, 4 Feb 2021 17:49:55 -0800 Subject: [PATCH 12/14] Update Windows build instructions --- BUILD.md | 80 ++++++++++++-------------------------------------------- 1 file changed, 17 insertions(+), 63 deletions(-) diff --git a/BUILD.md b/BUILD.md index 948ecd4..4d21343 100644 --- a/BUILD.md +++ b/BUILD.md @@ -40,92 +40,42 @@ Download Python 3.8.7, 32-bit (x86) from https://www.python.org/downloads/releas Open a command prompt and cd to the gpgsync folder. If you don't have it already, install poetry (`pip install poetry`). Then install dependencies: ```cmd -python -m poetry install +poetry install ``` After that you can launch GPG Sync during development with: -``` -python -m poetry run python dev_scripts\gpgsync -v +```cmd +poetry run python dev_scripts\gpgsync -v ``` ### To make a .exe: 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 and install the 32-bit [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145). I downloaded `vc_redist.x86.exe`. - -Download and install the standalone [Windows 10 SDK](https://dev.windows.com/en-us/downloads/windows-10-sdk). Note that you may not need this if you already have Visual Studio. +Download and install the standalone [Windows 10 SDK](https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk/). Add the following directories to the path: -* `C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x86` -* `C:\Program Files (x86)\Windows Kits\10\Redist\10.0.18362.0\ucrt\DLLs\x86` -* `C:\Users\user\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\PyQt5\Qt\bin` - -Finally, open a command prompt, cd into the gpgsync directory, and type: `pyinstaller install\pyinstaller.spec`. `gpgsync.exe` and all of their supporting files will get created inside the `dist` folder. - -### If you want the .exe to not get falsely flagged as malicious by anti-virus software - -GPG Sync uses PyInstaller to turn the python source code into Windows executable `.exe` file. Apparently, malware developers also use PyInstaller, and some anti-virus vendors have included snippets of PyInstaller code in their virus definitions. To avoid this, you have to compile the Windows PyInstaller bootloader yourself instead of using the pre-compiled one that comes with PyInstaller. - -(If you don't care about this, you can install PyInstaller with `pip install PyInstaller==3.4`.) - -Here's how to compile the PyInstaller bootloader: - -Download and install [Microsoft Build Tools for Visual Studio 2017](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2017). I downloaded `vs_buildtools.exe`. In the installer, check the box next to "Visual C++ build tools". Click "Individual components", and under "Compilers, build tools and runtimes", check "Windows Universal CRT SDK". Then click install. When installation is done, you may have to reboot your computer. - -Then, enable the 32-bit Visual C++ Toolset on the Command Line like this: - -``` -cd "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build" -vcvars32.bat -``` - -Make sure you have a new enough `setuptools`: - -``` -pip install --upgrade setuptools -``` +* `C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86` +* `C:\Program Files (x86)\Windows Kits\10\Redist\10.0.19041.0\ucrt\DLLs\x86` -Now make sure you don't have PyInstaller installed from pip: +Finally, open a command prompt, cd into the gpgsync directory, and run: -``` -pip uninstall PyInstaller -rmdir C:\Users\user\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\PyInstaller /S -``` - -Change to a folder where you keep source code, and clone the PyInstaller git repo: - -``` -git clone https://github.com/pyinstaller/pyinstaller.git -git checkout v4.2 -``` - -And compile the bootloader, following [these instructions](https://pythonhosted.org/PyInstaller/bootloader-building.html). To compile, run this: - -``` -cd bootloader -python waf distclean all --target-arch=32bit --msvc_targets=x86 -``` - -Finally, install the PyInstaller module into your local site-packages: - -``` -cd .. -python setup.py install +```cmd +poetry run pyinstaller install\pyinstaller.spec ``` -Now the next time you use PyInstaller to build GPG Sync, the `.exe` file should not be flagged as malicious by anti-virus. +`gpgsync.exe` and all of their supporting files will get created inside the `dist` folder. ### To build the installer: -* Go to http://nsis.sourceforge.net/Download and download the latest NSIS. I downloaded `nsis-3.04-setup.exe`. +* Go to http://nsis.sourceforge.net/Download and download the latest NSIS. I downloaded `nsis-3.06.1-setup.exe`. * Add `C:\Program Files (x86)\NSIS` to the path. Now install the Processes NSIS plugin. -* Go to https://nsis.sourceforge.io/NsProcess_plugin and download NsProcess. I donwnloaded `nsProcess_1_6.7z` (with sha256 hash `fc19fc66a5219a233570fafd5daeb0c9b85387b379f6df5ac8898159a57c5944`) +* Go to https://nsis.sourceforge.io/NsProcess_plugin and download NsProcess. I downloaded `nsProcess_1_6.7z` (with sha256 hash `fc19fc66a5219a233570fafd5daeb0c9b85387b379f6df5ac8898159a57c5944`) * Decompress it. You will probably need [7-Zip](https://www.7-zip.org/) * Copy `nsProcess_1.6/Plugin/*.dll` to `C:\Program Files (x86)\NSIS\Plugins\x86-ansi` * Copy `nsProcess_1.6/Include/ncProcess.nsh` to `C:\Program Files (x86)\NSIS\Include` @@ -137,7 +87,11 @@ If you want to sign binaries with Authenticode: Note that you must have a codesigning certificate installed in order to use the `install\build_exe.bat` script, because it codesigns `gpgsync.exe`, `uninstall.exe`, and `gpgsync-setup.exe`. -Open a command prompt, cd to the gpgsync directory, and type: `install\build_exe.bat` +Open a command prompt, cd to the gpgsync directory, and run: + +```cmd +poetry run install\build_exe.bat +``` This will prompt you to codesign three binaries and execute one unsigned binary. When you're done clicking through everything you will have `dist\gpgsync-setup.exe`. From d6f3554b16499b05f3c4cfd7a8f15ef8558792aa Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 5 Feb 2021 11:58:52 -0800 Subject: [PATCH 13/14] Make tests pass on CI --- .circleci/config.yml | 8 +-- poetry.lock | 136 ++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 2 + test/conftest.py | 4 -- 4 files changed, 141 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 95b2f4a..b3a90c0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,23 +4,23 @@ jobs: test: docker: - - image: circleci/python:3.7-buster + - image: circleci/python:3.8-buster steps: - run: name: Install dependencies command: | sudo apt-get update - sudo apt-get install -y gnupg2 python3-pyqt5 tor xvfb + sudo apt-get install -y gnupg2 tor xvfb - run: name: Start tor service command: sudo service tor start - checkout - run: name: Install python dependencies - command: pipenv install --dev + command: poetry install - run: name: Run tests - command: pipenv run xvfb-run -s "-screen 0 1280x1024x24" python setup.py pytest + command: poetry run xvfb-run -s "-screen 0 1280x1024x24" python setup.py pytest build-ubuntu-bionic: docker: diff --git a/poetry.lock b/poetry.lock index a6d54bd..0b93847 100644 --- a/poetry.lock +++ b/poetry.lock @@ -6,6 +6,28 @@ category = "dev" optional = false python-versions = "*" +[[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 = "20.3.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["coverage[toml] (>=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"] + [[package]] name = "certifi" version = "2020.12.5" @@ -22,6 +44,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "future" version = "0.18.2" @@ -38,6 +68,14 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "iniconfig" +version = "1.1.1" +description = "iniconfig: brain-dead simple config-ini parsing" +category = "dev" +optional = false +python-versions = "*" + [[package]] name = "macholib" version = "1.14" @@ -71,6 +109,25 @@ python-versions = "*" [package.dependencies] future = "*" +[[package]] +name = "pluggy" +version = "0.13.1" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[package.extras] +dev = ["pre-commit", "tox"] + +[[package]] +name = "py" +version = "1.10.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.*" + [[package]] name = "pyinstaller" version = "4.2" @@ -125,6 +182,39 @@ category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +[[package]] +name = "pytest" +version = "6.2.2" +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,<1.0.0a1" +py = ">=1.8.2" +toml = "*" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +name = "pytest-runner" +version = "5.2" +description = "Invoke py.test as distutils command with dependency resolution" +category = "dev" +optional = false +python-versions = ">=2.7" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] +testing = ["pytest (>=3.5,!=3.7.3)", "pytest-checkdocs", "pytest-flake8", "pytest-black-multipy", "pytest-cov", "pytest-virtualenv"] + [[package]] name = "python-dateutil" version = "2.8.1" @@ -186,6 +276,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 = "urllib3" version = "1.26.3" @@ -202,13 +300,21 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [metadata] lock-version = "1.1" python-versions = ">=3.8,<3.10" -content-hash = "344bcb86793b8d2e9784ab50a9fba52b7b2d026fea54101b2337069b40852729" +content-hash = "c2c6400e17cdff55e692134c80975edfc0aeee1bf2ce02f6c58806def4e40bb5" [metadata.files] altgraph = [ {file = "altgraph-0.17-py2.py3-none-any.whl", hash = "sha256:c623e5f3408ca61d4016f23a681b9adb100802ca3e3da5e718915a9e4052cebe"}, {file = "altgraph-0.17.tar.gz", hash = "sha256:1f05a47122542f97028caf78775a095fbe6a2699b5089de8477eb583167d69aa"}, ] +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-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, + {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, +] certifi = [ {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, @@ -217,6 +323,10 @@ chardet = [ {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, {file = "chardet-4.0.0.tar.gz", hash = "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa"}, ] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] future = [ {file = "future-0.18.2.tar.gz", hash = "sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"}, ] @@ -224,6 +334,10 @@ idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] +iniconfig = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] macholib = [ {file = "macholib-1.14-py2.py3-none-any.whl", hash = "sha256:c500f02867515e6c60a27875b408920d18332ddf96b4035ef03beddd782d4281"}, {file = "macholib-1.14.tar.gz", hash = "sha256:0c436bc847e7b1d9bda0560351bf76d7caf930fb585a828d13608839ef42c432"}, @@ -235,6 +349,14 @@ packaging = [ pefile = [ {file = "pefile-2019.4.18.tar.gz", hash = "sha256:a5d6e8305c6b210849b47a6174ddf9c452b2888340b8177874b862ba6c207645"}, ] +pluggy = [ + {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, + {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, +] +py = [ + {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, + {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, +] pyinstaller = [ {file = "pyinstaller-4.2.tar.gz", hash = "sha256:f5c0eeb2aa663cce9a5404292c0195011fa500a6501c873a466b2e8cad3c950c"}, ] @@ -259,6 +381,14 @@ 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.2-py3-none-any.whl", hash = "sha256:b574b57423e818210672e07ca1fa90aaf194a4f63f3ab909a2c67ebb22913839"}, + {file = "pytest-6.2.2.tar.gz", hash = "sha256:9d1edf9e7d0b84d72ea3dbcdfd22b35fb543a5e8f2a60092dd578936bf63d7f9"}, +] +pytest-runner = [ + {file = "pytest-runner-5.2.tar.gz", hash = "sha256:96c7e73ead7b93e388c5d614770d2bae6526efd997757d3543fe17b557a0942b"}, + {file = "pytest_runner-5.2-py2.py3-none-any.whl", hash = "sha256:5534b08b133ef9a5e2c22c7886a8f8508c95bb0b0bdc6cc13214f269c3c70d51"}, +] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, @@ -295,6 +425,10 @@ six = [ {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, ] +toml = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] urllib3 = [ {file = "urllib3-1.26.3-py2.py3-none-any.whl", hash = "sha256:1b465e494e3e0d8939b50680403e3aedaa2bc434b7d5af64dfd3c958d7f5ae80"}, {file = "urllib3-1.26.3.tar.gz", hash = "sha256:de3eedaad74a2683334e282005cd8d7f22f4d55fa690a2a1020a416cb0a47e73"}, diff --git a/pyproject.toml b/pyproject.toml index e5e71dc..f2be53a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,8 @@ pywin32 = {version = "^300", platform = "win32"} [tool.poetry.dev-dependencies] pip = "^21.0.1" pyinstaller = "^4.2" +pytest = "^6.2.2" +pytest-runner = "^5.2" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/test/conftest.py b/test/conftest.py index 9dabe8e..3dfa4d7 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -2,7 +2,6 @@ import pytest import sys import tempfile -from PySide2 import QtWidgets from gpgsync.common import Common from gpgsync.gnupg import GnuPG @@ -11,9 +10,6 @@ # Set GPG Sync to dev mode, so it looks for resources in the right place sys.gpgsync_dev = True -# Setup Qt -qt_app = QtWidgets.QApplication(sys.argv) - # Generate a Common singleton @pytest.fixture From d041089d233ba3edb9befd1d4581f14e99999ed7 Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 5 Feb 2021 12:10:41 -0800 Subject: [PATCH 14/14] Update changelog, version bump to 0.3.6, and update packagecloud packaging --- .circleci/config.yml | 151 +++++++++++++++++-------------------------- CHANGELOG.md | 5 ++ share/version | 2 +- 3 files changed, 66 insertions(+), 92 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index b3a90c0..4775536 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,17 +22,17 @@ jobs: name: Run tests command: poetry run xvfb-run -s "-screen 0 1280x1024x24" python setup.py pytest - build-ubuntu-bionic: + build-ubuntu-focal: docker: - - image: ubuntu:18.04 + - image: ubuntu:20.04 steps: - run: name: Install dependencies command: | apt-get update - DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all python3-all dh-python python3-pyqt5 python3-stdeb python3-requests python3-socks python3-packaging python3-dateutil python3-pytest python3-pytest-runner gnupg2 - gem install --no-ri --no-rdoc rake - gem install --no-ri --no-rdoc package_cloud + DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all dh-python python3-pytest python3-pytest-runner python3-stdeb python3-pyside2.qtcore python3-pyside2.qtwidgets python3-pyside2.qtgui python3-requests python3-socks python3-packaging python3-dateutil gnupg2 + gem install -N rake + gem install -N package_cloud - checkout - run: name: Create the .deb package @@ -43,44 +43,20 @@ jobs: name: Deploy to packagecloud.io command: | VERSION=$(cat share/version |cut -dv -f2) - package_cloud push firstlookmedia/code/ubuntu/bionic deb_dist/gpgsync_${VERSION}-1_all.deb - package_cloud push firstlookmedia/code/ubuntu/bionic deb_dist/gpgsync_${VERSION}-1.dsc - - build-ubuntu-disco: - docker: - - image: ubuntu:19.04 - steps: - - run: - name: Install dependencies - command: | - apt-get update - DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all python3-all dh-python python3-pyqt5 python3-stdeb python3-requests python3-socks python3-packaging python3-dateutil python3-pytest python3-pytest-runner gnupg2 - gem install --no-ri --no-rdoc rake - gem install --no-ri --no-rdoc package_cloud - - checkout - - run: - name: Create the .deb package - command: | - ./install/build_deb.sh - dpkg -i deb_dist/gpgsync_*.deb - - run: - name: Deploy to packagecloud.io - command: | - VERSION=$(cat share/version |cut -dv -f2) - package_cloud push firstlookmedia/code/ubuntu/disco deb_dist/gpgsync_${VERSION}-1_all.deb - package_cloud push firstlookmedia/code/ubuntu/disco deb_dist/gpgsync_${VERSION}-1.dsc + package_cloud push firstlookmedia/code/ubuntu/focal deb_dist/gpgsync_${VERSION}-1_all.deb + package_cloud push firstlookmedia/code/ubuntu/focal deb_dist/gpgsync_${VERSION}-1.dsc - build-ubuntu-eoan: + build-ubuntu-groovy: docker: - - image: ubuntu:19.10 + - image: ubuntu:20.10 steps: - run: name: Install dependencies command: | apt-get update - DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all python3-all dh-python python3-pyqt5 python3-stdeb python3-requests python3-socks python3-packaging python3-dateutil python3-pytest python3-pytest-runner gnupg2 - gem install --no-ri --no-rdoc rake - gem install --no-ri --no-rdoc package_cloud + DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all dh-python python3-pytest python3-pytest-runner python3-stdeb python3-pyside2.qtcore python3-pyside2.qtwidgets python3-pyside2.qtgui python3-requests python3-socks python3-packaging python3-dateutil gnupg2 + gem install -N rake + gem install -N package_cloud - checkout - run: name: Create the .deb package @@ -91,18 +67,18 @@ jobs: name: Deploy to packagecloud.io command: | VERSION=$(cat share/version |cut -dv -f2) - package_cloud push firstlookmedia/code/ubuntu/eoan deb_dist/gpgsync_${VERSION}-1_all.deb - package_cloud push firstlookmedia/code/ubuntu/eoan deb_dist/gpgsync_${VERSION}-1.dsc + package_cloud push firstlookmedia/code/ubuntu/groovy deb_dist/gpgsync_${VERSION}-1_all.deb + package_cloud push firstlookmedia/code/ubuntu/groovy deb_dist/gpgsync_${VERSION}-1.dsc - build-ubuntu-focal: + build-debian-buster: docker: - - image: ubuntu:20.04 + - image: debian:buster steps: - run: name: Install dependencies command: | apt-get update - DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all python3-all dh-python python3-pyqt5 python3-stdeb python3-requests python3-socks python3-packaging python3-dateutil python3-pytest python3-pytest-runner gnupg2 + DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all dh-python python3-pytest python3-pytest-runner python3-stdeb python3-pyside2.qtcore python3-pyside2.qtwidgets python3-pyside2.qtgui python3-requests python3-socks python3-packaging python3-dateutil gnupg2 gem install --no-ri --no-rdoc rake gem install --no-ri --no-rdoc package_cloud - checkout @@ -115,20 +91,20 @@ jobs: name: Deploy to packagecloud.io command: | VERSION=$(cat share/version |cut -dv -f2) - package_cloud push firstlookmedia/code/ubuntu/focal deb_dist/gpgsync_${VERSION}-1_all.deb - package_cloud push firstlookmedia/code/ubuntu/focal deb_dist/gpgsync_${VERSION}-1.dsc + package_cloud push firstlookmedia/code/debian/buster deb_dist/gpgsync_${VERSION}-1_all.deb + package_cloud push firstlookmedia/code/debian/buster deb_dist/gpgsync_${VERSION}-1.dsc - build-debian-buster: + build-debian-bullseye: docker: - - image: debian:buster + - image: debian:bullseye steps: - run: name: Install dependencies command: | apt-get update - DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all python3-all dh-python python3-pyqt5 python3-stdeb python3-requests python3-socks python3-packaging python3-dateutil python3-pytest python3-pytest-runner gnupg2 - gem install --no-ri --no-rdoc rake - gem install --no-ri --no-rdoc package_cloud + DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all dh-python python3-pytest python3-pytest-runner python3-stdeb python3-pyside2.qtcore python3-pyside2.qtwidgets python3-pyside2.qtgui python3-requests python3-socks python3-packaging python3-dateutil gnupg2 + gem install -N rake + gem install -N package_cloud - checkout - run: name: Create the .deb package @@ -139,41 +115,39 @@ jobs: name: Deploy to packagecloud.io command: | VERSION=$(cat share/version |cut -dv -f2) - package_cloud push firstlookmedia/code/debian/buster deb_dist/gpgsync_${VERSION}-1_all.deb - package_cloud push firstlookmedia/code/debian/buster deb_dist/gpgsync_${VERSION}-1.dsc + package_cloud push firstlookmedia/code/debian/bullseye deb_dist/gpgsync_${VERSION}-1_all.deb + package_cloud push firstlookmedia/code/debian/bullseye deb_dist/gpgsync_${VERSION}-1.dsc - build-debian-bullseye: + build-fedora-31: docker: - - image: debian:bullseye + - image: fedora:31 steps: - run: name: Install dependencies command: | - apt-get update - DEBIAN_FRONTEND=noninteractive apt-get install -y git ssh ruby-dev rubygems build-essential fakeroot python-all python3-all dh-python python3-pyqt5 python3-stdeb python3-requests python3-socks python3-packaging python3-dateutil python3-pytest python3-pytest-runner gnupg2 - gem install --no-ri --no-rdoc rake - gem install --no-ri --no-rdoc package_cloud + dnf install -y git openssh ruby-devel make automake gcc gcc-c++ rpm-build python3-pytest-runner python3-pyside2 python3-requests python3-packaging python3-dateutil gnupg2 + gem install package_cloud - checkout - run: - name: Create the .deb package + name: Create the .rpm package command: | - ./install/build_deb.sh - dpkg -i deb_dist/gpgsync_*.deb + ./install/build_rpm.sh + dnf install -y dist/gpgsync-*-1.noarch.rpm - run: name: Deploy to packagecloud.io command: | VERSION=$(cat share/version |cut -dv -f2) - package_cloud push firstlookmedia/code/debian/bullseye deb_dist/gpgsync_${VERSION}-1_all.deb - package_cloud push firstlookmedia/code/debian/bullseye deb_dist/gpgsync_${VERSION}-1.dsc + package_cloud push firstlookmedia/code/fedora/31 dist/gpgsync-${VERSION}-1.noarch.rpm + package_cloud push firstlookmedia/code/fedora/31 dist/gpgsync-${VERSION}-1.src.rpm - build-fedora-30: + build-fedora-32: docker: - - image: fedora:30 + - image: fedora:32 steps: - run: name: Install dependencies command: | - dnf install -y git openssh ruby-devel make automake gcc gcc-c++ rpm-build qt5-devel python3-qt5 python3-requests python3-pytest-runner python3-packaging python3-dateutil gnupg2 + dnf install -y git openssh ruby-devel make automake gcc gcc-c++ rpm-build python3-pytest-runner python3-pyside2 python3-requests python3-packaging python3-dateutil gnupg2 gem install package_cloud - checkout - run: @@ -185,17 +159,17 @@ jobs: name: Deploy to packagecloud.io command: | VERSION=$(cat share/version |cut -dv -f2) - package_cloud push firstlookmedia/code/fedora/30 dist/gpgsync-${VERSION}-1.noarch.rpm - package_cloud push firstlookmedia/code/fedora/30 dist/gpgsync-${VERSION}-1.src.rpm + package_cloud push firstlookmedia/code/fedora/32 dist/gpgsync-${VERSION}-1.noarch.rpm + package_cloud push firstlookmedia/code/fedora/32 dist/gpgsync-${VERSION}-1.src.rpm - build-fedora-31: +build-fedora-33: docker: - - image: fedora:31 + - image: fedora:33 steps: - run: name: Install dependencies command: | - dnf install -y git openssh ruby-devel make automake gcc gcc-c++ rpm-build qt5-devel python3-qt5 python3-requests python3-pytest-runner python3-packaging python3-dateutil gnupg2 + dnf install -y git openssh ruby-devel make automake gcc gcc-c++ rpm-build python3-pytest-runner python3-pyside2 python3-requests python3-packaging python3-dateutil gnupg2 gem install package_cloud - checkout - run: @@ -207,8 +181,9 @@ jobs: name: Deploy to packagecloud.io command: | VERSION=$(cat share/version |cut -dv -f2) - package_cloud push firstlookmedia/code/fedora/31 dist/gpgsync-${VERSION}-1.noarch.rpm - package_cloud push firstlookmedia/code/fedora/31 dist/gpgsync-${VERSION}-1.src.rpm + package_cloud push firstlookmedia/code/fedora/33 dist/gpgsync-${VERSION}-1.noarch.rpm + package_cloud push firstlookmedia/code/fedora/33 dist/gpgsync-${VERSION}-1.src.rpm + workflows: version: 2 @@ -217,30 +192,18 @@ workflows: - test build-tags: jobs: - - build-ubuntu-bionic: - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - build-ubuntu-disco: - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - - build-ubuntu-eoan: - filters: - tags: - only: /^v.*/ - branches: - ignore: /.*/ - build-ubuntu-focal: filters: tags: only: /^v.*/ branches: ignore: /.*/ + # - build-ubuntu-groovy: + # filters: + # tags: + # only: /^v.*/ + # branches: + # ignore: /.*/ - build-debian-buster: filters: tags: @@ -253,15 +216,21 @@ workflows: only: /^v.*/ branches: ignore: /.*/ - - build-fedora-30: + - build-fedora-31: filters: tags: only: /^v.*/ branches: ignore: /.*/ - - build-fedora-31: + - build-fedora-32: filters: tags: only: /^v.*/ branches: ignore: /.*/ + # - build-fedora-33: + # filters: + # tags: + # only: /^v.*/ + # branches: + # ignore: /.*/ diff --git a/CHANGELOG.md b/CHANGELOG.md index bb45c79..ebd2fa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # GPG Sync Changelog +## 0.3.6 + +* Support macOS Big Sur +* Switch dependencies to PySide2, poetry + ## 0.3.5 * Notarized package in macOS diff --git a/share/version b/share/version index 03f2afa..d379b57 100644 --- a/share/version +++ b/share/version @@ -1 +1 @@ -v0.3.5 +v0.3.6