diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 7b60f2c04..6cb871112 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -15,7 +15,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + python-version: ['3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test_docker_debian.yml b/.github/workflows/test_docker_debian.yml index 7c929ae76..c7202e705 100644 --- a/.github/workflows/test_docker_debian.yml +++ b/.github/workflows/test_docker_debian.yml @@ -69,18 +69,3 @@ jobs: # with: # debian_codename: 'bullseye' # platform: linux/arm/v6 - - run_buster_armv7: - name: 'buster armv7' - uses: ./.github/workflows/test_docker_debian_codename_sub.yml - with: - debian_codename: 'buster' - platform: linux/arm/v7 - - # # can be activate on test branches, currently failing - # run_buster_armv6: - # name: 'buster armv6' - # uses: ./.github/workflows/test_docker_debian_codename_sub.yml - # with: - # debian_codename: 'buster' - # platform: linux/arm/v6 diff --git a/.github/workflows/test_docker_debian_codename_sub.yml b/.github/workflows/test_docker_debian_codename_sub.yml index c41a880d4..00ef4efd7 100644 --- a/.github/workflows/test_docker_debian_codename_sub.yml +++ b/.github/workflows/test_docker_debian_codename_sub.yml @@ -58,7 +58,7 @@ jobs: uses: docker/setup-qemu-action@v3.0.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.1.0 + uses: docker/setup-buildx-action@v3.2.0 with: # network=host driver-opt needed to push to local registry driver-opts: network=host @@ -155,7 +155,7 @@ jobs: uses: docker/setup-qemu-action@v3.0.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.1.0 + uses: docker/setup-buildx-action@v3.2.0 - name: Artifact Download Docker Image uses: actions/download-artifact@v4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6ac2d37c6..44b4ff13b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -91,7 +91,7 @@ If the code change results in a test failure, we will make our best effort to co ### Guidelines -* The oldest supported Raspberry Pi OS version is currently **Buster**. Therefore all Python code should work with **Python 3.7**. +* All code has to run under the stable and legacy version of Raspberry Pi OS (please check if currently even an older version is still supported). * For GPIO all code should work with **RPi.GPIO**. gpiozero is currently not intended to use. ### Additional Resources diff --git a/README.md b/README.md index c514a2436..ebaada654 100644 --- a/README.md +++ b/README.md @@ -15,16 +15,6 @@ Phoniebox is a contactless jukebox for the Raspberry Pi, playing audio files, playlists, podcasts, web streams and spotify triggered by RFID cards. All plug and play via USB, no soldering iron needed. It also features GPIO buttons control support. -## Important Notice regarding Spotify Integration - -**Spotify has [disabled access to libspotify on May 16, 2022](https://developer.spotify.com/community/news/2022/04/12/libspotify-sunset/).** - -This means **Spotify in Phoniebox doesn't work at the moment**. For further information see [Spotify FAQ](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/Spotify-FAQ) - -We are working to provide an integrated solution. -For Version 2 there is a possible fix to reactivate spotify with a manual installation described [here](https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/1815#issuecomment-1666535983). -For Version 3 [#2164](https://github.com/MiczFlor/RPi-Jukebox-RFID/pull/2164) is laying the groundwork. Help is greatly appreciated. - ## The new Phoniebox Calendar is here Another bunch of wonderful designs! @@ -80,11 +70,11 @@ Check out the following references. * [**RFID** control](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/MANUAL#cardcontrol) for playout and controlling your Phoniebox (e.g. set [maximum volume with RFID](https://github.com/MiczFlor/RPi-Jukebox-RFID/pull/633) cards). * Support for various RFID readers, e.g. * USB - * [RC422](components/rfid-reader/RC522/README.md) + * [RC522](components/rfid-reader/RC522/README.md) * [PN532](components/rfid-reader/PN532/README.md) * PC/SC * also [multiple readers](https://github.com/MiczFlor/RPi-Jukebox-RFID/pull/1012#issue-434052529) simultaneously -* [**GPIO** control](components/gpio_control/README.md) for [buttons](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/Using-GPIO-hardware-buttons), [knobs / dials](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/Audio-RotaryKnobVolume) and much more to control your Phoniebox via GPIO. +* [**GPIO** control](components/gpio_control/README.md) for [buttons](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/Using-GPIO-hardware-buttons) and much more to control your Phoniebox via GPIO. * Control via smooth [**Web App**](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/MANUAL#webapp) running on ajax from your phone, tablet or PC. You can play, upload, move files, assign new RFID cards, control playout, settings, etc. * Support for files with embedded chapters metadata (like m4a) * Customizable poweroff command diff --git a/components/audio/PirateAudioHAT/setup_pirateAudioHAT.sh b/components/audio/PirateAudioHAT/setup_pirateAudioHAT.sh index 97c91194b..2fc977443 100755 --- a/components/audio/PirateAudioHAT/setup_pirateAudioHAT.sh +++ b/components/audio/PirateAudioHAT/setup_pirateAudioHAT.sh @@ -7,11 +7,10 @@ source "${JUKEBOX_HOME_DIR}"/scripts/helperscripts/inc.systemHelper.sh question() { local question=$1 - read -p "${question} (y/n)? " choice + read -p "${question} (Y/n)? " choice case "$choice" in - y|Y ) ;; - n|N ) exit 0;; - * ) echo "Error: invalid" ; question ${question};; + [nN][oO]|[nN]) exit 0;; + * ) ;; esac } diff --git a/components/bluetooth-sink-switch/README.md b/components/bluetooth-sink-switch/README.md index 572bde2a1..a0e170f8d 100644 --- a/components/bluetooth-sink-switch/README.md +++ b/components/bluetooth-sink-switch/README.md @@ -16,7 +16,7 @@ If no bluetooth device is connected, the output defaults back to speakers. After ### Limitations -This feature only works for the *Classic* Edition. Why? It relies on the mpd multiple output channels feature to switch between outputs. This is no available in mopidy, which is used in the Spotify Edition. +This feature only works for the *Classic* Edition. Why? It relies on the mpd multiple output channels feature to switch between outputs. This is not available in mopidy, which is used in the Spotify Edition. ## Installation diff --git a/components/controls/buttons_usb_encoder/setup-buttons-usb-encoder.sh b/components/controls/buttons_usb_encoder/setup-buttons-usb-encoder.sh index 95db0199c..0fa5fadc0 100755 --- a/components/controls/buttons_usb_encoder/setup-buttons-usb-encoder.sh +++ b/components/controls/buttons_usb_encoder/setup-buttons-usb-encoder.sh @@ -6,11 +6,10 @@ BUTTONS_USB_ENCODER_DIR="${JUKEBOX_HOME_DIR}/components/controls/buttons_usb_enc question() { local question=$1 - read -p "${question} (y/n)? " choice + read -p "${question} (Y/n)? " choice case "$choice" in - y|Y ) ;; - n|N ) exit 0;; - * ) echo "Error: invalid" ; question ${question};; + [nN][oO]|[nN]) exit 0;; + * ) ;; esac } diff --git a/components/gpio_control/README.md b/components/gpio_control/README.md index 8661e8d27..bae060400 100644 --- a/components/gpio_control/README.md +++ b/components/gpio_control/README.md @@ -24,20 +24,18 @@ Up to now the following input devices are implemented: * **ShutdownButton**: A specialized implementation for a shutdown button with integrated (but optional) LED support. It initializes a shutdown if the button is pressed more than `time_pressed` seconds and a (optional) LED on GPIO `led_pin` is flashing until that time is reached. For additional information, see [extended documentation below](#shutdownbutton). -* **RotaryEncoder**: - Control of a rotary encoder, for example KY040, see also in [Wiki](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/Audio-RotaryKnobVolume). - It can be configured using `pinUp` and `PiNDown` (use GPIO numbers here), `functionCallUp`, `functionCallDown`, and `timeBase` see [extended documentation below](#rotaryencoder). - * **TwoButtonControl**: This Device uses two Buttons and implements a third action if both buttons are pressed together. See [extended documentation below](#twobuttoncontrol). +* **RotaryEncoder**: + Control of a rotary encoder, for example KY040. + It can be configured using `Pin1` and `Pin2` (use GPIO numbers here), `functionCall1`, `functionCall2` see [extended documentation below](#rotaryencoder). + * **StatusLED**: A LED which will light up once the Phoniebox has fully booted up and is ready to be used. For additional information, see [extended documentation below](#statusled). Each section needs to be activated by setting `enabled: True`. -Many example files are located in `~/RPi-Jukebox-RFID/components/gpio_control/example_configs/`. - ## Extended documentation This section provides some extended documentation and guideline. Especially some exemplary configurations are introduced showing how these controls can be set up in the configuration file `~/RPi-Jukebox-RFID/settings/gpio_settings.ini`. @@ -172,19 +170,75 @@ Furthermore, the following settings can be used as described for the [regular bu A RotaryEncoder can be created using an `ini` entry like this: ```bash -[VolumeControl] +[RotaryVolumeControl] enabled: True Type: RotaryEncoder -Pin1: 7 -Pin2: 8 -timeBase: 0.02 +Pin1: 22 +Pin2: 23 +timeBase: 0.1 functionCall1: functionCallVolU functionCall2: functionCallVolD ``` -Pin1 and FunctionCall1 correspond to rotary direction "up", while Pin2 and FunctionCall2 correspond to "down". +* **enabled**: This needs to be `True` for the rotary encoder to work. +* **Pin1**: GPIO number corresponding to rotary direction "clockwise" ('CLK') +* **Pin2**: GPIO number corresponding to rotary direction "counter clockwise" ('DT') +* **functionCall1**: function called for every rotation step corresponding to rotary direction "clockwise". See below for passed arguments. See [function documentation below](#functions). +* **functionCall2**: function called for every rotation step corresponding to rotary direction "counter clockwise". See below for passed arguments. See [function documentation below](#functions). +* **timeBase**: Factor used for calculating the rotation value base on rotation speed, defaults to `0.1`. Use `0` for deactivating rotation speed influence. +Example: + * a single rotation step leads to the value 1 passed to the function. + * steady rotation of two to or more steps, leads to the value 1 for the first call and the value 2 for all further calls. + * speeding up rotation of two to or more steps, leads to the value 1 for the first call, the value 2 for the second, the value 3 for the third and so on. +* **functionCall1Args**: Arguments for `functionCall1`, defaults to `None`. If defined takes precedence over rotation value. Arguments are ignored, if `functionCall1` does not take any. +* **functionCall2Args**: Arguments for `functionCall2`, defaults to `None`. If defined takes precedence over rotation value. Arguments are ignored, if `functionCall1` does not take any. + +To also use the push button of the encoder just a button definition: +```bash +[Mute] +enabled: True +Type: Button +Pin: 27 +functionCall: functionCallVol0 +``` + Note that the old configuration entries PinUp/PinDown and functionCallUp/functionCallDown are deprecated and might stop working in future. + +```bash +[RotarySeekingControl] +enabled: True +Type: RotaryEncoder +Pin1: 22 +Pin2: 23 +timeBase: 0.1 +functionCall1: functionCallPlayerSeekFwd +functionCall1Args: 5 +functionCall2: functionCallPlayerSeekBack +functionCall2Args: 5 +``` + +In this example, the encoder will be used to seek for- and backwards by 5 seconds on every rotation step. The rotation value will **NOT** be used in this case as the function args are defined! + + +#### Circuit diagram +```text + .---------------. .---------------. + | | | | + | CLK |----------------------| GPIO 22 | + | | | | + | DT |----------------------| GPIO 23 | + | | | | + | SW |----------------------| GPIO 27 | + | | | | + | + |----------------------| 3.3V | + | | | | + | GND |----------------------| GND | + | | | | + '---------------' '---------------' + KY-040 Raspberry +``` + ### StatusLED A StatusLED can be created using an `ini` entry like this: diff --git a/components/gpio_control/example_configs/gpio_setting_rotary_vol_prevnext.ini b/components/gpio_control/example_configs/gpio_setting_rotary_vol_prevnext.ini deleted file mode 100755 index 3e829d55e..000000000 --- a/components/gpio_control/example_configs/gpio_setting_rotary_vol_prevnext.ini +++ /dev/null @@ -1,36 +0,0 @@ -[DEFAULT] -enabled: True - -[VolumeControl] -enabled: True -Type: RotaryEncoder -PinUp: 7 -PinDown: 8 -timeBase: 0.02 -functionCallDown: functionCallVolD -functionCallUp: functionCallVolU - -[PrevNextControl] -enabled: True -Type: RotaryEncoder -PinUp: 16 -PinDown: 20 -timeBase: 0.02 -functionCallDown: functionCallPlayerPrev -functionCallUp: functionCallPlayerNext - -[Shutdown] -enabled: True -Type: Button -Pin: 17 -pull_up_down: pull_down -edge: raising -functionCall: functionCallShutdown - -[PlayPause] -enabled: True -Type: Button -Pin: 25 -pull_up_down: pull_up -edge: falling -functionCall: functionCallPlayerPause diff --git a/components/gpio_control/example_configs/gpio_settings.ini b/components/gpio_control/example_configs/gpio_settings.ini index 4f84ba01b..a386d6ec6 100755 --- a/components/gpio_control/example_configs/gpio_settings.ini +++ b/components/gpio_control/example_configs/gpio_settings.ini @@ -4,20 +4,28 @@ antibouncehack: False [VolumeControl] enabled: False -Type: TwoButtonControl ;or RotaryEncoder +Type: TwoButtonControl Pin1: 5 Pin2: 6 pull_up_down: pull_up hold_time: 0.3 hold_mode: Repeat -timeBase: 0.1 ;only for RotaryEncoder functionCall1: functionCallVolU functionCall2: functionCallVolD -functionCallTwoButtons: functionCallVol0 ;only for TwoButtonControl +functionCallTwoButtons: functionCallVol0 ;functionCall1Args: 1 ;functionCall2Args: 1 ;functionCallTwoButtonsArgs: x +[RotaryVolumeControl] +enabled: False +Type: RotaryEncoder +Pin1: 22 +Pin2: 23 +timeBase: 0.1 +functionCall1: functionCallVolU +functionCall2: functionCallVolD + [PrevNextControl] enabled: False Type: TwoButtonControl @@ -143,3 +151,7 @@ pull_up_down: pull_up functionCall: functionCallTriggerPlayFolder functionCallArgs: someRelativeFolderName +[StatusLED] +enabled: False +Type: StatusLED +Pin: 14 diff --git a/components/gpio_control/example_configs/gpio_settings_rotary_and_led.ini b/components/gpio_control/example_configs/gpio_settings_rotary_and_led.ini deleted file mode 100644 index f636adbcf..000000000 --- a/components/gpio_control/example_configs/gpio_settings_rotary_and_led.ini +++ /dev/null @@ -1,49 +0,0 @@ -[DEFAULT] -enabled: True - -[VolumeControl] -enabled: True -Type: RotaryEncoder -PinUp: 17 -PinDown: 22 -pull_up_down: pull_up -timeBase: 0.2 -; only for rotary encoder -functionCallDown: functionCallVolD -functionCallUp: functionCallVolU -functionCallTwoButtons: functionCallStop -; only for TwoButtonControl -functionCallButton: functionCallPlayerPause -; only for RotaryEncoderClickable - -[PrevNextControl] -enabled: True -Type: TwoButtonControl -Pin1: 6 -Pin2: 12 -functionCall1: functionCallPlayerPrev -functionCall2: functionCallPlayerNext -functionCallTwoButtons: functionCallPlayerStop -pull_up_down: pull_up -hold_time: 0.3 -hold_mode: None - - -[Shutdown] -enabled: False -Type: Button -Pin: 3 -functionCall: functionCallShutdown - - -[PlayPause] -enabled: True -Type: Button -Pin: 27 -pull_up_down: pull_up -functionCall: functionCallPlayerPause - -[StatusLED] -enabled: True -Type: MPDStatusLED -Pin: 16 diff --git a/components/gpio_control/example_configs/gpio_settings_status_led.ini b/components/gpio_control/example_configs/gpio_settings_status_led.ini deleted file mode 100644 index 68e6461b2..000000000 --- a/components/gpio_control/example_configs/gpio_settings_status_led.ini +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -enabled: True - -[StatusLED] -enabled: True -Type: StatusLED -Pin: 14 diff --git a/components/gpio_control/function_calls.py b/components/gpio_control/function_calls.py index e293282c0..c3eda5913 100644 --- a/components/gpio_control/function_calls.py +++ b/components/gpio_control/function_calls.py @@ -18,7 +18,7 @@ def __init__(self): def functionCallShutdown(self, *args): function_call("{command} -c=shutdown".format(command=self.playout_control), shell=True) - def functionCallVolU(self, steps=None): + def functionCallVolU(self, steps=None, *args): if steps is None: function_call("{command} -c=volumeup".format(command=self.playout_control), shell=True) else: @@ -26,7 +26,7 @@ def functionCallVolU(self, steps=None): command=self.playout_control), shell=True) - def functionCallVolD(self, steps=None): + def functionCallVolD(self, steps=None, *args): if steps is None: function_call("{command} -c=volumedown".format(command=self.playout_control), shell=True) else: @@ -65,22 +65,22 @@ def functionCallPlayerStop(self, *args): function_call("{command} -c=playerstop".format(command=self.playout_control), shell=True) - def functionCallPlayerSeekFwd(self, seconds=None): + def functionCallPlayerSeekFwd(self, seconds=None, *args): if seconds is None: seconds = 10 function_call("{command} -c=playerseek -v=+{value}".format(command=self.playout_control, value=seconds), shell=True) - def functionCallPlayerSeekBack(self, seconds=None): + def functionCallPlayerSeekBack(self, seconds=None, *args): if seconds is None: seconds = 10 function_call("{command} -c=playerseek -v=-{value}".format(command=self.playout_control, value=seconds), shell=True) - def functionCallPlayerSeekFarFwd(self, seconds=None): + def functionCallPlayerSeekFarFwd(self, seconds=None, *args): if seconds is None: seconds = 60 function_call("{command} -c=playerseek -v=+{value}".format(command=self.playout_control, value=seconds), shell=True) - def functionCallPlayerSeekFarBack(self, seconds=None): + def functionCallPlayerSeekFarBack(self, seconds=None, *args): if seconds is None: seconds = 60 function_call("{command} -c=playerseek -v=-{value}".format(command=self.playout_control, value=seconds), shell=True) @@ -94,15 +94,15 @@ def functionCallPlayerRandomCard(self, *args): def functionCallPlayerRandomFolder(self, *args): function_call("{command} -c=randomfolder".format(command=self.playout_control), shell=True) - def functionCallBluetoothToggle(self, mode=None): + def functionCallBluetoothToggle(self, mode=None, *args): if mode is None: mode = 'toggle' function_call("{command} -c=bluetoothtoggle -v={value}".format(command=self.playout_control, value=mode), shell=True) - def functionCallTriggerPlayCardId(self, cardid): + def functionCallTriggerPlayCardId(self, cardid, *args): function_call("{command} --cardid={value}".format(command=self.rfid_trigger, value = cardid), shell=True) - def functionCallTriggerPlayFolder(self, folder): + def functionCallTriggerPlayFolder(self, folder, *args): function_call("{command} --dir={value}".format(command=self.rfid_trigger, value = folder), shell=True) def getFunctionCall(self, functionName): diff --git a/components/gpio_control/gpio_control.py b/components/gpio_control/gpio_control.py index 45977b89b..3e91df31b 100755 --- a/components/gpio_control/gpio_control.py +++ b/components/gpio_control/gpio_control.py @@ -32,7 +32,10 @@ def getFunctionCall(self, function_name, function_args): try: if function_name is not None and function_name != 'None': functionCall = getattr(self.function_calls, function_name) - return (lambda *args: functionCall(*args, function_args)) + if function_args is not None and function_args != 'None': + return (lambda *args: functionCall(function_args, *args)) + else: + return (lambda *args: functionCall(*args)) except AttributeError: self.logger.error('Could not find FunctionCall {function_name}'.format(function_name=function_name)) return lambda *args: None @@ -77,8 +80,8 @@ def generate_device(self, config, deviceName): elif device_type == 'RotaryEncoder': return RotaryEncoder(config.getint('Pin1'), config.getint('Pin2'), - self.getFunctionCall(config.get('functionCall1'), None), - self.getFunctionCall(config.get('functionCall2'), None), + self.getFunctionCall(config.get('functionCall1'), config.get('functionCall1Args', fallback=None)), + self.getFunctionCall(config.get('functionCall2'), config.get('functionCall2Args', fallback=None)), config.getfloat('timeBase', fallback=0.1), name=deviceName) elif device_type == 'ShutdownButton': diff --git a/components/gpio_control/test/test_gpio_control.py b/components/gpio_control/test/test_gpio_control.py index 4c139b67e..26d6885fa 100644 --- a/components/gpio_control/test/test_gpio_control.py +++ b/components/gpio_control/test/test_gpio_control.py @@ -16,11 +16,11 @@ def gpio_control_class(): class MockFunctionCalls: - def funcTestWithoutParameter(self, *args): - return "funcTestWithoutParameter" + def funcTestWithoutParameter(*args): + return "funcTestWithoutParameter()" - def funcTestWithParameter(self, param1): - return f"funcTestWithParameter({param1})" + def funcTestWithParameter(param1, *args): + return f"funcTestWithParameter({str(param1)})" _gpio_control_class = GPIOControl(MockFunctionCalls) # function_calls will be mocked return _gpio_control_class @@ -226,19 +226,44 @@ def test_generateDevice_TwoButtonControl(self, gpio_control_class): def test_getFunctionCall_None_None(self, gpio_control_class): result = gpio_control_class.getFunctionCall(None, None) - assert result(()) is None + assert result() is None result = gpio_control_class.getFunctionCall('None', None) - assert result(()) is None + assert result() is None result = gpio_control_class.getFunctionCall("nonExisting", None) - assert result(()) is None + assert result() is None - def test_getFunctionCall_withoutParam(self, gpio_control_class): + def test_getFunctionCall_funcWithoutArgs(self, gpio_control_class): result = gpio_control_class.getFunctionCall("funcTestWithoutParameter", None) - assert result(()) == "funcTestWithoutParameter" + assert result() == "funcTestWithoutParameter()" - def test_getFunctionCall_withParam(self, gpio_control_class): - result = gpio_control_class.getFunctionCall("funcTestWithParameter", "param1") - assert result(()) == "funcTestWithParameter(param1)" + def test_getFunctionCall_funcWithoutArgs_withParam(self, gpio_control_class): + result = gpio_control_class.getFunctionCall("funcTestWithoutParameter", None) + assert result("param") == "funcTestWithoutParameter()" + + def test_getFunctionCall_funcWithoutArgs_withFuncArgs(self, gpio_control_class): + result = gpio_control_class.getFunctionCall("funcTestWithoutParameter", "funcArgs") + assert result() == "funcTestWithoutParameter()" + + def test_getFunctionCallfuncWithoutArgs_withFuncArgsAndParam(self, gpio_control_class): + result = gpio_control_class.getFunctionCall("funcTestWithoutParameter", "funcArgs") + assert result("param") == "funcTestWithoutParameter()" + + def test_getFunctionCall_funcWithArgs_withoutFuncArgsAndParam(self, gpio_control_class): + result = gpio_control_class.getFunctionCall("funcTestWithParameter", None) + with pytest.raises(TypeError): + result() + + def test_getFunctionCall_funcWithArgs_withParam(self, gpio_control_class): + result = gpio_control_class.getFunctionCall("funcTestWithParameter", None) + assert result("param") == "funcTestWithParameter(param)" + + def test_getFunctionCall_funcWithArgs_withFuncArgs(self, gpio_control_class): + result = gpio_control_class.getFunctionCall("funcTestWithParameter", "funcArgs") + assert result() == "funcTestWithParameter(funcArgs)" + + def test_getFunctionCall_funcWithArgs_withFuncArgsAndParam(self, gpio_control_class): + result = gpio_control_class.getFunctionCall("funcTestWithParameter", "funcArgs") + assert result("param") == "funcTestWithParameter(funcArgs)" # --------------- diff --git a/components/rfid-reader/PN532/setup_pn532.sh b/components/rfid-reader/PN532/setup_pn532.sh index 3b9ab1252..8f2e97bbb 100755 --- a/components/rfid-reader/PN532/setup_pn532.sh +++ b/components/rfid-reader/PN532/setup_pn532.sh @@ -5,11 +5,10 @@ JUKEBOX_HOME_DIR="${HOME_DIR}/RPi-Jukebox-RFID" question() { local question=$1 - read -p "${question} (y/n)? " choice + read -p "${question} (Y/n)? " choice case "$choice" in - y|Y ) ;; - n|N ) exit 0;; - * ) echo "Error: invalid" ; question ${question};; + [nN][oO]|[nN]) exit 0;; + * ) ;; esac } diff --git a/components/rfid-reader/RC522/setup_rc522.sh b/components/rfid-reader/RC522/setup_rc522.sh index 43ab60fa6..b6333767b 100644 --- a/components/rfid-reader/RC522/setup_rc522.sh +++ b/components/rfid-reader/RC522/setup_rc522.sh @@ -5,11 +5,10 @@ JUKEBOX_HOME_DIR="${HOME_DIR}/RPi-Jukebox-RFID" question() { local question=$1 - read -p "${question} (y/n)? " choice + read -p "${question} (Y/n)? " choice case "$choice" in - y|Y ) ;; - n|N ) exit 0;; - * ) echo "Error: invalid" ; question ${question};; + [nN][oO]|[nN]) exit 0;; + * ) ;; esac } diff --git a/components/smart-home-automation/MQTT-protocol/README.md b/components/smart-home-automation/MQTT-protocol/README.md index 69267656b..03c0d0696 100644 --- a/components/smart-home-automation/MQTT-protocol/README.md +++ b/components/smart-home-automation/MQTT-protocol/README.md @@ -144,7 +144,7 @@ components/smart-home-automation/MQTT-protocol/ ## Auto-Starting the daemon at bootup * The daemon is run by executing the script `daemon_mqtt_client.py` which will run in an endless loop. -* There's a sample service file (`phoniebox-mqtt-client.service.stretch-default.sample`) that can be used to register the daemon to be run at bootup. +* There's a sample service file (`phoniebox-mqtt-client.service-default.sample`) that can be used to register the daemon to be run at bootup. * It is currently not integrated into the one-line-install script so please run the following commands to do it manually. First step: copy files to destination locations: @@ -152,7 +152,7 @@ First step: copy files to destination locations: ~~~bash # First copy the daemon script and service config file to the correct directory: sudo cp /home/pi/RPi-Jukebox-RFID/components/smart-home-automation/MQTT-protocol/daemon_mqtt_client.py /home/pi/RPi-Jukebox-RFID/scripts/ -sudo cp /home/pi/RPi-Jukebox-RFID/components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service.stretch-default.sample /etc/systemd/system/phoniebox-mqtt-client.service +sudo cp /home/pi/RPi-Jukebox-RFID/components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service-default.sample /etc/systemd/system/phoniebox-mqtt-client.service # make sure the file exists touch /home/pi/RPi-Jukebox-RFID/settings/Latest_RFID ~~~ diff --git a/components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service.stretch-default.sample b/components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service-default.sample similarity index 100% rename from components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service.stretch-default.sample rename to components/smart-home-automation/MQTT-protocol/phoniebox-mqtt-client.service-default.sample diff --git a/htdocs/inc.processCheckCardEditRegister.php b/htdocs/inc.processCheckCardEditRegister.php index 5ae713aee..7910cc164 100755 --- a/htdocs/inc.processCheckCardEditRegister.php +++ b/htdocs/inc.processCheckCardEditRegister.php @@ -109,8 +109,8 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { $messageSuccess = ""; if($post['delete'] == "delete") { - $messageAction .= "
The card with the ID '".$post['cardID']." has been deleted. - If you made a mistake, this is your chance to press 'Submit' to restore the card settings. + $messageAction .= "
The card with the ID '".$post['cardID']." has been deleted. + If you made a mistake, this is your chance to press 'Submit' to restore the card settings. Else: Go Home.
"; // remove $fileshortcuts to cardID file in shortcuts $exec = "rm ".$fileshortcuts; @@ -118,18 +118,18 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { print "deleting shortcut:\n"; print $exec; print ""; - } + } exec($exec); } elseif($post['submit'] == "submit") { /* * error check */ - + // posted too little? if( - (!isset($post['streamURL']) || !isset($post['streamType'])) - && !isset($post['audiofolder']) - && !isset($post['YTstreamURL']) + (!isset($post['streamURL']) || !isset($post['streamType'])) + && !isset($post['audiofolder']) + && !isset($post['YTstreamURL']) && !isset($post['TriggerCommand']) ) { $messageError .= $lang['cardRegisterErrorStreamOrAudio']." (error 002)"; @@ -161,9 +161,9 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { } // streamFolderName not given - if( - (isset($post['streamURL']) || isset($post['YTstreamURL'])) - && !isset($post['audiofolder']) + if( + (isset($post['streamURL']) || isset($post['YTstreamURL'])) + && !isset($post['audiofolder']) && !isset($post['audiofolderNew']) ) { $messageError .= $lang['cardRegisterErrorSuggestFolder']." (error 006)"; @@ -172,7 +172,7 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { } //wrong spotify url, convert to mopidy format - if((isset($post['streamURL']) && $post['streamType'] == "spotify") && (strpos($post['streamURL'], "https://open.spotify.com/") !== false)){ + if((isset($post['streamURL']) && $post['streamType'] == "spotify") && (strpos($post['streamURL'], "https://open.spotify.com/") !== false)){ $patterns = array(); $patterns[0] = '/https\:\/\/open.spotify.com/'; $patterns[1] = '/\/(playlist|album|track|artist)\//'; @@ -200,7 +200,7 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { * Stream URL to be created */ // 20200512 included code from removed the old include('inc.processAddNewStream.php'); - + // create new folder $streamfolder = $Audio_Folders_Path."/".$post['audiofolderNew']."/"; $exec = "mkdir -p '".$streamfolder."'"; @@ -208,7 +208,7 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { // New folder is created so we link a RFID to it. Write $post['audiofolderNew'] to cardID file in shortcuts $exec = "rm ".$fileshortcuts."; echo '".$post['audiofolderNew']."' > ".$fileshortcuts."; chmod 777 ".$fileshortcuts; exec($exec); - + // figure out $streamfile depending on $post['streamType'] switch($post['streamType']) { case "spotify": @@ -223,7 +223,7 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { default: $streamfile = "url.txt"; } - + // write $post['streamURL'] to $streamfile and make accessible to anyone $exec = "echo '".$post['streamURL']."' > '".$streamfolder."/".$streamfile."'; sudo chmod -R 777 '".$streamfolder."'"; exec($exec); @@ -235,15 +235,15 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { * RFID triggers system commands */ // 20200512 included code from removed the old include('inc.processAddTriggerCommand.php'); - + // Replace the potential existing RFID value with the posted one //print $post['cardID']."->".$post['TriggerCommand']; $fillRfidArrAvailWithUsed[$post['TriggerCommand']] = $post['cardID']; - + /****************************************** * Create new conf file based on posted values */ - + // copy sample file to conf file exec("cp ../settings/rfid_trigger_play.conf.sample ../settings/rfid_trigger_play.conf; chmod 777 ../settings/rfid_trigger_play.conf"); // replace posted values in new conf file @@ -255,13 +255,13 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { } // success message $messageSuccess = $lang['cardRegisterTriggerSuccess']." ".$post['TriggerCommand']; - } + } elseif(isset($post['YTstreamURL'])) { /******************************************************* * YouTube Download */ // 20200512 included code from removed the old include('inc.processAddYT.php'); - + if(isset($post['audiofolderNew'])) { // create new folder $exec = "mkdir --parents '".$Audio_Folders_Path."/".$post['audiofolderNew']."'; chmod 777 '".$Audio_Folders_Path."/".$post['audiofolderNew']."'"; @@ -278,11 +278,12 @@ function fillRfidArrAvailWithUsed($rfidAvailArr, $rfidUsedArr=array()) { // link to existing audiofolder $foldername = $Audio_Folders_Path."/".$post['audiofolder']; } - $exec = "cd '".$foldername."'; youtube-dl -f bestaudio --extract-audio --audio-format mp3 ".$post['YTstreamURL']." > ".$conf['shared_abs']."/youtube-dl.log; chmod 777 ".$foldername."/* 2>&1 &"; - exec($exec); + $exec = "cd '".$foldername."'; yt-dlp --compat-options youtube-dl -f bestaudio --extract-audio --audio-format mp3 '".$post['YTstreamURL']."' >> ".$conf['shared_abs']."/youtube-download.log 2>&1; chmod 777 ".$foldername."/*;"; + # Run command in background! + exec("{ ".$exec." } > /dev/null &"); // success message $messageSuccess = $lang['cardRegisterDownloadingYT']; - } + } elseif(isset($post['audiofolder']) && trim($post['audiofolder']) != "false") { /******************************************************* * connect card with existing audio folder diff --git a/htdocs/lang/lang-de-DE.php b/htdocs/lang/lang-de-DE.php index 95d50d02d..31f1d4b8b 100644 --- a/htdocs/lang/lang-de-DE.php +++ b/htdocs/lang/lang-de-DE.php @@ -129,7 +129,7 @@ $lang['cardRegisterErrorConvertSpotifyURL'] = "Falsche Spotify URL, konvertiert in korrektes Format"; $lang['cardRegisterStream2Card'] = "Stream ist mit der Karten-ID verknüpft."; $lang['cardRegisterFolder2Card'] = "Audio-Ordner ist nun mit der Karten-ID verknüpft."; -$lang['cardRegisterDownloadingYT'] = "
YouTube Audio wird heruntergeladen. Dies kann einige Minuten dauern. Du kannst die Logdatei \"youtube-dl.log\" im Ordner \"shared\" ansehen.
"; +$lang['cardRegisterDownloadingYT'] = "YouTube Audio wird heruntergeladen. Dies kann einige Minuten dauern. Du kannst die Logdatei \"youtube-download.log\" im Ordner \"shared\" ansehen.
"; $lang['cardRegisterSwipeUpdates'] = "Dies wird automatisch aktualisiert, wenn du eine RFID-Karte ausliest."; $lang['cardRegisterManualLinks'] = "Du kannst Karten auch manuell mit Ordnern verbinden. Das Handbuch erklärt, wie man sich mit der Phoniebox verbindet und Karten registriert.
"; $lang['cardRegisterTriggerSuccess'] = "Die Karte ist jetzt verknüpft um die Funktion auszuführen:"; diff --git a/htdocs/lang/lang-en-UK.php b/htdocs/lang/lang-en-UK.php index 5b68fc9e3..7e8ec706e 100755 --- a/htdocs/lang/lang-en-UK.php +++ b/htdocs/lang/lang-en-UK.php @@ -130,7 +130,7 @@ $lang['cardRegisterErrorConvertSpotifyURL'] = "Wrong spotify url, converted to the correct format"; $lang['cardRegisterStream2Card'] = "Stream is linked to Card ID."; $lang['cardRegisterFolder2Card'] = "Audio folder is now linked to Card."; -$lang['cardRegisterDownloadingYT'] = "YouTube audio is downloading. This may take a couple of minutes. You may check the logfile \"youtube-dl.log\" in the shared folder.
"; +$lang['cardRegisterDownloadingYT'] = "YouTube audio is downloading. This may take a couple of minutes. You may check the logfile \"youtube-download.log\" in the shared folder.
"; $lang['cardRegisterSwipeUpdates'] = "This will automatically update as you swipe a RFID card."; $lang['cardRegisterManualLinks'] = "You can also connect cards to folders manually. The manual explains how to connect to the phoniebox and register cards.
"; $lang['cardRegisterTriggerSuccess'] = "The card is now linked to trigger the command:"; diff --git a/htdocs/lang/lang-fr-FR.php b/htdocs/lang/lang-fr-FR.php index 352846b37..34dadf421 100755 --- a/htdocs/lang/lang-fr-FR.php +++ b/htdocs/lang/lang-fr-FR.php @@ -130,7 +130,7 @@ $lang['cardRegisterErrorConvertSpotifyURL'] = "URL Spotify incorrecte, elle a été convertie au bon format"; $lang['cardRegisterStream2Card'] = "Le stream est lié à la carte."; $lang['cardRegisterFolder2Card'] = "Le dossier audio est désormais lié à une carte."; -$lang['cardRegisterDownloadingYT'] = "Piste YouTube en cours de téléchargement. Cela peut prendre plusieurs minutes. Log dans le fichier \"youtube-dl.log\".
"; +$lang['cardRegisterDownloadingYT'] = "Piste YouTube en cours de téléchargement. Cela peut prendre plusieurs minutes. Log dans le fichier \"youtube-download.log\".
"; $lang['cardRegisterSwipeUpdates'] = "Mise à jour automatique lors du passage d'une carte."; $lang['cardRegisterManualLinks'] = "Vous pouvez lier manuellement une carte à un dossier. Explication dans la documentation connection à phoniebox et enregistrer une carte.
"; $lang['cardRegisterTriggerSuccess'] = "La carte est désormais lié à une commande :"; diff --git a/htdocs/lang/lang-nl-NL.php b/htdocs/lang/lang-nl-NL.php index 38c6c451b..faa6eed53 100755 --- a/htdocs/lang/lang-nl-NL.php +++ b/htdocs/lang/lang-nl-NL.php @@ -113,7 +113,7 @@ $lang['cardRegisterErrorConvertSpotifyURL'] = "Verkeerde spotify url, geconverteerd naar het juiste formaat"; $lang['cardRegisterStream2Card'] = "Stream is gekoppeld aan kaart-ID."; $lang['cardRegisterFolder2Card'] = "De audiomap is nu gekoppeld aan kaart-ID"; -$lang['cardRegisterDownloadingYT'] = "YouTube-audio wordt gedownload. Dit kan een paar minuten duren. U kunt het logbestand 'youtube-dl.log' in de gedeelde map controleren.
"; +$lang['cardRegisterDownloadingYT'] = "YouTube-audio wordt gedownload. Dit kan een paar minuten duren. U kunt het logbestand 'youtube-download.log' in de gedeelde map controleren.
"; $lang['cardRegisterSwipeUpdates'] = "Dit wordt automatisch bijgewerkt terwijl je een RFID-kaart veegt."; $lang['cardRegisterManualLinks'] = "U kunt kaarten ook handmatig met mappen verbinden. In de handleiding wordt uitgelegd hoe u verbinding maakt met de phoniebox en kaarten registreert.
"; diff --git a/misc/sampleconfigs/15-fastcgi-php.conf.buster-default.sample b/misc/sampleconfigs/15-fastcgi-php.conf-default.sample old mode 100755 new mode 100644 similarity index 100% rename from misc/sampleconfigs/15-fastcgi-php.conf.buster-default.sample rename to misc/sampleconfigs/15-fastcgi-php.conf-default.sample diff --git a/misc/sampleconfigs/autohotspot/NetworkManager/autohotspot.service b/misc/sampleconfigs/autohotspot/NetworkManager/autohotspot.service index 746b960e1..e33c10910 100644 --- a/misc/sampleconfigs/autohotspot/NetworkManager/autohotspot.service +++ b/misc/sampleconfigs/autohotspot/NetworkManager/autohotspot.service @@ -1,7 +1,6 @@ [Unit] Description=Automatically generates an wifi hotspot when a valid SSID is not in range After=multi-user.target -Requires=network-online.target [Service] Type=simple diff --git a/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot-daemon.service b/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot-daemon.service index d0381e5ce..3be630d16 100644 --- a/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot-daemon.service +++ b/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot-daemon.service @@ -1,6 +1,6 @@ [Unit] Description=Daemon for regular network connection if no hotspot is created -After=multi-user.target +After=network.target [Service] Type=simple diff --git a/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot.service b/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot.service index 746b960e1..e33c10910 100644 --- a/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot.service +++ b/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot.service @@ -1,7 +1,6 @@ [Unit] Description=Automatically generates an wifi hotspot when a valid SSID is not in range After=multi-user.target -Requires=network-online.target [Service] Type=simple diff --git a/misc/sampleconfigs/deviceName.txt.stretch-default.sample b/misc/sampleconfigs/deviceName.txt.stretch-default.sample deleted file mode 100755 index 434b52bed..000000000 --- a/misc/sampleconfigs/deviceName.txt.stretch-default.sample +++ /dev/null @@ -1 +0,0 @@ -Sycreader USB Reader \ No newline at end of file diff --git a/misc/sampleconfigs/dhcpcd.conf.buster-default-noHotspot.sample b/misc/sampleconfigs/dhcpcd.conf-default-noHotspot.sample old mode 100755 new mode 100644 similarity index 100% rename from misc/sampleconfigs/dhcpcd.conf.buster-default-noHotspot.sample rename to misc/sampleconfigs/dhcpcd.conf-default-noHotspot.sample diff --git a/misc/sampleconfigs/gpio_settings.ini.sample b/misc/sampleconfigs/gpio_settings.ini.sample index 4f84ba01b..a386d6ec6 100644 --- a/misc/sampleconfigs/gpio_settings.ini.sample +++ b/misc/sampleconfigs/gpio_settings.ini.sample @@ -4,20 +4,28 @@ antibouncehack: False [VolumeControl] enabled: False -Type: TwoButtonControl ;or RotaryEncoder +Type: TwoButtonControl Pin1: 5 Pin2: 6 pull_up_down: pull_up hold_time: 0.3 hold_mode: Repeat -timeBase: 0.1 ;only for RotaryEncoder functionCall1: functionCallVolU functionCall2: functionCallVolD -functionCallTwoButtons: functionCallVol0 ;only for TwoButtonControl +functionCallTwoButtons: functionCallVol0 ;functionCall1Args: 1 ;functionCall2Args: 1 ;functionCallTwoButtonsArgs: x +[RotaryVolumeControl] +enabled: False +Type: RotaryEncoder +Pin1: 22 +Pin2: 23 +timeBase: 0.1 +functionCall1: functionCallVolU +functionCall2: functionCallVolD + [PrevNextControl] enabled: False Type: TwoButtonControl @@ -143,3 +151,7 @@ pull_up_down: pull_up functionCall: functionCallTriggerPlayFolder functionCallArgs: someRelativeFolderName +[StatusLED] +enabled: False +Type: StatusLED +Pin: 14 diff --git a/misc/sampleconfigs/lighttpd.conf.buster-default.sample b/misc/sampleconfigs/lighttpd.conf-default.sample old mode 100755 new mode 100644 similarity index 100% rename from misc/sampleconfigs/lighttpd.conf.buster-default.sample rename to misc/sampleconfigs/lighttpd.conf-default.sample diff --git a/misc/sampleconfigs/mopidy-etc.sample b/misc/sampleconfigs/mopidy.conf.sample similarity index 81% rename from misc/sampleconfigs/mopidy-etc.sample rename to misc/sampleconfigs/mopidy.conf.sample index ac2b7707a..7465c250d 100644 --- a/misc/sampleconfigs/mopidy-etc.sample +++ b/misc/sampleconfigs/mopidy.conf.sample @@ -1,12 +1,3 @@ -[core] -cache_dir = /var/cache/mopidy -config_dir = /etc/mopidy -data_dir = /var/lib/mopidy - -[logging] -config_file = /etc/mopidy/logging.conf -debug_file = /var/log/mopidy/mopidy-debug.log - [local] enabled = true media_dir = %DIRaudioFolders% diff --git a/misc/sampleconfigs/mopidy.sample b/misc/sampleconfigs/mopidy.sample deleted file mode 100644 index 7ce7c7bd6..000000000 --- a/misc/sampleconfigs/mopidy.sample +++ /dev/null @@ -1,159 +0,0 @@ -# For further information about options in this file see: -# http://docs.mopidy.com/ -# -# The initial commented out values reflect the defaults as of: -# Mopidy 2.2.0 -# Mopidy-File 2.2.0 -# Mopidy-HTTP 2.2.0 -# Mopidy-Iris 3.27.1 -# Mopidy-Local 2.2.0 -# Mopidy-Local-Images 1.0.0 -# Mopidy-M3U 2.2.0 -# Mopidy-MPD 2.2.0 -# Mopidy-SoftwareMixer 2.2.0 -# Mopidy-Spotify 3.1.0 -# Mopidy-Stream 2.2.0 -# -# Available options and defaults might have changed since then, -# run `mopidy config` to see the current effective config and -# `mopidy --version` to check the current version. - -[core] -cache_dir = $XDG_CACHE_DIR/mopidy -config_dir = $XDG_CONFIG_DIR/mopidy -data_dir = $XDG_DATA_DIR/mopidy -max_tracklist_length = 10000 -restore_state = false - -[logging] -#color = true -#console_format = %(levelname)-8s %(message)s -#debug_format = %(levelname)-8s %(asctime)s [%(process)d:%(threadName)s] %(name)s\n %(message)s -#debug_file = mopidy.log -#config_file = - -[audio] -#mixer = software -mixer_volume = 30 -output = alsasink -#buffer_time = - -[proxy] -#scheme = -#hostname = -#port = -#username = -#password = - -[local-images] -#enabled = true -#library = json -#base_uri = /images/ -#image_dir = -#album_art_files = -# *.jpg -# *.jpeg -# *.png - -[iris] -#enabled = true -country = DE -locale = de_DE -#spotify_authorization_url = https://jamesbarnsley.co.nz/iris/auth_spotify.php -#lastfm_authorization_url = https://jamesbarnsley.co.nz/iris/auth_lastfm.php -#genius_authorization_url = https://jamesbarnsley.co.nz/iris/auth_genius.php -#snapcast_enabled = false -#snapcast_host = localhost -#snapcast_port = 1705 - -[mpd] -#enabled = true -hostname = 0.0.0.0 -#port = 6600 -#password = -#max_connections = 20 -#connection_timeout = 60 -#zeroconf = Mopidy MPD server on $hostname -#command_blacklist = -# listall -# listallinfo -#default_playlist_scheme = m3u - -[http] -#enabled = true -hostname = 0.0.0.0 -#port = 6680 -#static_dir = -#zeroconf = Mopidy HTTP server on $hostname -#allowed_origins = - -[stream] -#enabled = true -#protocols = -# http -# https -# mms -# rtmp -# rtmps -# rtsp -#metadata_blacklist = -#timeout = 5000 - -[m3u] -#enabled = true -#base_dir = $XDG_MUSIC_DIR -default_encoding = UTF-8 -default_extension = .m3u -playlists_dir = /home/pi/RPi-Jukebox-RFID/playlists - -[softwaremixer] -#enabled = true - -[file] -#enabled = true -#media_dirs = -# $XDG_MUSIC_DIR|Music -# ~/|Home -#excluded_file_extensions = -# .jpg -# .jpeg -#show_dotfiles = false -#follow_symlinks = false -metadata_timeout = 1 - -[local] -enabled = true -#library = json -media_dir = %DIRaudioFolders% -#scan_timeout = 1000 -#scan_flush_threshold = 100 -#scan_follow_symlinks = false -excluded_file_extensions = -# .directory -# .html -# .jpeg - .jpg -# .log -# .nfo -# .png - .txt - .conf - placeholder - -[spotify] -enabled = true -username = %spotify_username% -password = %spotify_password% -client_id = %spotify_client_id% -client_secret = %spotify_client_secret% -#bitrate = 160 -#volume_normalization = true -#private_session = false -#timeout = 10 -#allow_cache = true -#allow_network = true -#allow_playlists = true -#search_album_count = 20 -#search_artist_count = 10 -#search_track_count = 50 -#toplist_countries = diff --git a/misc/sampleconfigs/phoniebox-activate-amplifier.service.stretch-default.sample b/misc/sampleconfigs/phoniebox-activate-amplifier.service-default.sample old mode 100755 new mode 100644 similarity index 100% rename from misc/sampleconfigs/phoniebox-activate-amplifier.service.stretch-default.sample rename to misc/sampleconfigs/phoniebox-activate-amplifier.service-default.sample diff --git a/misc/sampleconfigs/phoniebox-rfid-reader.service.stretch-default.sample b/misc/sampleconfigs/phoniebox-rfid-reader.service-default.sample old mode 100755 new mode 100644 similarity index 100% rename from misc/sampleconfigs/phoniebox-rfid-reader.service.stretch-default.sample rename to misc/sampleconfigs/phoniebox-rfid-reader.service-default.sample diff --git a/misc/sampleconfigs/phoniebox-startup-scripts.service.stretch-default.sample b/misc/sampleconfigs/phoniebox-startup-scripts.service-default.sample similarity index 100% rename from misc/sampleconfigs/phoniebox-startup-scripts.service.stretch-default.sample rename to misc/sampleconfigs/phoniebox-startup-scripts.service-default.sample diff --git a/misc/sampleconfigs/phoniebox-startup-sound.service.stretch-default.sample b/misc/sampleconfigs/phoniebox-startup-sound.service.stretch-default.sample deleted file mode 100755 index e2f9af570..000000000 --- a/misc/sampleconfigs/phoniebox-startup-sound.service.stretch-default.sample +++ /dev/null @@ -1,16 +0,0 @@ -[Unit] -Description=Phoniebox Startup Sound -After=mpd.service - -[Service] -User=pi -Group=pi -Type=oneshot -RemainAfterExit=true -WorkingDirectory=/home/pi/RPi-Jukebox-RFID -ExecStartPre=/home/pi/RPi-Jukebox-RFID/scripts/playout_controls.sh -c=setvolumetostartup -ExecStart=/bin/sleep 2 -ExecStartPost=/usr/bin/mpg123 /home/pi/RPi-Jukebox-RFID/shared/startupsound.mp3 - -[Install] -WantedBy=multi-user.target diff --git a/misc/sampleconfigs/php.ini.buster-default.sample b/misc/sampleconfigs/php.ini-default.sample old mode 100755 new mode 100644 similarity index 100% rename from misc/sampleconfigs/php.ini.buster-default.sample rename to misc/sampleconfigs/php.ini-default.sample diff --git a/misc/sampleconfigs/smb.conf.buster-default.sample b/misc/sampleconfigs/smb.conf-default.sample old mode 100755 new mode 100644 similarity index 98% rename from misc/sampleconfigs/smb.conf.buster-default.sample rename to misc/sampleconfigs/smb.conf-default.sample index 38f4650f6..c0baa0189 --- a/misc/sampleconfigs/smb.conf.buster-default.sample +++ b/misc/sampleconfigs/smb.conf-default.sample @@ -4,7 +4,7 @@ # # This is the main Samba configuration file. You should read the # smb.conf(5) manual page in order to understand the options listed -# here. Samba has a huge number of configurable options most of which +# here. Samba has a huge number of configurable options most of which # are not shown in this example # # Some options that are often worth tuning have been included as @@ -16,8 +16,8 @@ # enough to be mentioned here # # NOTE: Whenever you modify this file you should run the command -# "testparm" to check that you have not made any basic syntactic -# errors. +# "testparm" to check that you have not made any basic syntactic +# errors. #======================= Global Settings ======================= @@ -66,7 +66,7 @@ # Server role. Defines in which mode Samba will operate. Possible # values are "standalone server", "member server", "classic primary # domain controller", "classic backup domain controller", "active -# directory domain controller". +# directory domain controller". # # Most people will want "standalone server" or "member server". # Running as "active directory domain controller" will require first @@ -101,7 +101,7 @@ # # The following settings only takes effect if 'server role = primary # classic domain controller', 'server role = backup domain controller' -# or 'domain logons' is set +# or 'domain logons' is set # # It specifies the location of the user's @@ -130,13 +130,13 @@ # password; please adapt to your needs ; add user script = /usr/sbin/adduser --quiet --disabled-password --gecos "" %u -# This allows machine accounts to be created on the domain controller via the -# SAMR RPC pipe. +# This allows machine accounts to be created on the domain controller via the +# SAMR RPC pipe. # The following assumes a "machines" group exists on the system ; add machine script = /usr/sbin/useradd -g machines -c "%u machine account" -d /var/lib/samba -s /bin/false %u # This allows Unix groups to be created on the domain controller via the SAMR -# RPC pipe. +# RPC pipe. ; add group script = /usr/sbin/addgroup --force-badname %g ############ Misc ############ @@ -220,7 +220,7 @@ create mask=0777 directory mask=0777 public=no - + # if the audiofiles are not in 'shared', we need this [phoniebox_audiofile] comment= Pi Jukebox diff --git a/misc/sampleconfigs/sudoers.buster-default.sample b/misc/sampleconfigs/sudoers.buster-default.sample deleted file mode 100755 index c98e7e85c..000000000 --- a/misc/sampleconfigs/sudoers.buster-default.sample +++ /dev/null @@ -1,29 +0,0 @@ -# -# This file MUST be edited with the 'visudo' command as root. -# -# Please consider adding local content in /etc/sudoers.d/ instead of -# directly modifying this file. -# -# See the man page for details on how to write a sudoers file. -# -Defaults env_reset -Defaults mail_badpass -Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" - -# Host alias specification - -# User alias specification - -# Cmnd alias specification - -# User privilege specification -root ALL=(ALL:ALL) ALL - -# Allow members of group sudo to execute any command -%sudo ALL=(ALL:ALL) ALL - -# See sudoers(5) for more information on "#include" directives: - -#includedir /etc/sudoers.d -www-data ALL=(ALL) NOPASSWD: ALL -mopidy ALL=NOPASSWD: /usr/local/lib/python2.7/dist-packages/mopidy_iris/system.sh diff --git a/packages-spotify.txt b/packages-spotify.txt index 862f2c2a3..5187a5f88 100644 --- a/packages-spotify.txt +++ b/packages-spotify.txt @@ -1,13 +1,7 @@ # Define packages for apt-get. These can be installed with # 'sed 's/#.*//g' packages.txt | xargs sudo apt-get install' -libspotify-dev -libspotify12 python3-cffi python3-ply python3-pycparser -python3-spotify mopidy -mopidy-mpd -mopidy-local -mopidy-spotify diff --git a/requirements-spotify.txt b/requirements-spotify.txt index 83c411544..2a27e9da5 100644 --- a/requirements-spotify.txt +++ b/requirements-spotify.txt @@ -1,3 +1,6 @@ # Spotify related requirements - # You need to install these with `sudo pip install --upgrade --force-reinstall -r requirements-spotify.txt` - Mopidy-Iris==3.69.3 +# You need to install these with `sudo pip install --upgrade --force-reinstall -r requirements-spotify.txt` +Mopidy-Local +Mopidy-MPD +Mopidy-Iris==3.69.3 +Mopidy-Spotify==5.0.0a2 diff --git a/requirements.txt b/requirements.txt index eba1cdd62..f4424e001 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ # related libraries. evdev git+https://github.com/lthiery/SPI-Py.git#egg=spi-py -git+https://github.com/ytdl-org/youtube-dl@master#egg=youtube-dl +yt-dlp pyserial RPi.GPIO diff --git a/scripts/RegisterDevice.py.Multi b/scripts/RegisterDevice.py.Multi index 66dc16898..008121496 100644 --- a/scripts/RegisterDevice.py.Multi +++ b/scripts/RegisterDevice.py.Multi @@ -17,7 +17,7 @@ def runCmd(cmd, wait=True): def setupPN532(): answer = input('Please make sure that the PN532 reader is wired up correctly ' 'to the GPIO ports before continuing...\n Continue?: [Y/n]') - if not answer or answer[0] != 'Y': + if answer and answer[0].lower() == 'n': return False print("Activating I2C interface...\n") runCmd("sudo raspi-config nonint do_i2c 0") @@ -41,7 +41,7 @@ def setupPN532(): def setupMFRC522(): answer = input('Please make sure that the RC522 reader is wired up correctly ' 'to the GPIO ports before continuing...\n Continue?: [Y/n]') - if not answer or answer[0] != 'Y': + if answer and answer[0].lower() == 'n': return False print("Installing Python requirements for RC522...\n") runCmd("sudo python3 -m pip install --upgrade --force-reinstall " @@ -78,7 +78,7 @@ def configureDevices(): addDevice() while True: answer = input('Do you want to add another device: [Y/n]') - if not answer or answer[0] != 'Y': + if answer and answer[0].lower() == 'n': break addDevice() diff --git a/scripts/helperscripts/Analytics_AfterInstallScript.sh b/scripts/helperscripts/Analytics_AfterInstallScript.sh index 2b68e9551..9ef8d648c 100755 --- a/scripts/helperscripts/Analytics_AfterInstallScript.sh +++ b/scripts/helperscripts/Analytics_AfterInstallScript.sh @@ -32,8 +32,8 @@ ls -lh /etc/lighttpd/conf-available/15-fastcgi-php.conf echo "*** /etc/php/7.3/fpm/php.ini" ls -lh /etc/php/7.3/fpm/php.ini -echo "*** /etc/sudoers" -ls -lh /etc/sudoers +echo "*** /etc/sudoers.d" +ls -lh /etc/sudoers.d/ echo "*** /etc/systemd/system/phoniebox*" ls -lh /etc/systemd/system/phoniebox-rfid-reader.service diff --git a/scripts/helperscripts/DeleteAllConfig.sh b/scripts/helperscripts/DeleteAllConfig.sh index 38081a051..556123b49 100755 --- a/scripts/helperscripts/DeleteAllConfig.sh +++ b/scripts/helperscripts/DeleteAllConfig.sh @@ -13,8 +13,9 @@ case "$response" in esac echo "Proceeding and deleting." -# these ones we MUST leave -#sudo rm /etc/sudoers +sudo rm /etc/sudoers.d/www-data +sudo rm /etc/sudoers.d/mopidy + #sudo rm /etc/samba/smb.conf # these ones we will leave @@ -47,4 +48,3 @@ sudo rm /etc/mpd.conf sudo rm /etc/locale.gen sudo rm /etc/default/locale sudo rm /etc/mopidy/mopidy.conf -sudo rm ~/.config/mopidy/mopidy.conf diff --git a/scripts/helperscripts/inc.helper.sh b/scripts/helperscripts/inc.helper.sh new file mode 100644 index 000000000..04cac78c8 --- /dev/null +++ b/scripts/helperscripts/inc.helper.sh @@ -0,0 +1,17 @@ +# Reads a textfile and pipes all lines as args to the given command. +# Does filter out comments. +# Arguments: +# 1 : textfile to read +# 2... : command to receive args (e.g. 'echo', 'apt-get -y install', ...) +call_with_args_from_file () { + local package_file="$1" + shift + + sed 's|#.*||g' ${package_file} | xargs "$@" +} + +# escape relevant chars for strings used in 'sed' commands. implies delimiter char '|' +escape_for_sed() { + local escaped=$(echo "$1" | sed -e 's/[\&'\''|]/\\&/g') + echo "$escaped" +} diff --git a/scripts/helperscripts/inc.networkHelper.sh b/scripts/helperscripts/inc.networkHelper.sh index ff0df181e..f96a9138d 100644 --- a/scripts/helperscripts/inc.networkHelper.sh +++ b/scripts/helperscripts/inc.networkHelper.sh @@ -74,7 +74,7 @@ add_wireless_network() { local wpa_network_with_dummy_psk=$(wpa_passphrase "$ssid" "dummypsk") if echo "$wpa_network_with_dummy_psk" | grep -qF 'network='; then local wpa_network=$(echo "$wpa_network_with_dummy_psk" | sed -e '/#psk/d' -e "s/psk=.*$/psk=${pass}/" -e "/^}/i\\\tpriority=${prio}" ) - sudo bash -c "echo '${wpa_network}' >> $WPA_CONF" + echo "${wpa_network}" | sudo tee -a "$WPA_CONF" > /dev/null fi fi fi diff --git a/scripts/helperscripts/setup_autohotspot.sh b/scripts/helperscripts/setup_autohotspot.sh index 2ae9cd361..61d0e2297 100644 --- a/scripts/helperscripts/setup_autohotspot.sh +++ b/scripts/helperscripts/setup_autohotspot.sh @@ -14,18 +14,6 @@ if [[ "$#" -lt 2 || ( "${AUTOHOTSPOTconfig}" != "NO" && "${AUTOHOTSPOTconfig}" ! exit 1 fi -# Reads a textfile and pipes all lines as args to the given command. -# Does filter out comments. -# Arguments: -# 1 : textfile to read -# 2... : command to receive args (e.g. 'echo', 'apt-get -y install', ...) -call_with_args_from_file () { - local package_file="$1" - shift - - sed 's/#.*//g' ${package_file} | xargs "$@" -} - _get_last_ip_segment() { local ip="$1" echo $ip | cut -d'.' -f1-3 @@ -80,6 +68,7 @@ wifi_interface=wlan0 ip_without_last_segment=$(_get_last_ip_segment $AUTOHOTSPOTip) autohotspot_profile="Phoniebox_Hotspot" +source "${JUKEBOX_HOME_DIR}"/scripts/helperscripts/inc.helper.sh source "${JUKEBOX_HOME_DIR}"/scripts/helperscripts/inc.networkHelper.sh _install_autohotspot_dhcpcd() { @@ -103,8 +92,8 @@ _install_autohotspot_dhcpcd() { config_file_backup "${dnsmasq_conf}" sudo cp "${JUKEBOX_HOME_DIR}"/misc/sampleconfigs/autohotspot/dhcpcd/dnsmasq.conf "${dnsmasq_conf}" - sudo sed -i "s|%WIFI_INTERFACE%|${wifi_interface}|g" "${dnsmasq_conf}" - sudo sed -i "s|%IP_WITHOUT_LAST_SEGMENT%|${ip_without_last_segment}|g" "${dnsmasq_conf}" + sudo sed -i "s|%WIFI_INTERFACE%|$(escape_for_sed "${wifi_interface}")|g" "${dnsmasq_conf}" + sudo sed -i "s|%IP_WITHOUT_LAST_SEGMENT%|$(escape_for_sed "${ip_without_last_segment}")|g" "${dnsmasq_conf}" sudo chown root:root "${dnsmasq_conf}" sudo chmod 644 "${dnsmasq_conf}" @@ -112,10 +101,10 @@ _install_autohotspot_dhcpcd() { config_file_backup "${hostapd_conf}" sudo cp "${JUKEBOX_HOME_DIR}"/misc/sampleconfigs/autohotspot/dhcpcd/hostapd.conf "${hostapd_conf}" - sudo sed -i "s|%WIFI_INTERFACE%|${wifi_interface}|g" "${hostapd_conf}" - sudo sed -i "s|%AUTOHOTSPOTssid%|${AUTOHOTSPOTssid}|g" "${hostapd_conf}" - sudo sed -i "s|%AUTOHOTSPOTpass%|${AUTOHOTSPOTpass}|g" "${hostapd_conf}" - sudo sed -i "s|%AUTOHOTSPOTcountryCode%|${AUTOHOTSPOTcountryCode}|g" "${hostapd_conf}" + sudo sed -i "s|%WIFI_INTERFACE%|$(escape_for_sed "${wifi_interface}")|g" "${hostapd_conf}" + sudo sed -i "s|%AUTOHOTSPOTssid%|$(escape_for_sed "${AUTOHOTSPOTssid}")|g" "${hostapd_conf}" + sudo sed -i "s|%AUTOHOTSPOTpass%|$(escape_for_sed "${AUTOHOTSPOTpass}")|g" "${hostapd_conf}" + sudo sed -i "s|%AUTOHOTSPOTcountryCode%|$(escape_for_sed "${AUTOHOTSPOTcountryCode}")|g" "${hostapd_conf}" sudo chown root:root "${hostapd_conf}" sudo chmod 644 "${hostapd_conf}" @@ -123,7 +112,7 @@ _install_autohotspot_dhcpcd() { config_file_backup "${hostapd_deamon}" sudo cp "${JUKEBOX_HOME_DIR}"/misc/sampleconfigs/autohotspot/dhcpcd/hostapd "${hostapd_deamon}" - sudo sed -i "s|%HOSTAPD_CONF%|${hostapd_conf}|g" "${hostapd_deamon}" + sudo sed -i "s|%HOSTAPD_CONF%|$(escape_for_sed "${hostapd_conf}")|g" "${hostapd_deamon}" sudo chown root:root "${hostapd_deamon}" sudo chmod 644 "${hostapd_deamon}" @@ -136,28 +125,28 @@ _install_autohotspot_dhcpcd() { fi if [[ ! $(grep -w "${dhcpcd_conf_nohook_wpa_supplicant}" ${dhcpcd_conf}) ]]; then - sudo bash -c "echo ${dhcpcd_conf_nohook_wpa_supplicant} >> ${dhcpcd_conf}" + echo "${dhcpcd_conf_nohook_wpa_supplicant}" | sudo tee -a "${dhcpcd_conf}" > /dev/null fi # create service to trigger hotspot sudo cp "${JUKEBOX_HOME_DIR}"/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot "${autohotspot_script}" - sudo sed -i "s|%WIFI_INTERFACE%|${wifi_interface}|g" "${autohotspot_script}" - sudo sed -i "s|%AUTOHOTSPOT_IP%|${AUTOHOTSPOTip}|g" "${autohotspot_script}" - sudo sed -i "s|%AUTOHOTSPOT_SERVICE_DAEMON%|${autohotspot_service_daemon}|g" "${autohotspot_script}" + sudo sed -i "s|%WIFI_INTERFACE%|$(escape_for_sed "${wifi_interface}")|g" "${autohotspot_script}" + sudo sed -i "s|%AUTOHOTSPOT_IP%|$(escape_for_sed "${AUTOHOTSPOTip}")|g" "${autohotspot_script}" + sudo sed -i "s|%AUTOHOTSPOT_SERVICE_DAEMON%|$(escape_for_sed "${autohotspot_service_daemon}")|g" "${autohotspot_script}" sudo chmod +x "${autohotspot_script}" sudo cp "${JUKEBOX_HOME_DIR}"/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot-daemon.service "${autohotspot_service_daemon_path}" - sudo sed -i "s|%WIFI_INTERFACE%|${wifi_interface}|g" "${autohotspot_service_daemon_path}" + sudo sed -i "s|%WIFI_INTERFACE%|$(escape_for_sed "${wifi_interface}")|g" "${autohotspot_service_daemon_path}" sudo chown root:root "${autohotspot_service_daemon_path}" sudo chmod 644 "${autohotspot_service_daemon_path}" sudo cp "${JUKEBOX_HOME_DIR}"/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot.service "${autohotspot_service_path}" - sudo sed -i "s|%AUTOHOTSPOT_SCRIPT%|${autohotspot_script}|g" "${autohotspot_service_path}" + sudo sed -i "s|%AUTOHOTSPOT_SCRIPT%|$(escape_for_sed "${autohotspot_script}")|g" "${autohotspot_service_path}" sudo chown root:root "${autohotspot_service_path}" sudo chmod 644 "${autohotspot_service_path}" sudo cp "${JUKEBOX_HOME_DIR}"/misc/sampleconfigs/autohotspot/dhcpcd/autohotspot.timer "${autohotspot_timer_path}" - sudo sed -i "s|%AUTOHOTSPOT_SERVICE%|${autohotspot_service}|g" "${autohotspot_timer_path}" + sudo sed -i "s|%AUTOHOTSPOT_SERVICE%|$(escape_for_sed "${autohotspot_service}")|g" "${autohotspot_timer_path}" sudo chown root:root "${autohotspot_timer_path}" sudo chmod 644 "${autohotspot_timer_path}" @@ -212,22 +201,22 @@ _install_autohotspot_NetworkManager() { # create service to trigger hotspot sudo cp "${JUKEBOX_HOME_DIR}"/misc/sampleconfigs/autohotspot/NetworkManager/autohotspot "${autohotspot_script}" - sudo sed -i "s|%WIFI_INTERFACE%|${wifi_interface}|g" "${autohotspot_script}" - sudo sed -i "s|%AUTOHOTSPOT_PROFILE%|${autohotspot_profile}|g" "${autohotspot_script}" - sudo sed -i "s|%AUTOHOTSPOT_SSID%|${AUTOHOTSPOTssid}|g" "${autohotspot_script}" - sudo sed -i "s|%AUTOHOTSPOT_PASSWORD%|${AUTOHOTSPOTpass}|g" "${autohotspot_script}" - sudo sed -i "s|%AUTOHOTSPOT_IP%|${AUTOHOTSPOTip}|g" "${autohotspot_script}" - sudo sed -i "s|%IP_WITHOUT_LAST_SEGMENT%|${ip_without_last_segment}|g" "${autohotspot_script}" - sudo sed -i "s|%AUTOHOTSPOT_TIMER_NAME%|${autohotspot_timer}|g" "${autohotspot_script}" + sudo sed -i "s|%WIFI_INTERFACE%|$(escape_for_sed "${wifi_interface}")|g" "${autohotspot_script}" + sudo sed -i "s|%AUTOHOTSPOT_PROFILE%|$(escape_for_sed "${autohotspot_profile}")|g" "${autohotspot_script}" + sudo sed -i "s|%AUTOHOTSPOT_SSID%|$(escape_for_sed "${AUTOHOTSPOTssid}")|g" "${autohotspot_script}" + sudo sed -i "s|%AUTOHOTSPOT_PASSWORD%|$(escape_for_sed "${AUTOHOTSPOTpass}")|g" "${autohotspot_script}" + sudo sed -i "s|%AUTOHOTSPOT_IP%|$(escape_for_sed "${AUTOHOTSPOTip}")|g" "${autohotspot_script}" + sudo sed -i "s|%IP_WITHOUT_LAST_SEGMENT%|$(escape_for_sed "${ip_without_last_segment}")|g" "${autohotspot_script}" + sudo sed -i "s|%AUTOHOTSPOT_TIMER_NAME%|$(escape_for_sed "${autohotspot_timer}")|g" "${autohotspot_script}" sudo chmod +x "${autohotspot_script}" sudo cp "${JUKEBOX_HOME_DIR}"/misc/sampleconfigs/autohotspot/NetworkManager/autohotspot.service "${autohotspot_service_path}" - sudo sed -i "s|%AUTOHOTSPOT_SCRIPT%|${autohotspot_script}|g" "${autohotspot_service_path}" + sudo sed -i "s|%AUTOHOTSPOT_SCRIPT%|$(escape_for_sed "${autohotspot_script}")|g" "${autohotspot_service_path}" sudo chown root:root "${autohotspot_service_path}" sudo chmod 644 "${autohotspot_service_path}" sudo cp "${JUKEBOX_HOME_DIR}"/misc/sampleconfigs/autohotspot/NetworkManager/autohotspot.timer "${autohotspot_timer_path}" - sudo sed -i "s|%AUTOHOTSPOT_SERVICE%|${autohotspot_service}|g" "${autohotspot_timer_path}" + sudo sed -i "s|%AUTOHOTSPOT_SERVICE%|$(escape_for_sed "${autohotspot_service}")|g" "${autohotspot_timer_path}" sudo chown root:root "${autohotspot_timer_path}" sudo chmod 644 "${autohotspot_timer_path}" diff --git a/scripts/installscripts/install-jukebox.sh b/scripts/installscripts/install-jukebox.sh index 751a2ef06..9025afeba 100644 --- a/scripts/installscripts/install-jukebox.sh +++ b/scripts/installscripts/install-jukebox.sh @@ -19,8 +19,6 @@ PATHDATA="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" GIT_BRANCH=${GIT_BRANCH:-master} GIT_URL=${GIT_URL:-https://github.com/MiczFlor/RPi-Jukebox-RFID.git} -echo GIT_BRANCH $GIT_BRANCH -echo GIT_URL $GIT_URL DATETIME=$(date +"%Y%m%d_%H%M%S") @@ -29,8 +27,7 @@ JOB="${SCRIPTNAME}" CURRENT_USER="${SUDO_USER:-$(whoami)}" HOME_DIR=$(getent passwd "$CURRENT_USER" | cut -d: -f6) -echo "Current User: $CURRENT_USER" -echo "User home dir: $HOME_DIR" + JUKEBOX_HOME_DIR="${HOME_DIR}/RPi-Jukebox-RFID" LOGDIR="${HOME_DIR}"/phoniebox_logs @@ -38,7 +35,6 @@ JUKEBOX_BACKUP_DIR="${HOME_DIR}/BACKUP" # Get the Raspberry Pi OS codename (e.g. buster, bullseye, ...) OS_CODENAME="$( . /etc/os-release; printf '%s\n' "$VERSION_CODENAME"; )" -printf "Used Raspberry Pi OS: ${OS_CODENAME}\n" WIFI_INTERFACE="wlan0" @@ -94,6 +90,14 @@ log_close() { fi } +# local function as it is needed before the repo is checked out! +_escape_for_shell() { + local escaped="${1//\"/\\\"}" + escaped="${escaped//\`/\\\`}" + escaped="${escaped//\$/\\\$}" + echo "$escaped" +} + checkPrerequisite() { #currently the user 'pi' is mandatory #https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/1785 @@ -215,12 +219,12 @@ case "$response" in *) # append variables to config file { - echo "WIFIconfig=\"$WIFIconfig\""; - echo "WIFIcountryCode=\"$WIFIcountryCode\""; - echo "WIFIssid=\"$WIFIssid\""; - echo "WIFIpass=\"$WIFIpass\""; - echo "WIFIip=\"$WIFIip\""; - echo "WIFIipRouter=\"$WIFIipRouter\""; + echo "WIFIconfig=\"$(_escape_for_shell "$WIFIconfig")\""; + echo "WIFIcountryCode=\"$(_escape_for_shell "$WIFIcountryCode")\""; + echo "WIFIssid=\"$(_escape_for_shell "$WIFIssid")\""; + echo "WIFIpass=\"$(_escape_for_shell "$WIFIpass")\""; + echo "WIFIip=\"$(_escape_for_shell "$WIFIip")\""; + echo "WIFIipRouter=\"$(_escape_for_shell "$WIFIipRouter")\""; } >> "${HOME_DIR}/PhonieboxInstall.conf" ;; esac @@ -229,9 +233,9 @@ case "$response" in WIFIconfig=NO echo "You want to configure WiFi later." # append variables to config file - echo "WIFIconfig=$WIFIconfig" >> "${HOME_DIR}/PhonieboxInstall.conf" + echo "WIFIconfig=\"$(_escape_for_shell "$WIFIconfig")\"" >> "${HOME_DIR}/PhonieboxInstall.conf" # make a fallback for WiFi Country Code, because we need that even without WiFi config - echo "WIFIcountryCode=DE" >> "${HOME_DIR}/PhonieboxInstall.conf" + echo "WIFIcountryCode=\"$(_escape_for_shell "DE")\"" >> "${HOME_DIR}/PhonieboxInstall.conf" ;; esac read -rp "Hit ENTER to proceed to the next step." INPUT @@ -303,18 +307,18 @@ case "$response" in esac # append variables to config file { - echo "AUTOHOTSPOTconfig=\"$AUTOHOTSPOTconfig\""; - echo "AUTOHOTSPOTssid=\"$AUTOHOTSPOTssid\""; - echo "AUTOHOTSPOTcountryCode=\"$AUTOHOTSPOTcountryCode\""; - echo "AUTOHOTSPOTpass=\"$AUTOHOTSPOTpass\""; - echo "AUTOHOTSPOTip=\"$AUTOHOTSPOTip\""; + echo "AUTOHOTSPOTconfig=\"$(_escape_for_shell "$AUTOHOTSPOTconfig")\""; + echo "AUTOHOTSPOTssid=\"$(_escape_for_shell "$AUTOHOTSPOTssid")\""; + echo "AUTOHOTSPOTcountryCode=\"$(_escape_for_shell "$AUTOHOTSPOTcountryCode")\""; + echo "AUTOHOTSPOTpass=\"$(_escape_for_shell "$AUTOHOTSPOTpass")\""; + echo "AUTOHOTSPOTip=\"$(_escape_for_shell "$AUTOHOTSPOTip")\""; } >> "${HOME_DIR}/PhonieboxInstall.conf" ;; *) AUTOHOTSPOTconfig=NO echo "You don't want to configure Autohotspot." # append variables to config file - echo "AUTOHOTSPOTconfig=$AUTOHOTSPOTconfig" >> "${HOME_DIR}/PhonieboxInstall.conf" + echo "AUTOHOTSPOTconfig=\"$(_escape_for_shell "$AUTOHOTSPOTconfig")\"" >> "${HOME_DIR}/PhonieboxInstall.conf" ;; esac @@ -430,7 +434,7 @@ check_existing() { ;; esac # append variables to config file - echo "EXISTINGuseRfidConf=$EXISTINGuseRfidConf" >> "${local_home_dir}/PhonieboxInstall.conf" + echo "EXISTINGuseRfidConf=\"$(_escape_for_shell "$EXISTINGuseRfidConf")\"" >> "${local_home_dir}/PhonieboxInstall.conf" read -rp "RFID shortcuts to play audio folders? [Y/n] " response case "$response" in @@ -442,7 +446,7 @@ check_existing() { ;; esac # append variables to config file - echo "EXISTINGuseRfidLinks=$EXISTINGuseRfidLinks" >> "${local_home_dir}/PhonieboxInstall.conf" + echo "EXISTINGuseRfidLinks=\"$(_escape_for_shell "$EXISTINGuseRfidLinks")\"" >> "${local_home_dir}/PhonieboxInstall.conf" read -rp "Audio folders: use existing? [Y/n] " response case "$response" in @@ -454,7 +458,7 @@ check_existing() { ;; esac # append variables to config file - echo "EXISTINGuseAudio=$EXISTINGuseAudio" >> "${local_home_dir}/PhonieboxInstall.conf" + echo "EXISTINGuseAudio=\"$(_escape_for_shell "$EXISTINGuseAudio")\"" >> "${local_home_dir}/PhonieboxInstall.conf" read -rp "Sound effects: use existing startup / shutdown sounds? [Y/n] " response case "$response" in @@ -466,7 +470,7 @@ check_existing() { ;; esac # append variables to config file - echo "EXISTINGuseSounds=$EXISTINGuseSounds" >> "${local_home_dir}/PhonieboxInstall.conf" + echo "EXISTINGuseSounds=\"$(_escape_for_shell "$EXISTINGuseSounds")\"" >> "${local_home_dir}/PhonieboxInstall.conf" if [ "$(printf '%s\n' "2.1" "$(cat ${local_home_dir}/BACKUP/settings/version-number)" | sort -V | head -n1)" = "2.1" ]; then read -rp "GPIO: use existing file? [Y/n] " response @@ -488,7 +492,7 @@ https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/Using-GPIO-hardware-buttons" config_gpio fi # append variables to config file - echo "EXISTINGuseGpio=$EXISTINGuseGpio" >> "${local_home_dir}/PhonieboxInstall.conf" + echo "EXISTINGuseGpio=\"$(_escape_for_shell "$EXISTINGuseGpio")\"" >> "${local_home_dir}/PhonieboxInstall.conf" read -rp "Button USB Encoder: use existing device and button mapping? [Y/n] " response case "$response" in @@ -500,7 +504,7 @@ https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/Using-GPIO-hardware-buttons" ;; esac # append variables to config file - echo "EXISTINGuseButtonUSBEncoder=$EXISTINGuseButtonUSBEncoder" >> "${local_home_dir}/PhonieboxInstall.conf" + echo "EXISTINGuseButtonUSBEncoder=\"$(_escape_for_shell "$EXISTINGuseButtonUSBEncoder")\"" >> "${local_home_dir}/PhonieboxInstall.conf" echo "Thanks. Got it." echo "The existing install can be found in the BACKUP directory." @@ -509,7 +513,7 @@ https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/Using-GPIO-hardware-buttons" esac fi # append variables to config file - echo "EXISTINGuse=$EXISTINGuse" >> "${local_home_dir}/PhonieboxInstall.conf" + echo "EXISTINGuse=\"$(_escape_for_shell "$EXISTINGuse")\"" >> "${local_home_dir}/PhonieboxInstall.conf" # Check if we found a Phoniebox install configuration earlier and ask if to run this now if [ "${EXISTINGusePhonieboxInstall}" == "YES" ]; then @@ -564,7 +568,7 @@ ${audio_interfaces} ;; esac # append variables to config file - echo "AUDIOiFace=\"$AUDIOiFace\"" >> "${HOME_DIR}/PhonieboxInstall.conf" + echo "AUDIOiFace=\"$(_escape_for_shell "$AUDIOiFace")\"" >> "${HOME_DIR}/PhonieboxInstall.conf" echo "Your iFace is called '$AUDIOiFace'" read -rp "Hit ENTER to proceed to the next step." INPUT } @@ -626,11 +630,11 @@ config_spotify() { esac # append variables to config file { - echo "SPOTinstall=\"$SPOTinstall\""; - echo "SPOTIuser=\"$SPOTIuser\""; - echo "SPOTIpass=\"$SPOTIpass\""; - echo "SPOTIclientid=\"$SPOTIclientid\""; - echo "SPOTIclientsecret=\"$SPOTIclientsecret\"" + echo "SPOTinstall=\"$(_escape_for_shell "$SPOTinstall")\""; + echo "SPOTIuser=\"$(_escape_for_shell "$SPOTIuser")\""; + echo "SPOTIpass=\"$(_escape_for_shell "$SPOTIpass")\""; + echo "SPOTIclientid=\"$(_escape_for_shell "$SPOTIclientid")\""; + echo "SPOTIclientsecret=\"$(_escape_for_shell "$SPOTIclientsecret")\"" } >> "${HOME_DIR}/PhonieboxInstall.conf" read -rp "Hit ENTER to proceed to the next step." INPUT } @@ -670,7 +674,7 @@ config_audio_folder() { ;; esac # append variables to config file - echo "DIRaudioFolders=\"$DIRaudioFolders\"" >> "${HOME_DIR}/PhonieboxInstall.conf" + echo "DIRaudioFolders=\"$(_escape_for_shell "$DIRaudioFolders")\"" >> "${HOME_DIR}/PhonieboxInstall.conf" echo "Your audio folders live in this dir:" echo "${DIRaudioFolders}" read -rp "Hit ENTER to proceed to the next step." INPUT @@ -711,7 +715,7 @@ config_gpio() { ;; esac # append variables to config file - echo "GPIOconfig=\"$GPIOconfig\"" >> "${HOME_DIR}/PhonieboxInstall.conf" + echo "GPIOconfig=\"$(_escape_for_shell "$GPIOconfig")\"" >> "${HOME_DIR}/PhonieboxInstall.conf" echo "" read -rp "Hit ENTER to proceed to the next step." INPUT } @@ -785,13 +789,11 @@ samba_config() { echo "Configuring Samba..." # Samba configuration settings # -rw-r--r-- 1 root root 9416 Apr 30 09:02 /etc/samba/smb.conf - sudo cp "${jukebox_dir}"/misc/sampleconfigs/smb.conf.buster-default.sample ${smb_conf} + sudo cp "${jukebox_dir}"/misc/sampleconfigs/smb.conf-default.sample ${smb_conf} sudo chown root:root "${smb_conf}" sudo chmod 644 "${smb_conf}" # for $DIRaudioFolders using | as alternate regex delimiter because of the folder path slash - sudo sed -i 's|%DIRaudioFolders%|'"$DIRaudioFolders"'|' "${smb_conf}" - # Replace homedir; double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${smb_conf}" + sudo sed -i 's|%DIRaudioFolders%|'"$(escape_for_sed "$DIRaudioFolders")"'|' "${smb_conf}" # Samba: create user 'pi' with password 'raspberry' # ToDo: use current user with a default password (echo "raspberry"; echo "raspberry") | sudo smbpasswd -s -a pi @@ -801,48 +803,33 @@ web_server_config() { local lighthttpd_conf="/etc/lighttpd/lighttpd.conf" local fastcgi_php_conf="/etc/lighttpd/conf-available/15-fastcgi-php.conf" local php_ini="/etc/php/$(ls -1 /etc/php)/cgi/php.ini" - local sudoers="/etc/sudoers" echo "Configuring web server..." # make sure lighttp can access the home directory of the user sudo chmod o+x ${HOME_DIR} # Web server configuration settings # -rw-r--r-- 1 root root 1040 Apr 30 09:19 /etc/lighttpd/lighttpd.conf - sudo cp "${jukebox_dir}"/misc/sampleconfigs/lighttpd.conf.buster-default.sample "${lighthttpd_conf}" + sudo cp "${jukebox_dir}"/misc/sampleconfigs/lighttpd.conf-default.sample "${lighthttpd_conf}" sudo chown root:root "${lighthttpd_conf}" sudo chmod 644 "${lighthttpd_conf}" - # double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${lighthttpd_conf}" # Web server PHP7 fastcgi conf # -rw-r--r-- 1 root root 398 Apr 30 09:35 /etc/lighttpd/conf-available/15-fastcgi-php.conf - sudo cp "${jukebox_dir}"/misc/sampleconfigs/15-fastcgi-php.conf.buster-default.sample ${fastcgi_php_conf} + sudo cp "${jukebox_dir}"/misc/sampleconfigs/15-fastcgi-php.conf-default.sample ${fastcgi_php_conf} sudo chown root:root "${fastcgi_php_conf}" sudo chmod 644 "${fastcgi_php_conf}" # settings for php.ini to support upload # -rw-r--r-- 1 root root 70999 Jun 14 13:50 /etc/php/7.3/cgi/php.ini - sudo cp "${jukebox_dir}"/misc/sampleconfigs/php.ini.buster-default.sample ${php_ini} + sudo cp "${jukebox_dir}"/misc/sampleconfigs/php.ini-default.sample ${php_ini} sudo chown root:root "${php_ini}" sudo chmod 644 "${php_ini}" # SUDO users (adding web server here) - # -r--r----- 1 root root 703 Nov 17 21:08 /etc/sudoers - sudo cp "${jukebox_dir}"/misc/sampleconfigs/sudoers.buster-default.sample ${sudoers} - sudo chown root:root "${sudoers}" - sudo chmod 440 "${sudoers}" -} - -# Reads a textfile and pipes all lines as args to the given command. -# Does filter out comments. -# Arguments: -# 1 : textfile to read -# 2... : command to receive args (e.g. 'echo', 'apt-get -y install', ...) -call_with_args_from_file () { - local package_file="$1" - shift - - sed 's/#.*//g' ${package_file} | xargs "$@" + local sudoers_wwwdata="/etc/sudoers.d/www-data" + echo "www-data ALL=(ALL) NOPASSWD: ALL" | sudo tee "${sudoers_wwwdata}" > /dev/null + sudo chown root:root "${sudoers_wwwdata}" + sudo chmod 440 "${sudoers_wwwdata}" } install_main() { @@ -883,6 +870,14 @@ install_main() { # Start logging here log_open + echo "################################################" + echo "Interactive mode: ${INTERACTIVE}" + echo "GIT_BRANCH ${GIT_BRANCH}" + echo "GIT_URL ${GIT_URL}" + echo "Current User: ${CURRENT_USER}" + echo "User home dir: ${HOME_DIR}" + echo "Used Raspberry Pi OS: ${OS_CODENAME}" + # Add conffile into logfile for better debugging echo "################################################" grep -v -e "SPOTI" -e "WIFIpass" "${HOME_DIR}/PhonieboxInstall.conf" @@ -917,6 +912,10 @@ install_main() { cd "${HOME_DIR}" git clone ${GIT_URL} --branch "${GIT_BRANCH}" + source "${jukebox_dir}"/scripts/helperscripts/inc.helper.sh + source "${jukebox_dir}"/scripts/helperscripts/inc.networkHelper.sh + + # some packages are only available on raspberry pi's but not on test docker containers running on x86_64 machines if [[ $(uname -m) =~ ^armv.+$ ]]; then call_with_args_from_file "${jukebox_dir}"/packages-raspberrypi.txt ${apt_get} ${allow_downgrades} install @@ -962,8 +961,22 @@ install_main() { ${apt_get} upgrade call_with_args_from_file "${jukebox_dir}"/packages-spotify.txt ${apt_get} ${allow_downgrades} install + # not yet available on apt.mopidy.com, so install manually + local arch=$(dpkg --print-architecture) + local gst_plugin_spotify_name="gst-plugin-spotify_0.12.2-1_${arch}.deb" + wget -q https://github.com/kingosticks/gst-plugins-rs-build/releases/download/gst-plugin-spotify_0.12.2-1/${gst_plugin_spotify_name} + ${apt_get} install ./${gst_plugin_spotify_name} + sudo rm -f ${gst_plugin_spotify_name} + # Install necessary Python packages ${pip_install} -r "${jukebox_dir}"/requirements-spotify.txt + + local sudoers_mopidy="/etc/sudoers.d/mopidy" + # Include 'python' in the command to make testing later on easier. If this command fails it will not be included in the file. + local python_version=$(python -c 'import sys; print("python{}.{}".format(sys.version_info.major, sys.version_info.minor))') + echo "mopidy ALL=NOPASSWD: /usr/local/lib/${python_version}/dist-packages/mopidy_iris/system.sh" | sudo tee "${sudoers_mopidy}" > /dev/null + sudo chown root:root "${sudoers_mopidy}" + sudo chmod 440 "${sudoers_mopidy}" fi # Install more required packages @@ -997,8 +1010,6 @@ install_main() { # create config file for web app from sample sudo cp "${jukebox_dir}"/htdocs/config.php.sample "${jukebox_dir}"/htdocs/config.php - # double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${jukebox_dir}"/htdocs/config.php # Starting web server and php7 sudo lighttpd-enable-mod fastcgi @@ -1023,7 +1034,7 @@ install_main() { sudo systemctl disable phoniebox-rotary-encoder sudo systemctl disable phoniebox-gpio-buttons.service sudo rm "${systemd_dir}"/rfid-reader.service - sudo rm "${systemd_dir}"/startup-sound.service + sudo rm "${systemd_dir}"/phoniebox-startup-sound.service sudo rm "${systemd_dir}"/gpio-buttons.service sudo rm "${systemd_dir}"/idle-watchdog.service sudo rm "${systemd_dir}"/phoniebox-rotary-encoder.service @@ -1032,27 +1043,17 @@ install_main() { # 2. install new ones - this is version > 1.1.8-beta RFID_READER_SERVICE="${systemd_dir}/phoniebox-rfid-reader.service" - sudo cp "${jukebox_dir}"/misc/sampleconfigs/phoniebox-rfid-reader.service.stretch-default.sample "${RFID_READER_SERVICE}" - # Replace homedir; double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${RFID_READER_SERVICE}" + sudo cp "${jukebox_dir}"/misc/sampleconfigs/phoniebox-rfid-reader.service-default.sample "${RFID_READER_SERVICE}" - #startup sound now part of phoniebox-startup-scripts - #sudo cp "${jukebox_dir}"/misc/sampleconfigs/phoniebox-startup-sound.service.stretch-default.sample "${systemd_dir}"/phoniebox-startup-sound.service STARTUP_SCRIPT_SERVICE="${systemd_dir}/phoniebox-startup-scripts.service" - sudo cp "${jukebox_dir}"/misc/sampleconfigs/phoniebox-startup-scripts.service.stretch-default.sample "${STARTUP_SCRIPT_SERVICE}" - # Replace homedir; double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${STARTUP_SCRIPT_SERVICE}" + sudo cp "${jukebox_dir}"/misc/sampleconfigs/phoniebox-startup-scripts.service-default.sample "${STARTUP_SCRIPT_SERVICE}" IDLE_WATCHDOG_SERVICE="${systemd_dir}/phoniebox-idle-watchdog.service" sudo cp "${jukebox_dir}"/misc/sampleconfigs/phoniebox-idle-watchdog.service.sample "${IDLE_WATCHDOG_SERVICE}" - # Replace homedir; double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${IDLE_WATCHDOG_SERVICE}" if [[ "${GPIOconfig}" == "YES" ]]; then GPIO_CONTROL_SERVICE="${systemd_dir}/phoniebox-gpio-control.service" sudo cp "${jukebox_dir}"/misc/sampleconfigs/phoniebox-gpio-control.service.sample "${GPIO_CONTROL_SERVICE}" - # Replace homedir; double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${GPIO_CONTROL_SERVICE}" fi sudo chown root:root "${systemd_dir}"/phoniebox-*.service @@ -1060,8 +1061,6 @@ install_main() { # enable the services needed sudo systemctl enable phoniebox-idle-watchdog sudo systemctl enable phoniebox-rfid-reader - #startup sound is part of phoniebox-startup-scripts now - #sudo systemctl enable phoniebox-startup-sound sudo systemctl enable phoniebox-startup-scripts # copy mp3s for startup and shutdown sound to the right folder cp "${jukebox_dir}"/misc/sampleconfigs/startupsound.mp3.sample "${jukebox_dir}"/shared/startupsound.mp3 @@ -1070,56 +1069,39 @@ install_main() { echo "Configuring MPD..." local mpd_conf="/etc/mpd.conf" + sudo systemctl enable mpd + sudo systemctl stop mpd # MPD configuration # -rw-r----- 1 mpd audio 14043 Jul 17 20:16 /etc/mpd.conf sudo cp "${jukebox_dir}"/misc/sampleconfigs/mpd.conf.sample ${mpd_conf} # Change vars to match install config - sudo sed -i 's/%AUDIOiFace%/'"$AUDIOiFace"'/' "${mpd_conf}" + sudo sed -i 's|%AUDIOiFace%|'"$(escape_for_sed "$AUDIOiFace")"'|' "${mpd_conf}" # for $DIRaudioFolders using | as alternate regex delimiter because of the folder path slash - sudo sed -i 's|%DIRaudioFolders%|'"$DIRaudioFolders"'|' "${mpd_conf}" - # Replace homedir; double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${mpd_conf}" + sudo sed -i 's|%DIRaudioFolders%|'"$(escape_for_sed "$DIRaudioFolders")"'|' "${mpd_conf}" sudo chown mpd:audio "${mpd_conf}" sudo chmod 640 "${mpd_conf}" - # start mpd - echo "Starting mpd service..." - sudo service mpd restart - sudo systemctl enable mpd # Spotify config if [ "${SPOTinstall}" == "YES" ]; then echo "Configuring Spotify support..." - local etc_mopidy_conf="/etc/mopidy/mopidy.conf" - local mopidy_conf="${HOME_DIR}/.config/mopidy/mopidy.conf" + local mopidy_conf="/etc/mopidy/mopidy.conf" sudo systemctl disable mpd - sudo service mpd stop + sudo systemctl stop mpd sudo systemctl enable mopidy + sudo systemctl stop mopidy # Install Config Files sudo cp "${jukebox_dir}"/misc/sampleconfigs/locale.gen.sample /etc/locale.gen sudo cp "${jukebox_dir}"/misc/sampleconfigs/locale.sample /etc/default/locale sudo locale-gen - mkdir -p "${HOME_DIR}"/.config/mopidy - sudo cp "${jukebox_dir}"/misc/sampleconfigs/mopidy-etc.sample "${etc_mopidy_conf}" - cp "${jukebox_dir}"/misc/sampleconfigs/mopidy.sample "${mopidy_conf}" + sudo cp "${jukebox_dir}"/misc/sampleconfigs/mopidy.conf.sample "${mopidy_conf}" # Change vars to match install config - sudo sed -i 's/%spotify_username%/'"$SPOTIuser"'/' "${etc_mopidy_conf}" - sudo sed -i 's/%spotify_password%/'"$SPOTIpass"'/' "${etc_mopidy_conf}" - sudo sed -i 's/%spotify_client_id%/'"$SPOTIclientid"'/' "${etc_mopidy_conf}" - sudo sed -i 's/%spotify_client_secret%/'"$SPOTIclientsecret"'/' "${etc_mopidy_conf}" + sudo sed -i 's|%spotify_username%|'"$(escape_for_sed "$SPOTIuser")"'|' "${mopidy_conf}" + sudo sed -i 's|%spotify_password%|'"$(escape_for_sed "$SPOTIpass")"'|' "${mopidy_conf}" + sudo sed -i 's|%spotify_client_id%|'"$(escape_for_sed "$SPOTIclientid")"'|' "${mopidy_conf}" + sudo sed -i 's|%spotify_client_secret%|'"$(escape_for_sed "$SPOTIclientsecret")"'|' "${mopidy_conf}" # for $DIRaudioFolders using | as alternate regex delimiter because of the folder path slash - sudo sed -i 's|%DIRaudioFolders%|'"$DIRaudioFolders"'|' "${etc_mopidy_conf}" - # Replace homedir; double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${etc_mopidy_conf}" - - sed -i 's/%spotify_username%/'"$SPOTIuser"'/' "${mopidy_conf}" - sed -i 's/%spotify_password%/'"$SPOTIpass"'/' "${mopidy_conf}" - sed -i 's/%spotify_client_id%/'"$SPOTIclientid"'/' "${mopidy_conf}" - sed -i 's/%spotify_client_secret%/'"$SPOTIclientsecret"'/' "${mopidy_conf}" - # for $DIRaudioFolders using | as alternate regex delimiter because of the folder path slash - sudo sed -i 's|%DIRaudioFolders%|'"$DIRaudioFolders"'|' "${mopidy_conf}" - # Replace homedir; double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${mopidy_conf}" + sudo sed -i 's|%DIRaudioFolders%|'"$(escape_for_sed "$DIRaudioFolders")"'|' "${mopidy_conf}" fi # GPIO-Control @@ -1138,8 +1120,8 @@ install_main() { echo "classic" > "${jukebox_dir}"/settings/edition fi - # update mpc / mpd DB - mpc update + wifi_settings "${jukebox_dir}" + autohotspot "${jukebox_dir}" # / INSTALLATION ##################################################### @@ -1167,7 +1149,7 @@ wifi_settings() { local wpa_supplicant_conf="/etc/wpa_supplicant/wpa_supplicant.conf" # -rw-rw-r-- 1 root netdev 137 Jul 16 08:53 /etc/wpa_supplicant/wpa_supplicant.conf sudo cp "${jukebox_dir}"/misc/sampleconfigs/wpa_supplicant.conf.sample "${wpa_supplicant_conf}" - sudo sed -i 's/%WIFIcountryCode%/'"$WIFIcountryCode"'/' "${wpa_supplicant_conf}" + sudo sed -i 's|%WIFIcountryCode%|'"$(escape_for_sed "$WIFIcountryCode")"'|' "${wpa_supplicant_conf}" sudo chown root:netdev "${wpa_supplicant_conf}" sudo chmod 664 "${wpa_supplicant_conf}" @@ -1177,13 +1159,13 @@ wifi_settings() { # DHCP configuration settings local dhcpcd_conf="/etc/dhcpcd.conf" #-rw-rw-r-- 1 root netdev 0 Apr 17 11:25 /etc/dhcpcd.conf - sudo cp "${jukebox_dir}"/misc/sampleconfigs/dhcpcd.conf.buster-default-noHotspot.sample "${dhcpcd_conf}" + sudo cp "${jukebox_dir}"/misc/sampleconfigs/dhcpcd.conf-default-noHotspot.sample "${dhcpcd_conf}" # Change IP for router and Phoniebox - sudo sed -i 's/%WIFIinterface%/'"$WIFI_INTERFACE"'/' "${dhcpcd_conf}" - sudo sed -i 's/%WIFIip%/'"$WIFIip"'/' "${dhcpcd_conf}" - sudo sed -i 's/%WIFIipRouter%/'"$WIFIipRouter"'/' "${dhcpcd_conf}" - sudo sed -i 's/%WIFIipExtDNS%/'"$wifiExtDNS"'/' "${dhcpcd_conf}" - sudo sed -i 's/%WIFIcountryCode%/'"$WIFIcountryCode"'/' "${dhcpcd_conf}" + sudo sed -i 's|%WIFIinterface%|'"$(escape_for_sed "$WIFI_INTERFACE")"'|' "${dhcpcd_conf}" + sudo sed -i 's|%WIFIip%|'"$(escape_for_sed "$WIFIip")"'|' "${dhcpcd_conf}" + sudo sed -i 's|%WIFIipRouter%|'"$(escape_for_sed "$WIFIipRouter")"'|' "${dhcpcd_conf}" + sudo sed -i 's|%WIFIipExtDNS%|'"$(escape_for_sed "$wifiExtDNS")"'|' "${dhcpcd_conf}" + sudo sed -i 's|%WIFIcountryCode%|'"$(escape_for_sed "$WIFIcountryCode")"'|' "${dhcpcd_conf}" # Change user:group and access mod sudo chown root:netdev "${dhcpcd_conf}" sudo chmod 664 "${dhcpcd_conf}" @@ -1224,7 +1206,7 @@ existing_assets() { # Additional error check: key should not start with a hash and not be empty. if [ ! "${key:0:1}" == '#' ] && [ -n "$key" ]; then # Replace the matching value in the newly created conf file - sed -i 's/%'"$key"'%/'"$val"'/' "${jukebox_dir}"/settings/rfid_trigger_play.conf + sed -i 's|%'"$key"'%|'"$val"'|' "${jukebox_dir}"/settings/rfid_trigger_play.conf fi done <"${backup_dir}"/settings/rfid_trigger_play.conf fi @@ -1257,8 +1239,6 @@ existing_assets() { # make sure service is still enabled by registering again USB_BUTTONS_SERVICE="/etc/systemd/system/phoniebox-buttons-usb-encoder.service" sudo cp -v "${jukebox_dir}"/components/controls/buttons_usb_encoder/phoniebox-buttons-usb-encoder.service.sample "${USB_BUTTONS_SERVICE}" - # Replace homedir; double quotes for variable expansion - sudo sed -i "s%/home/pi%${HOME_DIR}%g" "${USB_BUTTONS_SERVICE}" sudo systemctl start phoniebox-buttons-usb-encoder.service sudo systemctl enable phoniebox-buttons-usb-encoder.service fi @@ -1345,80 +1325,101 @@ autohotspot() { fi } -finish_installation() { - local jukebox_dir="$1" +finished() { echo " # # INSTALLATION FINISHED # ##################################################### + +Let the sounds begin. +Find more information and documentation on the github account: +https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/ + " +} - ##################################################### - # Register external device(s) +register_rfid_reader() { + local jukebox_dir="$1" - echo "If you are using an RFID reader, connect it to your RPi." - echo "(In case your RFID reader required soldering, consult the manual.)" - # Use -e to display response of user in the logfile - read -e -r -p "Have you connected your RFID reader? [Y/n] " response - case "$response" in - [nN][oO]|[nN]) - ;; - *) - echo 'Please select the RFID reader you want to use' - options=("USB-Reader (e.g. Neuftech)" "RC522" "PN532" "Manual configuration" "Multiple RFID reader") - select opt in "${options[@]}"; do - case $opt in - "USB-Reader (e.g. Neuftech)") - cd "${jukebox_dir}"/scripts/ || exit - python3 RegisterDevice.py - sudo chown pi:www-data "${jukebox_dir}"/scripts/deviceName.txt - sudo chmod 644 "${jukebox_dir}"/scripts/deviceName.txt - break - ;; - "RC522") - bash "${jukebox_dir}"/components/rfid-reader/RC522/setup_rc522.sh - break - ;; - "PN532") - bash "${jukebox_dir}"/components/rfid-reader/PN532/setup_pn532.sh - break - ;; - "Manual configuration") - echo "Please configure your reader manually." - break - ;; - "Multiple RFID reader") - cd "${jukebox_dir}"/scripts/ || exit - sudo python3 RegisterDevice.py.Multi - break - ;; - *) - echo "This is not a number" - ;; - esac - done - esac + echo "" + echo "-----------------------------------------------------" + echo "Register RFID reader" + echo "-----------------------------------------------------" - echo - echo "DONE. Let the sounds begin." - echo "Find more information and documentation on the github account:" - echo "https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/" + if [[ ${INTERACTIVE} == "true" ]]; then + echo "If you are using an RFID reader, connect it to your RPi." + echo "(In case your RFID reader required soldering, consult the manual.)" + # Use -e to display response of user in the logfile + read -e -r -p "Have you connected your RFID reader? [Y/n] " response + case "$response" in + [nN][oO]|[nN]) + ;; + *) + echo 'Please select the RFID reader you want to use' + options=("USB-Reader (e.g. Neuftech)" "RC522" "PN532" "Manual configuration" "Multiple RFID reader") + select opt in "${options[@]}"; do + case $opt in + "USB-Reader (e.g. Neuftech)") + cd "${jukebox_dir}"/scripts/ || exit + python3 RegisterDevice.py + sudo chown pi:www-data "${jukebox_dir}"/scripts/deviceName.txt + sudo chmod 644 "${jukebox_dir}"/scripts/deviceName.txt + break + ;; + "RC522") + bash "${jukebox_dir}"/components/rfid-reader/RC522/setup_rc522.sh + break + ;; + "PN532") + bash "${jukebox_dir}"/components/rfid-reader/PN532/setup_pn532.sh + break + ;; + "Manual configuration") + echo "Please configure your reader manually." + break + ;; + "Multiple RFID reader") + cd "${jukebox_dir}"/scripts/ || exit + sudo python3 RegisterDevice.py.Multi + break + ;; + *) + echo "This is not a number" + ;; + esac + done + esac + else + echo "Skipping RFID reader setup..." + echo "For manual registration of an RFID reader type:" + echo "python3 ${JUKEBOX_HOME_DIR}/scripts/RegisterDevice.py" + fi +} - echo "Reboot is needed to activate all settings" - # Use -e to display response of user in the logfile - read -e -r -p "Would you like to reboot now? [Y/n] " response - case "$response" in - [nN][oO]|[nN]) - # Close logging - log_close - ;; - *) - # Close logging - log_close - sudo shutdown -r now - ;; - esac +cleanup_and_reboot() { + + echo "" + echo "-----------------------------------------------------" + echo "A reboot is required to activate all settings!" + local do_shutdown=false + if [[ ${INTERACTIVE} == "true" ]]; then + # Use -e to display response of user in the logfile + read -e -r -p "Would you like to reboot now? [Y/n] " response + case "$response" in + [nN][oO]|[nN]) + ;; + *) + do_shutdown=true + ;; + esac + fi + + # Close logging + log_close + if [[ ${do_shutdown} == "true" ]]; then + sudo shutdown -r now + fi } ######## @@ -1446,10 +1447,6 @@ main() { fi install_main "${JUKEBOX_HOME_DIR}" - source "${JUKEBOX_HOME_DIR}"/scripts/helperscripts/inc.networkHelper.sh - - wifi_settings "${JUKEBOX_HOME_DIR}" - autohotspot "${JUKEBOX_HOME_DIR}" existing_assets "${JUKEBOX_HOME_DIR}" "${JUKEBOX_BACKUP_DIR}" folder_access "${JUKEBOX_HOME_DIR}" "pi:www-data" 775 @@ -1458,15 +1455,10 @@ main() { sudo chown pi:www-data "${JUKEBOX_HOME_DIR}/settings/PhonieboxInstall.conf" sudo chmod 775 "${JUKEBOX_HOME_DIR}/settings/PhonieboxInstall.conf" - if [[ ${INTERACTIVE} == "true" ]]; then - finish_installation "${JUKEBOX_HOME_DIR}" - else - echo "Skipping USB device setup..." - echo "For manual registration of a USB card reader type:" - echo "python3 ${JUKEBOX_HOME_DIR}/scripts/RegisterDevice.py" - echo " " - echo "Reboot is required to activate all settings!" - fi + finished + + register_rfid_reader "${JUKEBOX_HOME_DIR}" + cleanup_and_reboot } start=$(date +%s) diff --git a/scripts/installscripts/tests/run_installation_autohotspot_NetworkManager.sh b/scripts/installscripts/tests/run_installation_autohotspot_NetworkManager.sh index 0979e7c72..cb935bec8 100644 --- a/scripts/installscripts/tests/run_installation_autohotspot_NetworkManager.sh +++ b/scripts/installscripts/tests/run_installation_autohotspot_NetworkManager.sh @@ -17,7 +17,8 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # y confirm interactive mode # n configure wifi (extra ENTER) # y configure autohotspot -# y use autohotspot default config (extra ENTER) +# n use autohotspot default config +# y use custom data (extra ENTER) # y use default audio iface (extra ENTER) # n spotify (extra ENTER) # y audio default location (extra ENTER) @@ -27,10 +28,15 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # n reboot export CI_TEST_DHCPCD="false" export CI_TEST_NETWORKMANAGER="true" -./../install-jukebox.sh <<< "y +./../install-jukebox.sh <<< 'y n y +n +a!b"c§d$e%f&g/h(i)j=k?l´m`n²o³p{q[r]s}t\u+v*w~x#y'\''z01234 +DE +ß,ä;ö.ü:Ä-Ö_Ü 1@2€3^4°5|6$7&8/9\0 +192.168.100.2 y y @@ -44,7 +50,7 @@ y y n n -" +' INSTALLATION_EXITCODE=$? # Test installation diff --git a/scripts/installscripts/tests/run_installation_autohotspot_dhcpcd.sh b/scripts/installscripts/tests/run_installation_autohotspot_dhcpcd.sh index 7091399bb..4e69e0866 100644 --- a/scripts/installscripts/tests/run_installation_autohotspot_dhcpcd.sh +++ b/scripts/installscripts/tests/run_installation_autohotspot_dhcpcd.sh @@ -17,7 +17,8 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # y confirm interactive mode # n configure wifi (extra ENTER) # y configure autohotspot -# y use autohotspot default config (extra ENTER) +# n use autohotspot default config +# y use custom data (extra ENTER) # y use default audio iface (extra ENTER) # n spotify (extra ENTER) # y audio default location (extra ENTER) @@ -27,10 +28,15 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # n reboot export CI_TEST_DHCPCD="true" export CI_TEST_NETWORKMANAGER="false" -./../install-jukebox.sh <<< "y +./../install-jukebox.sh <<< 'y n y +n +a!b"c§d$e%f&g/h(i)j=k?l´m`n²o³p{q[r]s}t\u+v*w~x#y'\''z01234 +DE +ß,ä;ö.ü:Ä-Ö_Ü 1@2€3^4°5|6$7&8/9\0 +10.0.0.1 y y @@ -44,7 +50,7 @@ y y n n -" +' INSTALLATION_EXITCODE=$? # Test installation diff --git a/scripts/installscripts/tests/run_installation_classic.sh b/scripts/installscripts/tests/run_installation_classic.sh index 434efc360..f52567f19 100644 --- a/scripts/installscripts/tests/run_installation_classic.sh +++ b/scripts/installscripts/tests/run_installation_classic.sh @@ -26,7 +26,7 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # n RFID registration # n reboot -./../install-jukebox.sh <<< "y +./../install-jukebox.sh <<< 'y n n @@ -42,7 +42,7 @@ y y n n -" +' INSTALLATION_EXITCODE=$? # Test installation diff --git a/scripts/installscripts/tests/run_installation_rfid.sh b/scripts/installscripts/tests/run_installation_rfid.sh index d9f150ad8..e3cfa08c2 100644 --- a/scripts/installscripts/tests/run_installation_rfid.sh +++ b/scripts/installscripts/tests/run_installation_rfid.sh @@ -28,7 +28,7 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # y, use legacy readermode # n reboot -./../install-jukebox.sh <<< "y +./../install-jukebox.sh <<< 'y n n @@ -47,7 +47,7 @@ y y y n -" +' INSTALLATION_EXITCODE=$? # Test installation diff --git a/scripts/installscripts/tests/run_installation_spotify.sh b/scripts/installscripts/tests/run_installation_spotify.sh index e63263a5a..d99ce30b3 100644 --- a/scripts/installscripts/tests/run_installation_spotify.sh +++ b/scripts/installscripts/tests/run_installation_spotify.sh @@ -25,7 +25,7 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # n RFID registration # n reboot -./../install-jukebox.sh <<< "y +./../install-jukebox.sh <<< 'y n n @@ -33,10 +33,10 @@ n y y -myuser -mypassword +a!b"c§d$e%f&g/h(i)j=k?l´m`n²o³p{q[r]s}t\u+v*w~x#y'\''zß,ä;ö.ü:Ä-Ö_Ü 1@2€3^4°5|67890 +a!b"c§d$e%f&g/h(i)j=k?l´m`n²o³p{q[r]s}t\u+v*w~x#y'\''zß,ä;ö.ü:Ä-Ö_Ü 1@2€3^4°5|67890 myclient_id -myclient_secret +myclient+SECRET/0123456789= y @@ -45,7 +45,7 @@ y y n n -" +' INSTALLATION_EXITCODE=$? # Test installation diff --git a/scripts/installscripts/tests/run_installation_staticip_dhcpcd.sh b/scripts/installscripts/tests/run_installation_staticip_dhcpcd.sh index a01610170..b143e8c70 100644 --- a/scripts/installscripts/tests/run_installation_staticip_dhcpcd.sh +++ b/scripts/installscripts/tests/run_installation_staticip_dhcpcd.sh @@ -28,11 +28,11 @@ echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selecti # n reboot export CI_TEST_DHCPCD="true" export CI_TEST_NETWORKMANAGER="false" -./../install-jukebox.sh <<< "y +./../install-jukebox.sh <<< 'y y -TestWifi +a!b"c§d$e%f&g/h(i)j=k?l´m`n²o³p{q[r]s}t\u+v*w~x#y'\''z01234 DE -TestWifiPW +ß,ä;ö.ü:Ä-Ö_Ü 1@2€3^4°5|6$7&8/9\0 192.168.100.2 192.168.100.1 y @@ -50,7 +50,7 @@ y y n n -" +' INSTALLATION_EXITCODE=$? # Test installation diff --git a/scripts/installscripts/tests/test_installation.sh b/scripts/installscripts/tests/test_installation.sh index 93fd63315..3f3aeebd8 100755 --- a/scripts/installscripts/tests/test_installation.sh +++ b/scripts/installscripts/tests/test_installation.sh @@ -27,12 +27,17 @@ check_chmod_chown() { for file in ${files}; do + local fail=false mod_actual=$(stat --format '%a' "${dir}/${file}") user_actual=$(stat -c '%U' "${dir}/${file}") group_actual=$(stat -c '%G' "${dir}/${file}") - test ! "${mod_expected}" -eq "${mod_actual}" && echo " ERROR: ${file} actual mod (${mod_actual}) differs from expected (${mod_expected})!" - test ! "${user_expected}" == "${user_actual}" && echo " ERROR: ${file} actual owner (${user_actual}) differs from expected (${user_expected})!" - test ! "${group_expected}" == "${group_actual}" && echo " ERROR: ${file} actual group (${group_actual}) differs from expected (${group_expected})!" + test ! "${mod_expected}" -eq "${mod_actual}" && echo " ERROR: ${file} actual mod (${mod_actual}) differs from expected (${mod_expected})!" && fail=true + test ! "${user_expected}" == "${user_actual}" && echo " ERROR: ${file} actual owner (${user_actual}) differs from expected (${user_expected})!" && fail=true + test ! "${group_expected}" == "${group_actual}" && echo " ERROR: ${file} actual group (${group_actual}) differs from expected (${group_expected})!" && fail=true + if [ $fail == true ]; then + ((failed_tests++)) + fi + ((tests++)) done } @@ -49,9 +54,33 @@ check_file_exists() { check_file_contains_string() { local string="$1" local file="$2" + local allowPartCheck="$3" + + local grep_option="w" + if [ -v allowPartCheck ]; then + grep_option="" + fi + + # sudo is required for checking /etc/mopidy/mopidy.conf + if [[ ! $(sudo grep -iF"${grep_option}" "${string}" "${file}") ]]; then + echo " ERROR: '${string}' not found in ${file}" + ((failed_tests++)) + fi + ((tests++)) +} + +check_file_contains_string_regex() { + local string="$1" + local file="$2" + local allowPartCheck="$3" + + local grep_option="w" + if [ -v allowPartCheck ]; then + grep_option="" + fi # sudo is required for checking /etc/mopidy/mopidy.conf - if [[ ! $(sudo grep -iw "${string}" "${file}") ]]; then + if [[ ! $(sudo grep -i"${grep_option}" "${string}" "${file}") ]]; then echo " ERROR: '${string}' not found in ${file}" ((failed_tests++)) fi @@ -249,7 +278,7 @@ verify_autohotspot_settings() { check_file_contains_string "daemon_service=\"${autohotspot_service_daemon}\"" "${autohotspot_script}" check_file_exists "${autohotspot_service_daemon_path}" - check_file_contains_string "\-i \"${autohotspot_wifi_interface}\"" "${autohotspot_service_daemon_path}" + check_file_contains_string "ExecStart=wpa_supplicant -i \"${autohotspot_wifi_interface}\"" "${autohotspot_service_daemon_path}" check_file_exists "${autohotspot_service_path}" check_file_contains_string "ExecStart=${autohotspot_script}" "${autohotspot_service_path}" @@ -320,6 +349,8 @@ verify_apt_packages() { # also check for spotify packages if it has been installed if [[ "${SPOTinstall}" == "YES" ]]; then packages="${packages} ${packages_spotify}" + # not yet available on apt.mopidy.com, so install manually + packages="${packages} gst-plugin-spotify" fi if [[ "$AUTOHOTSPOTconfig" == "YES" ]]; then @@ -404,7 +435,8 @@ verify_webserver_config() { check_chmod_chown 644 root root "/etc/lighttpd" "lighttpd.conf" check_chmod_chown 644 root root "/etc/lighttpd/conf-available" "15-fastcgi-php.conf" check_chmod_chown 644 root root "/etc/php/${phpver}/cgi" "php.ini" - check_chmod_chown 440 root root "/etc" "sudoers" + check_file_contains_string "www-data ALL=(ALL) NOPASSWD: ALL" "/etc/sudoers.d/www-data" + check_chmod_chown 440 root root "/etc/sudoers.d/" "www-data" # Bonus TODO: check that fastcgi and fastcgi-php mods are enabled } @@ -423,22 +455,18 @@ verify_systemd_services() { verify_spotify_config() { if [[ "${SPOTinstall}" == "YES" ]]; then - local etc_mopidy_conf="/etc/mopidy/mopidy.conf" - local mopidy_conf="${HOME_DIR}/.config/mopidy/mopidy.conf" + local mopidy_conf="/etc/mopidy/mopidy.conf" printf "\nTESTING spotify config...\n\n" - check_file_contains_string "username = ${SPOTIuser}" "${etc_mopidy_conf}" - check_file_contains_string "password = ${SPOTIpass}" "${etc_mopidy_conf}" - check_file_contains_string "client_id = ${SPOTIclientid}" "${etc_mopidy_conf}" - check_file_contains_string "client_secret = ${SPOTIclientsecret}" "${etc_mopidy_conf}" - check_file_contains_string "media_dir = ${DIRaudioFolders}" "${etc_mopidy_conf}" - check_file_contains_string "username = ${SPOTIuser}" "${mopidy_conf}" check_file_contains_string "password = ${SPOTIpass}" "${mopidy_conf}" check_file_contains_string "client_id = ${SPOTIclientid}" "${mopidy_conf}" check_file_contains_string "client_secret = ${SPOTIclientsecret}" "${mopidy_conf}" check_file_contains_string "media_dir = ${DIRaudioFolders}" "${mopidy_conf}" + check_file_contains_string "mopidy ALL=NOPASSWD: /usr/local/lib/python" "/etc/sudoers.d/mopidy" allowPartCheck + check_file_contains_string "/dist-packages/mopidy_iris/system.sh" "/etc/sudoers.d/mopidy" allowPartCheck + check_chmod_chown 440 root root "/etc/sudoers.d/" "mopidy" # check that mopidy service is enabled check_service_enablement mopidy enabled @@ -452,8 +480,8 @@ verify_mpd_config() { printf "\nTESTING mpd config...\n\n" - check_file_contains_string "^[[:blank:]]\+mixer_control[[:blank:]]\+\"${AUDIOiFace}\"" "${mpd_conf}" - check_file_contains_string "^music_directory[[:blank:]]\+\"${DIRaudioFolders}\"" "${mpd_conf}" + check_file_contains_string_regex "^[[:blank:]]\+mixer_control[[:blank:]]\+\"${AUDIOiFace}\"" "${mpd_conf}" + check_file_contains_string_regex "^music_directory[[:blank:]]\+\"${DIRaudioFolders}\"" "${mpd_conf}" check_chmod_chown 640 mpd audio "/etc" "mpd.conf" diff --git a/scripts/startup-scripts.sh b/scripts/startup-scripts.sh index 94b1c6a66..d1042b7b3 100755 --- a/scripts/startup-scripts.sh +++ b/scripts/startup-scripts.sh @@ -54,7 +54,12 @@ echo "${mpgvolume} is the mpg123 startup volume" ####################### # re-scan music library -mpc rescan +# if spotify edition is installed, update via mopidy as mpc update doesnt work +if [ "$EDITION" == "plusSpotify" ]; then + sudo mopidyctl local scan > /dev/null 2>&1 +else + mpc rescan +fi ####################### # read out wifi config? diff --git a/settings/version-number b/settings/version-number index e70b4523a..24ba9a38d 100644 --- a/settings/version-number +++ b/settings/version-number @@ -1 +1 @@ -2.6.0 +2.7.0