From b75fb4a4dbd7e81aa888a07200656f0319adf489 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Thu, 15 Feb 2024 20:32:32 -0500 Subject: [PATCH 01/11] Add venv to install.sh --- .gitignore | 1 + README.md | 18 ++++++++++++------ install.sh | 40 ++++++++++++++++++++++++++++++++++------ 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index e8b4f3dd..29e0a885 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ wheels/ .installed.cfg *.egg MANIFEST +venv/ # PyInstaller # Usually these files are written by a python script from a template diff --git a/README.md b/README.md index 198bc75e..4197ee33 100755 --- a/README.md +++ b/README.md @@ -118,6 +118,9 @@ cd mlb-led-scoreboard/ sudo ./install.sh ``` +This will create a Python Virtual Environment and install all of the required dependencies. The +virtual environment will be located at `mlb-led-scoreboard/venv/`. + This will install the rgbmatrix binaries, which we get from [another open source library](https://github.com/hzeller/rpi-rgb-led-matrix/tree/master/bindings/python#building). It controls the actual rendering of the scoreboard onto the LEDs. If you're curious, you can read through their documentation on how all of the lower level stuff works. It will also install the following python libraries that are required for certain parts of the scoreboard to function. @@ -144,7 +147,7 @@ Additional flags are available for customizing your install: -c, --skip-config Skips default config overwrite without prompting. -a, --skip-all Performs all above skips. - +--no-venv Do not create a virtual environment for the dependencies. --emulator-only Do not install dependencies under sudo. Skips building matrix dependencies. -h, --help Displays help @@ -167,11 +170,14 @@ The latest version of the software is available [here](https://github.com/MLB-LE Make sure your Raspberry Pi's timezone is configured to your local time zone. They'll often have London time on them by default. You can change the timezone of your raspberry pi by running `sudo raspi-config`. ## Usage -`sudo python3 main.py` Running as root is 100% an absolute must, or the matrix won't render. +The installation script adds a line to the top of `main.py` to automatically pick up the virtual environment. +This means re-activating the environment (`source ./venv/bin/activate`) is not a requirement. + +`sudo ./main.py` Running as root is 100% an absolute must, or the matrix won't render. **Adafruit HAT/Bonnet users: You must supply a command line flag:** -`sudo python3 main.py --led-gpio-mapping="adafruit-hat"` +`sudo ./main.py --led-gpio-mapping="adafruit-hat"` See the Flags section below for more flags you can optionally provide. @@ -180,13 +186,13 @@ See the Flags section below for more flags you can optionally provide. The scoreboard can run on other platforms by means of software emulation via `RGBMatrixEmulator`. When running via the emulator, you do not need to prepend your startup commands with `sudo`: ```sh -python3 main.py +./main.py ``` You can also force the scoreboard into emulation mode by using the `--emulated` flag: ```sh -python3 main.py --emulated +./main.py --emulated ``` When running in emulation mode, you can continue to use your existing command line flags as normal. @@ -262,7 +268,7 @@ A default `config.json.example` file is included for reference. Copy this file t * Pitch Data - Pitch data can be shown on the game screen, See the [coordinates readme file](/coordinates/README.md) for details. In addition, the `short` and `long` pitch description can be changed in data/pitches.py * Previous Play Data - Data for the previous play can be shown on the game screen. See the [coordinates readme file](/coordinates/README.md) for details. Long and short play descriptions can be changed in data/plays.py - * **NOTE:** Because play result data is ephemeral, not every play result will be displayed. Situations like a mound visit, injury, or other timeout immediately following a play often cause the play result to be immediately replaced on the MLB API. + * **NOTE:** Because play result data is ephemeral, not every play result will be displayed. Situations like a mound visit, injury, or other timeout immediately following a play often cause the play result to be immediately replaced on the MLB API. ### Flags diff --git a/install.sh b/install.sh index a0a62edf..12e2e8e4 100755 --- a/install.sh +++ b/install.sh @@ -11,7 +11,7 @@ usage() { -p, --skip-python: Skip Python 3 installation. Requires manual Python 3 setup if not already installed. -a, --skip-all: Skip all dependencies and config installation (equivalent to -c -p -m). - + --no-venv Do not create a virtual environment for the dependencies. --emulator-only: Do not install dependencies under sudo. Skips building matrix dependencies (equivalent to -m) USAGE @@ -22,6 +22,7 @@ SKIP_PYTHON=false SKIP_CONFIG=false SKIP_MATRIX=false NO_SUDO=false +SKIP_VENV=false for arg in "$@"; do case $arg in @@ -41,6 +42,7 @@ for arg in "$@"; do SKIP_CONFIG=true SKIP_MATRIX=true SKIP_PYTHON=true + SKIP_VENV=true shift # Remove -a / --skip-all from `$@` ;; --emulator-only) @@ -48,6 +50,10 @@ for arg in "$@"; do NO_SUDO=true shift # remove --emulator-only from `$@` ;; + --no-venv) + SKIP_VENV=true + shift # remove --no-venv from `$@` + ;; -h | --help) usage # run usage function on help ;; @@ -69,6 +75,7 @@ if [ "$SKIP_PYTHON" = false ]; then python3-pip \ python3-pillow \ python3-tk \ + python3-venv \ libxml2-dev \ libxslt-dev \ libsdl2-mixer-2.0-0 \ @@ -84,10 +91,31 @@ echo " Installing dependencies..." echo "------------------------------------" echo +if [ "$SKIP_VENV" = false ]; then + echo "Creating virtual environment..." + if [ "$NO_SUDO" = false ]; then + sudo python3 -m venv ./venv + else + python3 -m venv ./venv + fi + source ./venv/bin/activate + + + if ! grep -q "#\!/" main.py; then + if [ "$NO_SUDO" = false ]; then + sed -i "1i #\!/usr/bin/sudo $(which python3)" main.py + else + sed -i "1i #\!$(which python3)" main.py + fi + chmod +x main.py + fi +fi +PYTHON=$(which python3) + if [ "$NO_SUDO" = false ]; then - sudo python3 -m pip install -r requirements.txt + sudo "$PYTHON" -m pip install -r requirements.txt else - python3 -m pip install -r requirements.txt + "$PYTHON" -m pip install -r requirements.txt fi if [ "$SKIP_MATRIX" = false ]; then @@ -97,8 +125,8 @@ if [ "$SKIP_MATRIX" = false ]; then git clone https://github.com/hzeller/rpi-rgb-led-matrix.git matrix cd matrix git pull - make build-python PYTHON=$(which python3) - sudo make install-python PYTHON=$(which python3) + make build-python PYTHON="$PYTHON" + sudo make install-python PYTHON="$PYTHON" cd ../.. fi @@ -123,7 +151,7 @@ else echo " update them with the latest options at this time." echo echo " This operation is automatic and will ensure you have up-to-date configuration." - echo + echo echo " This action will NOT override any custom configuration you already have unless" echo " the option has been obsoleted and is no longer in use." echo "===================================================================================" From c9b10f09e27b2bd3791d2aa24d5e387313a2bb4b Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Fri, 16 Feb 2024 22:48:42 -0500 Subject: [PATCH 02/11] Extra git magic to skip the shebang line in main --- .git-config-template | 4 ++++ .gitattributes | 1 + install.sh | 4 ++++ 3 files changed, 9 insertions(+) create mode 100644 .git-config-template create mode 100644 .gitattributes diff --git a/.git-config-template b/.git-config-template new file mode 100644 index 00000000..46177aec --- /dev/null +++ b/.git-config-template @@ -0,0 +1,4 @@ +[filter "noshebang"] + clean = grep -v '.!/.*python3' + smudge = cat + required diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..eac12b97 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +main.py filter=noshebang diff --git a/install.sh b/install.sh index 12e2e8e4..98d9ec5f 100755 --- a/install.sh +++ b/install.sh @@ -108,6 +108,10 @@ if [ "$SKIP_VENV" = false ]; then sed -i "1i #\!$(which python3)" main.py fi chmod +x main.py + + if ! grep -q "noshebang" ./.git/config; then + cat .git-config-template >> .git/config + fi fi fi PYTHON=$(which python3) From 78ab6f62172428e6233c040662c86fe777373213 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Tue, 20 Feb 2024 20:24:08 -0500 Subject: [PATCH 03/11] added check for osx bsd style sed in installer --- install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 98d9ec5f..88633d58 100755 --- a/install.sh +++ b/install.sh @@ -102,7 +102,9 @@ if [ "$SKIP_VENV" = false ]; then if ! grep -q "#\!/" main.py; then - if [ "$NO_SUDO" = false ]; then + if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' '1i\'$'\n''#!'"$(which python3)"$'\n' main.py + elif [ "$NO_SUDO" = false ]; then sed -i "1i #\!/usr/bin/sudo $(which python3)" main.py else sed -i "1i #\!$(which python3)" main.py From 074525374d1681a6e5badb1939a75abff8888a4d Mon Sep 17 00:00:00 2001 From: Tyler Porter Date: Tue, 20 Feb 2024 22:36:51 -0500 Subject: [PATCH 04/11] Bump version to 8.0.0 --- version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.py b/version.py index 0fbb7e62..35b569d2 100644 --- a/version.py +++ b/version.py @@ -1,5 +1,5 @@ SCRIPT_NAME = "MLB LED Scoreboard" -SCRIPT_VERSION = "7.0.0" +SCRIPT_VERSION = "8.0.0" if __name__ == "__main__": From 89d6ed5fddba9af70e9b58add940c6b6a12962c5 Mon Sep 17 00:00:00 2001 From: Nicholas Saraniti Date: Thu, 22 Feb 2024 12:26:51 -0500 Subject: [PATCH 05/11] Added apt command to install make --- install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/install.sh b/install.sh index 98d9ec5f..330d385c 100755 --- a/install.sh +++ b/install.sh @@ -124,6 +124,7 @@ fi if [ "$SKIP_MATRIX" = false ]; then echo "Running rgbmatrix installation..." + sudo apt-get install -y make mkdir submodules cd submodules git clone https://github.com/hzeller/rpi-rgb-led-matrix.git matrix From 9cfacb23519c246a477d5a985b4b2f5efe9ca751 Mon Sep 17 00:00:00 2001 From: Tyler Porter Date: Tue, 20 Feb 2024 22:41:23 -0500 Subject: [PATCH 06/11] Remove Pillow patch, require Pillow > 10.0.1 Run CI on Python > 3.8 Update action to v5 Add list of supported Pythons --- .github/workflows/run_unittest_on_pr_open.yml | 4 ++-- README.md | 3 ++- main.py | 18 ++---------------- renderers/offday.py | 15 ++++----------- requirements.txt | 13 +------------ 5 files changed, 11 insertions(+), 42 deletions(-) diff --git a/.github/workflows/run_unittest_on_pr_open.yml b/.github/workflows/run_unittest_on_pr_open.yml index c50fde17..39cba2a7 100644 --- a/.github/workflows/run_unittest_on_pr_open.yml +++ b/.github/workflows/run_unittest_on_pr_open.yml @@ -12,11 +12,11 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] + python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies diff --git a/README.md b/README.md index a2bf8b08..a797f8bc 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # mlb-led-scoreboard -![Current Version](https://img.shields.io/github/v/release/MLB-LED-Scoreboard/MLB-LED-Scoreboard) [![Join Discord](https://img.shields.io/badge/discord-join-blue.svg)](https://discord.gg/FdD6ec9fdt) +![Current Version](https://img.shields.io/github/v/release/MLB-LED-Scoreboard/MLB-LED-Scoreboard) ![](https://img.shields.io/badge/python-3.8_%7C_3.9_%7C_3.10_%7C_3.11-blue) +[![Join Discord](https://img.shields.io/badge/discord-join-green.svg)](https://discord.gg/FdD6ec9fdt) Project header diff --git a/main.py b/main.py index aed14378..563c3d8e 100755 --- a/main.py +++ b/main.py @@ -21,21 +21,7 @@ import threading import time -# TODO: This code addresses CVE-2023-4863 in Pillow < 10.0.1, which requires Python 3.8+ -# See requirements.txt for rationale. -try: - from PIL import Image - - pil_version = tuple(map(int, Image.__version__.split("."))) - if pil_version < (10, 0, 1): - debug.warning(f"Attempted to load an insecure PIL version ({Image.__version__}). We require PIL 10.0.1 or higher.") - - raise ModuleNotFoundError - - PIL_LOADED = True -except: - debug.warning("PIL failed to load -- images will not be displayed.") - PIL_LOADED = False +from PIL import Image # Important! Import the driver first to initialize it, then import submodules as needed. import driver @@ -74,7 +60,7 @@ def main(matrix, config_base): # MLB image disabled when using renderer, for now. # see: https://github.com/ty-porter/RGBMatrixEmulator/issues/9#issuecomment-922869679 - if os.path.exists(logo_path) and driver.is_hardware() and PIL_LOADED: + if os.path.exists(logo_path) and driver.is_hardware(): logo = Image.open(logo_path) matrix.SetImage(logo.convert("RGB")) logo.close() diff --git a/renderers/offday.py b/renderers/offday.py index 94a4a042..338b70c3 100644 --- a/renderers/offday.py +++ b/renderers/offday.py @@ -2,13 +2,7 @@ import time -try: - from PIL import Image - - PIL_LOADED = True -except: - - PIL_LOADED = False +from PIL import Image from data.time_formats import TIME_FORMAT_12H from data.config.color import Color @@ -44,10 +38,9 @@ def __render_clock(canvas, layout, colors, time_format): def __render_weather(canvas, layout, colors, weather): if weather.available(): - if PIL_LOADED: - image_file = weather.icon_filename() - weather_icon = Image.open(image_file) - __render_weather_icon(canvas, layout, colors, weather_icon) + image_file = weather.icon_filename() + weather_icon = Image.open(image_file) + __render_weather_icon(canvas, layout, colors, weather_icon) __render_weather_text(canvas, layout, colors, weather.conditions, "conditions") __render_weather_text(canvas, layout, colors, weather.temperature_string(), "temperature") __render_weather_text(canvas, layout, colors, weather.wind_speed_string(), "wind_speed") diff --git a/requirements.txt b/requirements.txt index 50f84928..3f95f664 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,17 +1,6 @@ feedparser==6.0.10 MLB_StatsAPI>=1.6.1 -# PIL is affected by CVE-2023-4863 -# https://nvd.nist.gov/vuln/detail/CVE-2023-4863 -# -# The vulnerability is patched in Pillow >= 10.0.1. This version does not support Python 3.7 due to this version being end-of-life. -# Python 3.7.3 is the default Python version for Raspbian / Raspberry Pi OS, and upgrading Python versions is difficult for non-technical users. -# -# Therefore, addressing the CVE at this time would be a breaking change for most users without an easy upgrade path to Python 3.8+. -# -# Dependabot PR: -# https://github.com/MLB-LED-Scoreboard/mlb-led-scoreboard/pull/502 -# -# Pillow==9.3.1 +Pillow>=10.0.1 pyowm==3.3.0 RGBMatrixEmulator>=0.8.4 tzlocal==4.2 From 0521393416dddbea6a0800f191b3082a333a15a7 Mon Sep 17 00:00:00 2001 From: Tyler Porter Date: Tue, 27 Feb 2024 01:20:08 -0500 Subject: [PATCH 07/11] Do not drop privilege when running RGBM --- README.md | 1 + utils.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/README.md b/README.md index a2bf8b08..ab275517 100755 --- a/README.md +++ b/README.md @@ -294,6 +294,7 @@ You can configure your LED matrix with the same flags used in the [rpi-rgb-led-m --led-pwm-dither-bits Time dithering of lower bits (Default: 0) --config Specify a configuration file name other, omitting json xtn (Default: config) --emulated Force the scoreboard to run in software emulation mode. +--drop-privileges Force the matrix driver to drop root privileges after setup. (Default: false) ``` ## Personalization diff --git a/utils.py b/utils.py index 05119a72..237b80f6 100644 --- a/utils.py +++ b/utils.py @@ -126,6 +126,9 @@ def args(): help="Force using emulator mode over default matrix display.", const=True ) + parser.add_argument( + "--drop-privileges", action="store_false", help="Force the matrix driver to drop root privileges after setup." + ) return parser.parse_args() @@ -148,6 +151,7 @@ def led_matrix_options(args): options.scan_mode = args.led_scan_mode options.pwm_lsb_nanoseconds = args.led_pwm_lsb_nanoseconds options.led_rgb_sequence = args.led_rgb_sequence + options.drop_privileges = args.drop_privileges try: options.pixel_mapper_config = args.led_pixel_mapper From 8cb23182c72f56ca8ac8f82c828d68131a18e56d Mon Sep 17 00:00:00 2001 From: Tyler Porter Date: Tue, 27 Feb 2024 16:45:28 -0500 Subject: [PATCH 08/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab275517..8e7e52dd 100755 --- a/README.md +++ b/README.md @@ -294,7 +294,7 @@ You can configure your LED matrix with the same flags used in the [rpi-rgb-led-m --led-pwm-dither-bits Time dithering of lower bits (Default: 0) --config Specify a configuration file name other, omitting json xtn (Default: config) --emulated Force the scoreboard to run in software emulation mode. ---drop-privileges Force the matrix driver to drop root privileges after setup. (Default: false) +--drop-privileges Force the matrix driver to drop root privileges after setup. (Default: true) ``` ## Personalization From 14d41d82380a03eb51827cecd1e3269f65aca2d1 Mon Sep 17 00:00:00 2001 From: Tyler Porter Date: Tue, 27 Feb 2024 16:45:42 -0500 Subject: [PATCH 09/11] Update utils.py --- utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils.py b/utils.py index 237b80f6..f4624f3a 100644 --- a/utils.py +++ b/utils.py @@ -127,7 +127,7 @@ def args(): const=True ) parser.add_argument( - "--drop-privileges", action="store_false", help="Force the matrix driver to drop root privileges after setup." + "--drop-privileges", action="store_true", help="Force the matrix driver to drop root privileges after setup." ) return parser.parse_args() From 9e563b92ead1091f761b3be04f67691d2af8910a Mon Sep 17 00:00:00 2001 From: Tyler Porter Date: Wed, 28 Feb 2024 01:29:25 -0500 Subject: [PATCH 10/11] Update install.sh --- install.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/install.sh b/install.sh index 2e131fa8..8f4036aa 100755 --- a/install.sh +++ b/install.sh @@ -100,19 +100,21 @@ if [ "$SKIP_VENV" = false ]; then fi source ./venv/bin/activate - if ! grep -q "#\!/" main.py; then if [[ "$OSTYPE" == "darwin"* ]]; then sed -i '' '1i\'$'\n''#!'"$(which python3)"$'\n' main.py elif [ "$NO_SUDO" = false ]; then - sed -i "1i #\!/usr/bin/sudo $(which python3)" main.py + sed -i "1i #\!/usr/bin/sudo $(which python3)" main.py else - sed -i "1i #\!$(which python3)" main.py + sed -i "1i #\!$(which python3)" main.py fi chmod +x main.py if ! grep -q "noshebang" ./.git/config; then + # Add template to .git/config, and trigger the filter by adding the file. + # After that, the shebang should be ignored. cat .git-config-template >> .git/config + git add main.py fi fi fi From a3c2c30717971833ffeace245069c0357797bf3c Mon Sep 17 00:00:00 2001 From: Tyler Porter Date: Wed, 28 Feb 2024 01:36:32 -0500 Subject: [PATCH 11/11] Fix bug in shebang ignore --- install.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/install.sh b/install.sh index 8f4036aa..27cf25df 100755 --- a/install.sh +++ b/install.sh @@ -110,12 +110,13 @@ if [ "$SKIP_VENV" = false ]; then fi chmod +x main.py + # Add template to .git/config (if it doesn't already exist), and trigger the filter by adding the file. + # After that, the shebang should be ignored. if ! grep -q "noshebang" ./.git/config; then - # Add template to .git/config, and trigger the filter by adding the file. - # After that, the shebang should be ignored. cat .git-config-template >> .git/config - git add main.py fi + + git add main.py fi fi PYTHON=$(which python3)