diff --git a/README.md b/README.md index ba6613d..5c88391 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,8 @@ and then run it by typing: pygpsclient ``` +**NB** If you get `error: externally-managed-environment`, refer to the longer installation guidelines for **virtual environments** using [pip](#pip) or [pipx](#pipx) below. + ## The Longer Version In the following, `python3` & `pip` refer to the Python 3 executables. You may need to substitute `python` for `python3`, depending on your particular environment (*on Windows it's generally `python`*). @@ -135,33 +137,50 @@ To access the serial port on most Linux platforms, you will need to be a member usermod -a -G tty myuser ``` -### Install using pip +### <a name="pip">Install using pip</a>  [](https://pypi.org/project/PyGPSClient/)  -The easiest way to install the latest version of `PyGPSClient` is with [pip](http://pypi.python.org/pypi/pip/): +The recommended way to install the latest version of `PyGPSClient` is with [pip](http://pypi.python.org/pypi/pip/): ```shell python3 -m pip install --upgrade pygpsclient ``` -If required, `PyGPSClient` can also be installed into a virtual environment, e.g.: - +If required, `PyGPSClient` can also be installed and run in a [virtual environment](https://www.geeksforgeeks.org/python-virtual-environment/) - this may be necessary if you have an `externally-managed-environment`, e.g.: ```shell python3 -m venv env source env/bin/activate # (or env\Scripts\activate on Windows) python3 -m pip install --upgrade pygpsclient +pygpsclient ``` -The pip installation process places an executable file `pygpsclient` in the Python binaries folder (`../bin` on Linux & MacOS, `..\Scripts` on Windows). The PyGPSClient application may be started by double-clicking on this executable file from your file manager or, if the binaries folder is in your PATH, by opening a terminal and typing (all lowercase): +To deactivate the virtual environment: ```shell +deactivate +``` + +To reactivate and run from the virtual environment: +```shell +source env/bin/activate # (or env\Scripts\activate on Windows) pygpsclient ``` -`pygpsclient` also accepts optional command line arguments for a variety of configurable parameters. These will override any saved configuration file settings. Type the following for help: +To upgrade PyGPSClient to the latest version from the virtual environment: +```shell +source env/bin/activate # (or env\Scripts\activate on Windows) +python3 -m pip install --upgrade pygpsclient +``` + +The pip installation process places an executable file `pygpsclient` in the Python binaries folder (`../bin` on Linux & MacOS, `..\Scripts` on Windows). The PyGPSClient application may be started by double-clicking on this executable file from your file manager or, if the binaries folder is in your PATH, by opening a terminal and typing (all lowercase): +```shell +pygpsclient +```` + +`pygpsclient` accepts optional command line arguments for a variety of configurable parameters. These will override any saved configuration file settings. Type the following for help: ```shell pygpsclient -h ``` @@ -185,10 +204,20 @@ Typically: 1. Windows: `C:\Users\myuser\AppData\Roaming\Python\Python3**\Scripts\pygpsclient.exe` 2. MacOS: `/Library/Frameworks/Python.framework/Versions/3.**/bin/pygpsclient` 3. Linux: `/home/myuser/.local/bin/pygpsclient` -4. Virtual Env: `env/bin/pygpsclient` (or `env\Scripts\pygpsclient.exe` on Windows) +4. Virtual Env: `$ENV/bin/pygpsclient` (or `$ENV\Scripts\pygpsclient.exe` on Windows), where `$ENV` is the full path to your virtual environment. where `**` signifies the Python version e.g. `3.12`. +### <a name="pipx">Install using pipx</a> + +You can also use [pipx](https://pipx.pypa.io/latest/installation/) (_if available_) to install `pygpsclient` into a virtual environment - use the `pipx ensurepath` command to add the relevant Python binaries folder to your PATH. + +```shell +pipx ensurepath +pipx install pygpsclient +``` + +`pipx` will typically create a virtual environment in the user's local shared folder e.g. `/home/user/.local/share/pipx/venvs/pygpsclient`. ### Creating A Desktop Application Launcher diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c03befd..dbfa620 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,9 @@ # PyGPSClient Release Notes +### RELEASE 1.5.4 + +1. Fix issue with GUI update facility not working for virtual environments. + ### RELEASE 1.5.3 1. Fix issue with displaying final content of file in console after EOF condition. diff --git a/src/pygpsclient/_version.py b/src/pygpsclient/_version.py index c92ec02..41a6226 100644 --- a/src/pygpsclient/_version.py +++ b/src/pygpsclient/_version.py @@ -8,4 +8,4 @@ :license: BSD 3-Clause """ -__version__ = "1.5.3" +__version__ = "1.5.4" diff --git a/src/pygpsclient/about_dialog.py b/src/pygpsclient/about_dialog.py index 4c7932a..52cefd7 100644 --- a/src/pygpsclient/about_dialog.py +++ b/src/pygpsclient/about_dialog.py @@ -10,9 +10,12 @@ :license: BSD 3-Clause """ +import logging +from inspect import currentframe, getfile +from os import path from platform import python_version from subprocess import CalledProcessError, run -from sys import platform +from sys import executable from tkinter import Button, Checkbutton, E, Frame, IntVar, Label, Tcl, Toplevel, W from webbrowser import open_new_tab @@ -50,7 +53,7 @@ class AboutDialog: About dialog box class """ - def __init__(self, app, **kwargs): + def __init__(self, app, **kwargs): # pylint: disable=unused-argument """ Initialise Toplevel dialog @@ -59,6 +62,7 @@ def __init__(self, app, **kwargs): self.__app = app # Reference to main application class self.__master = self.__app.appmaster # Reference to root class (Tk) + self.logger = logging.getLogger(__name__) self._dialog = Toplevel() self._dialog.title = DLGABOUT self._dialog.geometry( @@ -258,26 +262,30 @@ def _do_update(self, *args, **kwargs): # pylint: disable=unused-argument self._btn_checkupdate.config(text="UPDATING...", fg="blue") self._dialog.update_idletasks() - pyc = "python" if platform == "win32" else "python3" - cmd = [ - pyc, - "-m", - "pip", - "install", - "--upgrade", - "--user", - "--force-reinstall", - ] - for pkg in self._updates: - cmd.append(pkg) - + pth = path.dirname(path.abspath(getfile(currentframe()))) + if "pipx" in pth: # installed into venv using pipx + cmd = [ + "pipx", + "upgrade", + "pygpsclient", + ] + else: # installed using pip + cmd = [ + executable, # i.e. python3 or python + "-m", + "pip", + "install", + "--upgrade", + ] + for pkg in self._updates: + cmd.append(pkg) + + result = None try: - run( - cmd, - check=True, - capture_output=True, - ) + result = run(cmd, check=True, capture_output=True) + self.logger.debug(result.stdout) except CalledProcessError: + self.logger.error(result.stdout) self._btn_checkupdate.config(text="UPDATE FAILED", fg="red") self._btn_checkupdate.bind("<Button>", self._check_for_update) return