From 57d5139b249ebdbc987b5023af05a2f33f60c96c Mon Sep 17 00:00:00 2001 From: ArndalAndersen Date: Wed, 1 May 2019 13:07:40 +0200 Subject: [PATCH 1/2] ENH: Update workflow to create executable --- CHANGES.md | 1 + EXECUTABLE.md | 10 ++++++---- pyqmix_backend/run.py | 2 +- pyqmix_backend/run.spec | 10 ++++++---- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 319e5d4..5e9cfa9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,6 @@ 2019.1 ------ +- Improve, fix, and update how to create an executable - Turn `pyqmix-web` into a proper Python package that can be published on PyPI - Add entry point script, such that the user can now simply enter `pyqmix-web` in their terminal after installation, which will fire up the backend and diff --git a/EXECUTABLE.md b/EXECUTABLE.md index f8d4728..ebe7059 100644 --- a/EXECUTABLE.md +++ b/EXECUTABLE.md @@ -3,14 +3,15 @@ ## This guideline assumes that: - A `run.py` file has been created. Check out the `run.py` file in this repository. -- Flask serves static files from the `pyqmix` sub-directory of an automatically created temporary folder. The exact location of this folder is saved in the environment variable `_MEIPASS` when the `PyInstaller`-created standalone exectuable is started. Typically it will be located inside the current user's `AppData\Local\Temp` folder. +- Flask serves static files from an automatically created temporary folder. The exact location of this folder is saved in the environment variable `_MEIPASS` when the `PyInstaller`-created standalone exectuable is started. Typically it will be located inside the current user's `AppData\Local\Temp` folder. Check out the `app.py` file in this repository. - The frontend and backend are located in neighboring directories ## Prepare the Python virtual environment for the backend - Create a virtual environment -- Install the required dependencies: `flask`, `flask-restplus`, and, of course, `pyqmix` -- Install `PyInstaller` +- Install the required dependencies: ` pip install flask flask-restplus pyqmix`. The executable will only work if flask and flask-restplus are installed via pip. +- Install PyInstaller: `pip install PyInstaller` +- The newest `jsonschema` module does not work with PyInstaller. Instead, use `jsonchema` in an older version, for example: 2.6.0. ## Create a production build of the React frontend 1. Open a terminal @@ -35,7 +36,8 @@ This will create a run.spec file in the backend directory. ``` * Edit pathex to: `pathex=[spec_root]` * Edit datas to: `datas=[('../name_of_frontend_folder/build', 'name_of_web_application')]` - + * Optionally, you can add an icon to your standalone. Add `icon='../pyqmix_frontend/public/pyqmixweb_desktop_icon.ico'` to the EXE-section of run.spec. + ## Build the executable 1. Open a terminal 2. Browse to the `pyqmix_backend` directory diff --git a/pyqmix_backend/run.py b/pyqmix_backend/run.py index e81c4aa..4910669 100644 --- a/pyqmix_backend/run.py +++ b/pyqmix_backend/run.py @@ -1,5 +1,5 @@ import webbrowser -from .backend_app import app +from pyqmix_backend.backend_app import app import threading import time from urllib import request diff --git a/pyqmix_backend/run.spec b/pyqmix_backend/run.spec index b1e1898..9f5dc38 100644 --- a/pyqmix_backend/run.spec +++ b/pyqmix_backend/run.spec @@ -4,10 +4,10 @@ # See: # https://stackoverflow.com/a/50402636/1944216 # https://pythonhosted.org/PyInstaller/spec-files.html#globals-available-to-the-spec-file +block_cipher = None import os spec_root = os.path.abspath(SPECPATH) - a = Analysis(['run.py'], pathex=[spec_root], binaries=[], @@ -18,18 +18,20 @@ a = Analysis(['run.py'], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, - cipher=block_cipher) + cipher=block_cipher, + noarchive=False) pyz = PYZ(a.pure, a.zipped_data, - cipher=None) - + cipher=block_cipher) exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, + [], name='pyqmix-web', debug=False, + bootloader_ignore_signals=False, strip=False, upx=True, runtime_tmpdir=None, From 4404a989a3fd9fea2f161cc65cd58efdc2f0d54b Mon Sep 17 00:00:00 2001 From: ArndalAndersen Date: Wed, 1 May 2019 13:01:07 +0200 Subject: [PATCH 2/2] ENH: Styling of modals served via the frontend-build. --- CHANGES.md | 1 + EXECUTABLE.md | 2 +- pyqmix_frontend/src/App.css | 4 ++-- pyqmix_frontend/src/App.js | 20 +++++++++++--------- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5e9cfa9..fb8eeda 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ open the browser - Add versioneer - Enable user to specify pump configuration directory +- Styling of frontend served via the build - Update to `react-scripts` 2.1.3 2018.11.07 diff --git a/EXECUTABLE.md b/EXECUTABLE.md index ebe7059..28ee260 100644 --- a/EXECUTABLE.md +++ b/EXECUTABLE.md @@ -44,4 +44,4 @@ This will create a run.spec file in the backend directory. 3. Activate the virtual environment 4. Type: `pyinstaller --clean run.spec` -This generates a `run.exe` file inside the backend's `dist` folder. +This generates a `.exe` file inside the backend's `dist` folder. diff --git a/pyqmix_frontend/src/App.css b/pyqmix_frontend/src/App.css index 3f2d170..9988ff4 100644 --- a/pyqmix_frontend/src/App.css +++ b/pyqmix_frontend/src/App.css @@ -70,8 +70,8 @@ body { } } -.text-modal { - white-space: pre-line; +.modal-input { + text-align: left; } .form-control { diff --git a/pyqmix_frontend/src/App.js b/pyqmix_frontend/src/App.js index 228738b..9a0e203 100644 --- a/pyqmix_frontend/src/App.js +++ b/pyqmix_frontend/src/App.js @@ -730,7 +730,7 @@ class PumpForm extends Component { + className="modal-input"> Select a pump configuration {/**/} @@ -809,7 +809,7 @@ class PumpForm extends Component { + className="modal-input"> Error - no pumps were detected. Ensure that: @@ -860,7 +860,8 @@ class PumpForm extends Component { disabled={this.state.selectedPumps.length === 0} > Reference Move Calibrate the selected pumps. - + Reference Move Detach all syringes from the pumps before continuing. @@ -894,7 +895,8 @@ class PumpForm extends Component { > Fill Cycle Fill & empty the syringe multiple times. Ends with a filled syringe. - + Fill Insert the inlet tube into the stimulus reservoir and @@ -971,7 +973,7 @@ class PumpForm extends Component { Empty & fill the syringe multiple times. Ends with an empty syringe. + className="modal-input"> Empty Remove the inlet tube from the stimulus reservoir and @@ -1045,7 +1047,7 @@ class PumpForm extends Component { > Bubble Cycle Guided procedure to remove air bubbles trapped in the syringe. Ends with a filled syringe. + className="modal-input"> Bubble Cycle Insert the inlet tube into the stimulus reservoir. @@ -1060,7 +1062,7 @@ class PumpForm extends Component { + className="modal-input"> Bubble Cycle Remove the inlet tube from the stimulus reservoir to aspirate air. @@ -1077,7 +1079,7 @@ class PumpForm extends Component { + className="modal-input"> Bubble Cycle Insert the inlet tube into the stimulus reservoir. @@ -1140,7 +1142,7 @@ class PumpForm extends Component { > Rinse Cycle Empty & fill the syringe multiple times. Ends with an empty syringe. + className="modal-input"> Rinse Insert the inlet tube into the rinsing fluid