diff --git a/.githooks/post-merge b/.githooks/post-merge index 6fc6e4f54..07b81db41 100755 --- a/.githooks/post-merge +++ b/.githooks/post-merge @@ -43,6 +43,7 @@ warn_python_requirements() { echo "ATTENTION: Python requirements have changed since last pull!" echo "" echo "To update python requirements on the RPi run" + echo "$ source .venv/bin/activate" echo "$ python -m pip install --upgrade -r requirements.txt" echo "************************************************************" echo -e "\n" diff --git a/.github/workflows/codeql-analysis_v3.yml b/.github/workflows/codeql-analysis_v3.yml index 1c1c68ba3..89693df2a 100644 --- a/.github/workflows/codeql-analysis_v3.yml +++ b/.github/workflows/codeql-analysis_v3.yml @@ -45,6 +45,9 @@ jobs: run: | # Install necessary packages sudo apt-get install libasound2-dev pulseaudio + python3 -m venv .venv + source ".venv/bin/activate" + python -m pip install --upgrade pip pip install -r requirements.txt # Set the `CODEQL-PYTHON` environment variable to the Python executable diff --git a/.github/workflows/pythonpackage_future3.yml b/.github/workflows/pythonpackage_future3.yml index f2174d0c0..2236a5a47 100644 --- a/.github/workflows/pythonpackage_future3.yml +++ b/.github/workflows/pythonpackage_future3.yml @@ -31,6 +31,9 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libasound2-dev pulseaudio + python3 -m venv .venv + source ".venv/bin/activate" + python3 -m pip install --upgrade pip pip3 install -r requirements.txt # For operation of the Jukebox, ZMQ must be compiled from sources due to Websocket support @@ -51,7 +54,6 @@ jobs: parallel: true - name: Lint with flake8 run: | - pip3 install flake8 # Stop the build if linting fails ./run_flake8.sh diff --git a/documentation/builders/configuration.md b/documentation/builders/configuration.md index 2e1c4ff23..dd4c1fd53 100644 --- a/documentation/builders/configuration.md +++ b/documentation/builders/configuration.md @@ -1,15 +1,15 @@ # Jukebox Configuration The Jukebox configuration is managed by a set of files located in `shared/settings`. -Some configuration changes can be made through the WebUI and take immediate effect. +Some configuration changes can be made through the Web App and take immediate effect. -The majority of configuration options is only available by editing the config files - +The majority of configuration options are only available by editing the config files - *when the service is not running!* Don't fear (overly), they contain commentaries. -For several aspects we have [configuration tools](../developers/coreapps.md#configuration-tools) and [detailed guides](./README.md#features). +For several aspects, we have [configuration tools](../developers/coreapps.md#configuration-tools) and [detailed guides](./README.md#features). -Even after running the tools, certain aspects can only be changed by modifying the configuration files directly. +Even after using the tools, certain aspects can only be changed by directly modifying the configuration files. ## Best practice procedure @@ -21,19 +21,17 @@ $ systemctl --user stop jukebox-daemon $ nano ./shared/settings/jukebox.yaml # Start Jukebox in console and check the log output (optional) -$ cd src/jukebox -$ ./run_jukebox.py +$ ./run_jukebox.sh # and if OK, press Ctrl-C and restart the service # Restart the service $ systemctl --user start jukebox-daemon ``` - -To try different configurations, you can start the Jukebox with a custom config file. +To try different configurations, you can start the Jukebox with a custom config file. This could be useful if you want your Jukebox to only allow a lower volume when started -at night time when there is time to go to bed :-) +at nighttime, signaling it's time to go to bed. :-) +The path to the custom config file must be either absolute or relative to the folder `src/jukebox/`. ```bash -$ cd src/jukebox -$ ./run_jukebox.py --conf path/to/custom/config.yaml +$ ./run_jukebox.sh --conf /absolute/path/to/custom/config.yaml ``` diff --git a/documentation/builders/troubleshooting.md b/documentation/builders/troubleshooting.md index ffc5189dc..5b4061aa8 100644 --- a/documentation/builders/troubleshooting.md +++ b/documentation/builders/troubleshooting.md @@ -64,12 +64,10 @@ on the console log. $ systemctl --user stop jukebox-daemon # Start the Jukebox in debug mode: -$ cd src/jukebox - # with default logger: -$ ./run_jukebox.py +$ ./run_jukebox.sh # or with custom logger configuration: -$ ./run_jukebox.py --logger path/to/custom/logger.yaml +$ ./run_jukebox.sh --logger path/to/custom/logger.yaml ``` ### Fallback configuration @@ -79,8 +77,7 @@ Attention: This only emits messages to the console and does not write to the log This is more a fallback features: ```bash -$ cd src/jukebox -$ ./run_jukebox.py -vv +$ ./run_jukebox.sh -vv ``` ### Extreme cases diff --git a/documentation/developers/coreapps.md b/documentation/developers/coreapps.md index f1402683d..80b3c043a 100644 --- a/documentation/developers/coreapps.md +++ b/documentation/developers/coreapps.md @@ -1,7 +1,6 @@ # Jukebox Apps -The Jukebox\'s core apps are located in `src/jukebox`. Run the following -command to learn more about each app and its parameters: +The Jukebox's core apps are located in `src/jukebox`. To learn more about each app and its parameters, run the following command: ``` bash $ cd src/jukebox @@ -10,13 +9,13 @@ $ ./ -h ## Jukebox Core -**Scriptname:** [run_jukebox.py](../../src/jukebox/run_jukebox.py) +**Scriptname:** [run_jukebox.sh](../../run_jukebox.sh) -This is the main app and starts the Jukebox Core. +This is the main app. It starts the Jukebox Core. -Usually this runs as a service, which is started automatically after boot-up. At times, it may be necessary to restart the service. For example after a configuration change. Not all configuration changes can be applied on-the-fly. See [Jukebox Configuration](../builders/configuration.md#jukebox-configuration). +This runs as a service, which starts automatically after boot-up. At times, it may be necessary to restart the service, for example, after a configuration change. Not all configuration changes can be applied on-the-fly. See [Jukebox Configuration](../builders/configuration.md#jukebox-configuration). -For debugging, it is usually desirable to run the Jukebox directly from the console rather than as service. This gives direct logging info in the console and allows changing command line parameters. See [Troubleshooting](../builders/troubleshooting.md). +For debugging, it's best to run Jukebox directly from the console rather than as a service, as this provides direct logging information in the console and allows for changing command line parameters. See [Troubleshooting](../builders/troubleshooting.md). ## Configuration Tools @@ -25,41 +24,39 @@ See [Best practice procedure](../builders/configuration.md#best-practice-procedu ### Audio -**Scriptname:** [run_configure_audio.py](../../src/jukebox/run_configure_audio.py) +**Scriptname:** [setup_configure_audio.sh](../../installation/components/setup_configure_audio.sh) -Setup tool to register the PulseAudio sinks as primary and secondary audio outputs. +A setup tool to register the PulseAudio sinks as primary and secondary audio outputs. -Will also setup equalizer and mono down mixer in the pulseaudio config file. Run this once after installation. Can be re-run at any time to change the settings. For more information see [Audio Configuration](../builders/audio.md). +This will also set up an equalizer and mono downmixer in the PulseAudio configuration file. Run this once after installation. It can be re-run at any time to change the settings. For more information see [Audio Configuration](../builders/audio.md). ### RFID Reader -**Scriptname:** [run_register_rfid_reader.py](../../src/jukebox/run_register_rfid_reader.py) +**Scriptname:** [setup_rfid_reader.sh](../../installation/components/setup_rfid_reader.sh) Setup tool to configure the RFID Readers. -Run this once to register and configure the RFID readers with the Jukebox. Can be re-run at any time to change the settings. For more information see [RFID Readers](./rfid/README.md). +Run this once to register and configure the RFID readers with Jukebox. It can be re-run at any time to change the settings. For more information see [RFID Readers](./rfid/README.md). > [!NOTE] -> This tool will always write a new configurations file. Thus, overwrite the old one (after checking with the user). Any manual modifications to the settings will have to be re-applied +> This tool will always create a new configuration file, thereby overwriting the old one (after confirming with the user). Any manual modifications to the settings will need to be reapplied. ## Developer Tools ### RPC -**Scriptname:** [run_rpc_tool.py](../../src/jukebox/run_rpc_tool.py) +**Scriptname:** [run_rpc_tool.sh](../../tools/run_rpc_tool.sh) Command Line Interface to the Jukebox RPC Server. -A command line tool for sending RPC commands to the running jukebox app. This uses the same interface as the WebUI. Can be used for additional control or for debugging. Use `./run_rpc_tool.py` to start the tool in interactive mode. +A command-line tool for sending RPC commands to the running Jukebox app, utilizing the same interface as the Web App, provides additional control or debugging capabilities. Start the tool in interactive mode with `./run_rpc_tool.sh`. -The tool features auto-completion and command history. +Features include auto-completion and command history, with available commands fetched from the running Jukebox service. -The list of available commands is fetched from the running Jukebox service. - -The tool can also be used to send commands directly, when passing a `-c` argument, e.g. `./run_rpc_tool.py -c host.shutdown`. +For direct command execution, use the `-c` argument, e.g., `./run_rpc_tool.sh -c host.shutdown`. ### Publicity Sniffer -**Scriptname:** [run_publicity_sniffer.py](../../src/jukebox/run_publicity_sniffer.py) +**Scriptname:** [run_publicity_sniffer.sh](../../tools/run_publicity_sniffer.sh) -A command line tool that monitors all messages being sent out from the Jukebox via the publishing interface. Received messages are printed in the console. Mainly used for debugging. +This command-line tool monitors all messages sent from Jukebox through the publishing interface, printing received messages in the console. It is primarily used for debugging. diff --git a/documentation/developers/known-issues.md b/documentation/developers/known-issues.md index db3429bcc..74823a16a 100644 --- a/documentation/developers/known-issues.md +++ b/documentation/developers/known-issues.md @@ -21,6 +21,6 @@ RUN cd ${HOME} && mkdir ${ZMQ_TMP_DIR} && cd ${ZMQ_TMP_DIR}; \ ## Configuration In `jukebox.yaml` (and all other config files): -Always use relative path from settingsfile `../../`, but do not use relative paths with `~/`. +Always use relative path from folder `src/jukebox` (`../../`), but do not use relative paths with `~/`. **Sole** exception is in `playermpd.mpd_conf`. diff --git a/installation/components/setup_configure_audio.sh b/installation/components/setup_configure_audio.sh new file mode 100755 index 000000000..dc1313e1c --- /dev/null +++ b/installation/components/setup_configure_audio.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Runner script to ensure +# - correct venv activation +# - independent from working directory + +# Change working directory to project root +SOURCE=${BASH_SOURCE[0]} +SCRIPT_DIR="$(dirname "$SOURCE")" +PROJECT_ROOT="$SCRIPT_DIR"/../.. +cd "$PROJECT_ROOT" || { echo "Could not change directory"; exit 1; } + +source .venv/bin/activate || { echo "ERROR: Failed to activate virtual environment for python"; exit 1; } + +cd src/jukebox || { echo "Could not change directory"; exit 1; } +python run_configure_audio.py $@ diff --git a/installation/components/setup_rfid_reader.sh b/installation/components/setup_rfid_reader.sh new file mode 100755 index 000000000..ebabcf12b --- /dev/null +++ b/installation/components/setup_rfid_reader.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Runner script to ensure +# - correct venv activation +# - independent from working directory + +# Change working directory to project root +SOURCE=${BASH_SOURCE[0]} +SCRIPT_DIR="$(dirname "$SOURCE")" +PROJECT_ROOT="$SCRIPT_DIR"/../.. +cd "$PROJECT_ROOT" || { echo "Could not change directory"; exit 1; } + +source .venv/bin/activate || { echo "ERROR: Failed to activate virtual environment for python"; exit 1; } + +cd src/jukebox || { echo "Could not change directory"; exit 1; } +python run_register_rfid_reader.py $@ diff --git a/installation/routines/install.sh b/installation/routines/install.sh index 66a65203c..4ff3e1ac9 100644 --- a/installation/routines/install.sh +++ b/installation/routines/install.sh @@ -15,6 +15,6 @@ install() { setup_rfid_reader optimize_boot_time setup_autohotspot - setup_login_message + setup_postinstall cleanup } diff --git a/installation/routines/set_raspi_config.sh b/installation/routines/set_raspi_config.sh index 6bfa8e725..7f39a0ba5 100644 --- a/installation/routines/set_raspi_config.sh +++ b/installation/routines/set_raspi_config.sh @@ -31,7 +31,3 @@ _run_set_raspi_config() { set_raspi_config() { run_with_log_frame _run_set_raspi_config "Set default raspi-config" } - -setup_login_message() { - sudo cp -f "${INSTALLATION_PATH}/resources/system/99-rpi-jukebox-rfid-welcome" "/etc/update-motd.d/99-rpi-jukebox-rfid-welcome" -} diff --git a/installation/routines/setup_postinstall.sh b/installation/routines/setup_postinstall.sh new file mode 100644 index 000000000..f448635f4 --- /dev/null +++ b/installation/routines/setup_postinstall.sh @@ -0,0 +1,13 @@ +_setup_login_message() { + local login_message_welcome_file="/etc/update-motd.d/99-rpi-jukebox-rfid-welcome" + sudo cp -f "${INSTALLATION_PATH}/resources/system/99-rpi-jukebox-rfid-welcome" "$login_message_welcome_file" + sudo chmod +x "$login_message_welcome_file" +} + +_run_setup_postinstall() { + _setup_login_message +} + +setup_postinstall() { + run_with_log_frame _run_setup_postinstall "Post install" +} diff --git a/installation/routines/setup_rfid_reader.sh b/installation/routines/setup_rfid_reader.sh index 3003d79a4..c7f3b7120 100644 --- a/installation/routines/setup_rfid_reader.sh +++ b/installation/routines/setup_rfid_reader.sh @@ -1,7 +1,9 @@ #!/usr/bin/env bash _run_setup_rfid_reader() { - run_and_print_lc python "${INSTALLATION_PATH}/src/jukebox/run_register_rfid_reader.py" + local script="${INSTALLATION_PATH}"/installation/components/setup_rfid_reader.sh + sudo chmod +x "$script" + run_and_print_lc "$script" } setup_rfid_reader() { diff --git a/resources/default-services/jukebox-daemon.service b/resources/default-services/jukebox-daemon.service index 050897e14..7898088e2 100644 --- a/resources/default-services/jukebox-daemon.service +++ b/resources/default-services/jukebox-daemon.service @@ -10,8 +10,8 @@ After=network.target sound.target mpd.service pulseaudio.service Requires=mpd.service pulseaudio.service [Service] -WorkingDirectory=%%INSTALLATION_PATH%%/src/jukebox -ExecStart=/bin/bash -c 'source %%INSTALLATION_PATH%%/.venv/bin/activate && python run_jukebox.py' +WorkingDirectory=%%INSTALLATION_PATH%% +ExecStart=/bin/bash -c '%%INSTALLATION_PATH%%/run_jukebox.sh' StandardOutput=inherit StandardError=inherit Restart=always diff --git a/resources/default-settings/jukebox.default.yaml b/resources/default-settings/jukebox.default.yaml index 5c37f178a..c087cc024 100644 --- a/resources/default-settings/jukebox.default.yaml +++ b/resources/default-settings/jukebox.default.yaml @@ -1,5 +1,5 @@ # IMPORTANT: -# Always use relative path from settingsfile `../../`, but do not use relative paths with `~/`. +# Always use relative path from folder `src/jukebox` (`../../`), but do not use relative paths with `~/`. # Sole (!) exception is in playermpd.mpd_conf system: box_name: Jukebox diff --git a/resources/default-settings/pulseaudio.default.pa b/resources/default-settings/pulseaudio.default.pa index ee91ff9bf..e4d20ec53 100644 --- a/resources/default-settings/pulseaudio.default.pa +++ b/resources/default-settings/pulseaudio.default.pa @@ -147,5 +147,5 @@ load-module module-filter-apply #set-default-source input ### Configuration by Jukebox's Tool may come below -# Run ./run_configure_audio.py for configuration +# Run ./installation/components/setup_configure_audio.sh for configuration diff --git a/resources/system/99-rpi-jukebox-rfid-welcome b/resources/system/99-rpi-jukebox-rfid-welcome index 1b9904f96..50cc71cc7 100644 --- a/resources/system/99-rpi-jukebox-rfid-welcome +++ b/resources/system/99-rpi-jukebox-rfid-welcome @@ -1,16 +1,12 @@ #!/usr/bin/env bash echo " -######################################################### +################################################## ___ __ ______ _ __________ ____ __ _ _ / _ \/ // / __ \/ |/ / _/ __/( _ \ / \( \/ ) / ___/ _ / /_/ / // // _/ ) _ (( O )) ( /_/ /_//_/\____/_/|_/___/____/ (____/ \__/(_/\_) -future3 -If you want to run a python script from the project -activate the venv before with 'source .venv/bin/activate' -See also https://github.com/MiczFlor/RPi-Jukebox-RFID/ -blob/future3/main/documentation/developers/python.md - -#########################################################" + Welcome to your Phoniebox +################################################## +" diff --git a/run_docgeneration.sh b/run_docgeneration.sh index 22ab8bc14..4fb5f1dc9 100755 --- a/run_docgeneration.sh +++ b/run_docgeneration.sh @@ -1,12 +1,16 @@ #!/usr/bin/env bash -# Runner script for pydoc-markdown to ensure +# Runner script to ensure +# - correct venv activation # - independent from working directory -# Change working directory to location of script +# Change working directory to project root SOURCE=${BASH_SOURCE[0]} SCRIPT_DIR="$(dirname "$SOURCE")" -cd "$SCRIPT_DIR" || (echo "Could not change to top-level project directory" && exit 1) +PROJECT_ROOT="$SCRIPT_DIR" +cd "$PROJECT_ROOT" || { echo "Could not change directory"; exit 1; } + +source .venv/bin/activate || { echo "ERROR: Failed to activate virtual environment for python"; exit 1; } # Run pydoc-markdown # make sure, directory exists diff --git a/run_flake8.sh b/run_flake8.sh index a9ec73285..f6603dc0a 100755 --- a/run_flake8.sh +++ b/run_flake8.sh @@ -1,13 +1,16 @@ #!/usr/bin/env bash -# Runner script for flak8 to ensure -# - correct config file +# Runner script to ensure +# - correct venv activation # - independent from working directory -# Change working directory to location of script +# Change working directory to project root SOURCE=${BASH_SOURCE[0]} SCRIPT_DIR="$(dirname "$SOURCE")" -cd "$SCRIPT_DIR" || (echo "Could not change to top-level project directory" && exit 1) +PROJECT_ROOT="$SCRIPT_DIR" +cd "$PROJECT_ROOT" || { echo "Could not change directory"; exit 1; } + +source .venv/bin/activate || { echo "ERROR: Failed to activate virtual environment for python"; exit 1; } # Run flake8 flake8 --config .flake8 "$@" diff --git a/run_jukebox.sh b/run_jukebox.sh new file mode 100755 index 000000000..48e8aa7ba --- /dev/null +++ b/run_jukebox.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Runner script to ensure +# - correct venv activation +# - independent from working directory + +# Change working directory to project root +SOURCE=${BASH_SOURCE[0]} +SCRIPT_DIR="$(dirname "$SOURCE")" +PROJECT_ROOT="$SCRIPT_DIR" +cd "$PROJECT_ROOT" || { echo "Could not change directory"; exit 1; } + +source .venv/bin/activate || { echo "ERROR: Failed to activate virtual environment for python"; exit 1; } + +cd src/jukebox || { echo "Could not change directory"; exit 1; } +python run_jukebox.py $@ diff --git a/run_pytest.sh b/run_pytest.sh index 766f05182..c944419ae 100755 --- a/run_pytest.sh +++ b/run_pytest.sh @@ -1,13 +1,16 @@ #!/usr/bin/env bash -# Runner script for pytest to ensure -# - correct config file +# Runner script to ensure +# - correct venv activation # - independent from working directory -# Change working directory to location of script +# Change working directory to project root SOURCE=${BASH_SOURCE[0]} SCRIPT_DIR="$(dirname "$SOURCE")" -cd "$SCRIPT_DIR" || (echo "Could not change to top-level project directory" && exit 1) +PROJECT_ROOT="$SCRIPT_DIR" +cd "$PROJECT_ROOT" || { echo "Could not change directory"; exit 1; } + +source .venv/bin/activate || { echo "ERROR: Failed to activate virtual environment for python"; exit 1; } # Run pytest pytest -c pytest.ini $@ diff --git a/src/jukebox/components/volume/__init__.py b/src/jukebox/components/volume/__init__.py index 4782581ca..9dd827e4a 100644 --- a/src/jukebox/components/volume/__init__.py +++ b/src/jukebox/components/volume/__init__.py @@ -603,7 +603,7 @@ def parse_config() -> List[PulseAudioSinkClass]: logger.error(f"Configured sink '{pulse_sink_name}' not available sinks '{all_sinks}!\n" f"Using default sink '{default_sink_name}' as fallback\n" f"Things like audio sink toggle and volume limit will not work as expected!\n" - f"Please run audio config tool: ./run_configure_audio.py") + f"Please run audio config tool: ./installation/components/setup_configure_audio.sh") sink_list.append(PulseAudioSinkClass(alias, pulse_sink_name, volume_limit)) key = 'secondary' diff --git a/src/jukebox/run_configure_audio.py b/src/jukebox/run_configure_audio.py old mode 100755 new mode 100644 diff --git a/src/jukebox/run_publicity_sniffer.py b/src/jukebox/run_publicity_sniffer.py old mode 100755 new mode 100644 diff --git a/src/jukebox/run_register_rfid_reader.py b/src/jukebox/run_register_rfid_reader.py old mode 100755 new mode 100644 index 18a1614d8..91d363157 --- a/src/jukebox/run_register_rfid_reader.py +++ b/src/jukebox/run_register_rfid_reader.py @@ -33,7 +33,8 @@ def main(): # The default config file relative to this files location and independent of working directory - cfg_file_default = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + '/../../shared/settings/rfid.yaml') + script_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) + cfg_file_default = os.path.abspath(os.path.join(script_path, '../../shared/settings/rfid.yaml')) parser = argparse.ArgumentParser() parser.add_argument("-f", "--force", diff --git a/src/jukebox/run_rpc_tool.py b/src/jukebox/run_rpc_tool.py old mode 100755 new mode 100644 diff --git a/tools/run_publicity_sniffer.sh b/tools/run_publicity_sniffer.sh new file mode 100755 index 000000000..2ea47b48b --- /dev/null +++ b/tools/run_publicity_sniffer.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Runner script to ensure +# - correct venv activation +# - independent from working directory + +# Change working directory to project root +SOURCE=${BASH_SOURCE[0]} +SCRIPT_DIR="$(dirname "$SOURCE")" +PROJECT_ROOT="$SCRIPT_DIR"/.. +cd "$PROJECT_ROOT" || { echo "Could not change directory"; exit 1; } + +source .venv/bin/activate || { echo "ERROR: Failed to activate virtual environment for python"; exit 1; } + +cd src/jukebox || { echo "Could not change directory"; exit 1; } +python run_publicity_sniffer.py $@ diff --git a/tools/run_rpc_tool.sh b/tools/run_rpc_tool.sh new file mode 100755 index 000000000..dad895c56 --- /dev/null +++ b/tools/run_rpc_tool.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# Runner script to ensure +# - correct venv activation +# - independent from working directory + +# Change working directory to project root +SOURCE=${BASH_SOURCE[0]} +SCRIPT_DIR="$(dirname "$SOURCE")" +PROJECT_ROOT="$SCRIPT_DIR"/.. +cd "$PROJECT_ROOT" || { echo "Could not change directory"; exit 1; } + +source .venv/bin/activate || { echo "ERROR: Failed to activate virtual environment for python"; exit 1; } + +cd src/jukebox || { echo "Could not change directory"; exit 1; } +python run_rpc_tool.py $@