diff --git a/.githooks/pre-commit b/.githooks/pre-commit index b1b0c0348..8ffc7de0c 100755 --- a/.githooks/pre-commit +++ b/.githooks/pre-commit @@ -9,6 +9,9 @@ # Note: This only checks the modified files # - docs build of if any python file is staged # Note: This builds the entire documentation if a changed file goes into the documentation +# - Markdownlint if any markdown file is staged +# Note: This checks all markdown files as configured in .markdownlint-cli2.yaml + # # If there are problem with this script, commit may still be done with # git commit --no-verify @@ -40,6 +43,20 @@ fi code=$(( flake8_code + doc_code )) +# Pass all staged markdown files through markdownlint-cli2 +MD_FILES="$(git diff --diff-filter=d --staged --name-only -- **/*.md)" +markdownlint_code=0 +if [[ -n $MD_FILES ]]; then + echo -e "\n**************************************************************" + echo "Modified Markdown files. Running markdownlint-cli2 ... " + echo -e "**************************************************************\n" + ./run_markdownlint.sh + markdownlint_code=$? + echo "Markdownlint-cli2 return code: $markdownlint_code" +fi + +code=$(( flake8_code + doc_code + markdownlint_code)) + if [[ code -gt 0 ]]; then echo -e "\n**************************************************************" echo -e "ERROR(s) during pre-commit checks. Aborting commit!" diff --git a/.github/ISSUE_TEMPLATE/bug_template.md b/.github/ISSUE_TEMPLATE/bug_template.md index 508cf50b9..afcb9bd0c 100644 --- a/.github/ISSUE_TEMPLATE/bug_template.md +++ b/.github/ISSUE_TEMPLATE/bug_template.md @@ -33,7 +33,6 @@ Please post here the output of 'tail -n 500 /var/log/syslog' or 'journalctl -u m i.e. `find logfiles at https://paste.ubuntu.com/p/cRS7qM8ZmP/` --> - ## Software ### Base image and version @@ -59,7 +58,6 @@ the following command will help with that i.e. `scripts/installscripts/buster-install-default.sh` --> - ## Hardware ### RaspberryPi version diff --git a/.github/workflows/markdown_v3.yml b/.github/workflows/markdown_v3.yml new file mode 100644 index 000000000..38284038e --- /dev/null +++ b/.github/workflows/markdown_v3.yml @@ -0,0 +1,28 @@ +name: Markdown Linting + +on: + push: + branches: + - 'future3/**' + paths: + - '**.md' + pull_request: + branches: + - 'future3/**' + paths: + - '**.md' + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Linting markdown + uses: DavidAnson/markdownlint-cli2-action@v15 + with: + config: .markdownlint-cli2.yaml + #continue-on-error: true diff --git a/.markdownlint-cli2.yaml b/.markdownlint-cli2.yaml new file mode 100644 index 000000000..2fd1409d8 --- /dev/null +++ b/.markdownlint-cli2.yaml @@ -0,0 +1,52 @@ +# +# markdownlint-cli2 configuration, see https://github.com/DavidAnson/markdownlint-cli2?tab=readme-ov-file#configuration +# + +# rules, see https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md +config: + line-length: false + # ignore dollar signs + commands-show-output: false + no-trailing-punctuation: false + +# Include a custom rule package +#customRules: +# - markdownlint-rule-titlecase + +# Fix no fixable errors +fix: false + +# Define a custom front matter pattern +#frontMatter: "[^]*<\/head>" + +# Define glob expressions to use (only valid at root) +globs: + - "**.md" + +# Define glob expressions to ignore +ignores: + - "documentation/developers/docstring/*" + - "src/**" + +# Use a plugin to recognize math +#markdownItPlugins: +# - +# - "@iktakahiro/markdown-it-katex" + +# Additional paths to resolve module locations from +#modulePaths: +# - "./modules" + +# Enable inline config comments +noInlineConfig: false + +# Disable progress on stdout (only valid at root) +noProgress: true + +# Use a specific formatter (only valid at root) +#outputFormatters: +# - +# - markdownlint-cli2-formatter-default + +# Show found files on stdout (only valid at root) +showFound: true diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 332baee88..a28c343f0 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,14 +1,14 @@ +# Contributor Covenant Code of Conduct -Dear Phonieboxians, - -As the Phoniebox community is growing, somebody suggested a pull request with the below document. I was hesitant to include it right away, but at the same time I thought: it might be good to have some kind of document to formulate the foundation this project is built on. To tell you the truth, this document is not it. However, it is a start and I thought: why not open this in the spirit of open source, sharing and pull requests and see if and how you or you or you want to change or add parts of this very *standard and corporate* document. Like most of you, I also have a small kid and my time is scarce, I might find some time though to add a bit. - -All the best, Micz +> [!NOTE] +> Dear Phonieboxians, +> +> As the Phoniebox community is growing, somebody suggested a pull request with the below document. I was hesitant to include it right away, but at the same time I thought: it might be good to have some kind of document to formulate the foundation this project is built on. To tell you the truth, this document is not it. However, it is a start and I thought: why not open this in the spirit of open source, sharing and pull requests and see if and how you or you or you want to change or add parts of this very *standard and corporate* document. Like most of you, I also have a small kid and my time is scarce, I might find some time though to add a bit. +> +> All the best, Micz 2018-08-21 -# Contributor Covenant Code of Conduct - This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] ## Our Pledge diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f4ac9cd16..feb47f2c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,15 +45,16 @@ as local, temporary scratch areas. Contributors have played a bigger role over time to keep Phoniebox on the edge of innovation :) -Our goal is to make it simple for you to contribute changes that improve functionality in your specific environment. -To achieve this, we have a set of guidelines that we kindly request contributors to adhere to. +Our goal is to make it simple for you to contribute changes that improve functionality in your specific environment. +To achieve this, we have a set of guidelines that we kindly request contributors to adhere to. These guidelines help us maintain a streamlined process and stay on top of incoming contributions. To report bug fixes and improvements, please follow the steps outlined below: + 1. For bug fixes and minor improvements, simply open a new issue or pull request (PR). 2. If you intend to port a feature from Version 2.x to future3 or wish to implement a new feature, we recommend reaching out to us beforehand. - - In such cases, please create an issue outlining your plans and intentions. - - We will ensure that there are no ongoing efforts on the same topic. + * In such cases, please create an issue outlining your plans and intentions. + * We will ensure that there are no ongoing efforts on the same topic. We eagerly await your contributions! You can review the current [feature list](documentation/developers/status.md) to check for available features and ongoing work. @@ -108,7 +109,7 @@ Run the checks below on the code. Fix those issues! Or you are running in delays We provide git hooks for those checks for convenience. To activate ~~~bash -cp .githooks/pre-commit` .git/hooks/. +cp .githooks/pre-commit .git/hooks/. ~~~ ### Python Code @@ -152,7 +153,7 @@ to detect in advance. If the code change results in a test failure, we will make our best effort to correct the error. If a fix cannot be determined and committed within 24 hours -of its discovery, the commit(s) responsible _may_ be reverted, at the +of its discovery, the commit(s) responsible *may* be reverted, at the discretion of the committer and Phonie maintainers. The original contributor will be notified of the revert. @@ -163,7 +164,7 @@ The original contributor will be notified of the revert. ## Guidelines -* Phoniebox runs on Raspberry Pi OS. +* Phoniebox runs on Raspberry Pi OS. * Minimum python version is currently **Python 3.9**. ## Additional Resources diff --git a/documentation/README.md b/documentation/README.md index bb11dd6f4..cbfb6276a 100644 --- a/documentation/README.md +++ b/documentation/README.md @@ -42,7 +42,7 @@ project check out the [documentation of Version 2](https://github.com/MiczFlor/R Version 3 has reached a mature state and will soon be the default version. However, some features may still be missing. Please check the [Feature Status](./developers/status.md), if YOUR feature is already implemented. -> [!NOTE] +> [!NOTE] > If version 3 has all the features you need, we recommend using Version 3. If there is a feature missing, please open an issue. diff --git a/documentation/builders/audio.md b/documentation/builders/audio.md index 93c46dd54..765c6a08e 100644 --- a/documentation/builders/audio.md +++ b/documentation/builders/audio.md @@ -24,6 +24,7 @@ to setup the configuration for the Jukebox Core App. Run the following steps in a console: + ```bash # Check available PulseAudio sinks $ pactl list sinks short @@ -45,6 +46,7 @@ $ paplay /usr/share/sounds/alsa/Front_Center.wav # This must also work when using an ALSA device $ aplay /usr/share/sounds/alsa/Front_Center.wav ``` + You can also try different PulseAudio sinks without setting the default sink. In this case the volume is the last used volume level for this sink: @@ -86,6 +88,7 @@ Pairing successful .... [PowerLocus Buddy]# exit ``` + If `bluetoothctl` has trouble to execute due to permission issue, try `sudo bluetoothctl`. Wait for a few seconds and then with `$ pactl list sinks short`, check wether the Bluetooth device shows up as an output. diff --git a/documentation/builders/autohotspot.md b/documentation/builders/autohotspot.md index 5a62a37ca..8efde605a 100644 --- a/documentation/builders/autohotspot.md +++ b/documentation/builders/autohotspot.md @@ -7,11 +7,12 @@ The Auto-Hotspot function enables the Jukebox to switch its connection between a ## How to connect -When the Jukebox cannot connect to a known WiFi, it will automatically create a hotspot. +When the Jukebox cannot connect to a known WiFi, it will automatically create a hotspot. You can connect to this hotspot using the password set during installation. Afterwards, you can access the Web App or connect via SSH as before, using the IP from the configuration. The default configuration is + ``` text * SSID : Phoniebox_Hotspot_ * Password : PlayItLoud! @@ -23,8 +24,7 @@ The default configuration is Auto-Hotspot can be enabled or disabled using the Web App or RPC Commands. -> [!NOTE] -> Disabling the Auto-Hotspot will run the WiFi check again and maintain the last connection state until reboot. +Disabling the Auto-Hotspot will run the WiFi check again and maintain the last connection state until reboot. > [!IMPORTANT] > If you disable this feature, you will lose access to the Jukebox if you are not near a known WiFi after reboot! @@ -34,11 +34,13 @@ Auto-Hotspot can be enabled or disabled using the Web App or RPC Commands. ### AutoHotspot functionality is not working Check the `autohotspot.service` status + ``` bash sudo systemctl status autohotspot.service ``` and logs + ``` bash sudo journalctl -u autohotspot.service -n 50 ``` @@ -52,12 +54,13 @@ Check your WiFi configuration. ### You need to add a new WiFi network to the Raspberry Pi #### Using the command line + Connect to the hotspot and open a terminal. Use the [raspi-config](https://www.raspberrypi.com/documentation/computers/configuration.html#wireless-lan) tool to add the new WiFi. ## Resources * [Raspberry Connect - Auto WiFi Hotspot Switch](https://www.raspberryconnect.com/projects/65-raspberrypi-hotspot-accesspoints/158-raspberry-pi-auto-wifi-hotspot-switch-direct-connection) * [Raspberry Pi - Configuring networking](https://www.raspberrypi.com/documentation/computers/configuration.html#using-the-command-line) -* [dhcpcd / wpa_supplicant]() - * [hostapd](http://w1.fi/hostapd/) - * [dnsmasq](https://thekelleys.org.uk/dnsmasq/doc.html) +* dhcpcd / wpa_supplicant + * [hostapd](http://w1.fi/hostapd/) + * [dnsmasq](https://thekelleys.org.uk/dnsmasq/doc.html) diff --git a/documentation/builders/components/power/onoff-shim.md b/documentation/builders/components/power/onoff-shim.md index b83ea6140..e9a2849c9 100644 --- a/documentation/builders/components/power/onoff-shim.md +++ b/documentation/builders/components/power/onoff-shim.md @@ -9,7 +9,7 @@ To install the software, open a terminal and type the following command to run t > [!NOTE] > The installation will ask you a few questions. You can safely answer with the default response. -``` +```bash curl https://get.pimoroni.com/onoffshim | bash ``` @@ -28,9 +28,8 @@ The OnOff SHIM comes with a 12-PIN header which needs soldering. If you want to | GPLCLK0 | 7 | 7 | GPIO4 | | GPIO17 | 11 | 11 | GPIO17 | -* More information can be found here: https://pinout.xyz/pinout/onoff_shim +* More information can be found here: ## Assembly options -![](https://cdn.review-images.pimoroni.com/upload-b6276a310ccfbeae93a2d13ec19ab83b-1617096824.jpg?width=640) - +![OnOffShim soldered on a Raspberry Pi](https://cdn.review-images.pimoroni.com/upload-b6276a310ccfbeae93a2d13ec19ab83b-1617096824.jpg?width=640) diff --git a/documentation/builders/components/soundcards/hifiberry.md b/documentation/builders/components/soundcards/hifiberry.md index 1f19fa96d..f663abb42 100644 --- a/documentation/builders/components/soundcards/hifiberry.md +++ b/documentation/builders/components/soundcards/hifiberry.md @@ -19,7 +19,6 @@ If you know you HifiBerry Board identifier, you can run the script as a 1-liner If you like to disable your HiFiberry Sound card and enable onboard sound, run the following command - ```bash ./setup_hifiberry.sh disable ``` diff --git a/documentation/builders/configuration.md b/documentation/builders/configuration.md index dd4c1fd53..c75f53683 100644 --- a/documentation/builders/configuration.md +++ b/documentation/builders/configuration.md @@ -27,9 +27,10 @@ $ ./run_jukebox.sh # Restart the service $ systemctl --user start jukebox-daemon ``` -To try different configurations, you can start the Jukebox with a custom config file. + +To try different configurations, you can start the Jukebox with a custom config file. This could be useful if you want your Jukebox to only allow a lower volume when started -at nighttime, signaling it's time to go to bed. :-) +at nighttime, signaling it's time to go to bed. :-) The path to the custom config file must be either absolute or relative to the folder `src/jukebox/`. ```bash diff --git a/documentation/builders/event-devices.md b/documentation/builders/event-devices.md index 8fe5d08e0..95e871430 100644 --- a/documentation/builders/event-devices.md +++ b/documentation/builders/event-devices.md @@ -1,6 +1,7 @@ # Event devices ## Background + Event devices are generic input devices that are exposed in `/dev/input`. This includes USB peripherals (Keyboards, Controllers, Joysticks or Mouse) as well as potentially bluetooth devices. @@ -23,6 +24,7 @@ modules: ``` And add the following section with the plugin specific configuration: + ``` yaml evdev: enabled: true @@ -49,6 +51,7 @@ devices: # list of devices to listen for on_press: # Currently only the on_press action is supported {rpc_command_definition} # eg `alias: toggle` ``` + The `{device nickname}` is only for your own orientation and can be choosen freely. For each device you need to figure out the `{device_name}` and the `{event_id}` corresponding to key strokes, as indicated in the sections below. @@ -65,7 +68,7 @@ for device in devices: The output could be in the style of: -``` +```text /dev/input/event1 Dell Dell USB Keyboard usb-0000:00:12.1-2/input0 /dev/input/event0 Dell USB Optical Mouse usb-0000:00:12.0-2/input0 ``` @@ -96,8 +99,10 @@ for event in dev.read_loop(): if event.type == ecodes.EV_KEY: print(categorize(event)) ``` + The output could be of the form: -``` + +```text device /dev/input/event1, name "DragonRise Inc. Generic USB Joystick ", phys "usb-3f980000.usb-1.2/input0" key event at 1672569673.124168, 297 (BTN_BASE4), down key event at 1672569673.385170, 297 (BTN_BASE4), up @@ -114,7 +119,6 @@ Look for entries like `No callback registered for button ...`. The RPC command follows the regular RPC command rules as defined in the [following documentation](./rpc-commands.md). - ## Full example config -A complete configuration example for a USB Joystick controller can be found in the [examples](../../resources/default-settings/evdev.example.yaml). \ No newline at end of file +A complete configuration example for a USB Joystick controller can be found in the [examples](../../resources/default-settings/evdev.example.yaml). diff --git a/documentation/builders/installation.md b/documentation/builders/installation.md index 7cd321b7a..e12514350 100644 --- a/documentation/builders/installation.md +++ b/documentation/builders/installation.md @@ -3,7 +3,7 @@ ## Install Raspberry Pi OS Lite > [!IMPORTANT] -> All Raspberry Pi models are supported. For sufficient performance, **we recommend Pi 2, 3 or Zero 2** (`ARMv7` models). Because Pi 1 or Zero 1 (`ARMv6` models) have limited resources, they are slower (during installation and start up procedure) and might require a bit more work! Pi 4 and 5 are an excess ;-) +> All Raspberry Pi models are supported. For sufficient performance, **we recommend Pi 2, 3 or Zero 2** (`ARMv7` models). Because Pi 1 or Zero 1 (`ARMv6` models) have limited resources, they are slower (during installation and start up procedure) and might require a bit more work! Pi 4 and 5 are an excess ;-) Before you can install the Phoniebox software, you need to prepare your Raspberry Pi. @@ -27,8 +27,9 @@ Before you can install the Phoniebox software, you need to prepare your Raspberr 8. Confirm the next warning about erasing the SD card with `Yes` 9. Wait for the imaging process to be finished (it'll take a few minutes) - ### Pre-boot preparation + +
In case you forgot to customize the OS settings, follow these instructions after RPi OS has been written to the SD card. @@ -81,8 +82,9 @@ You will need a terminal, like PuTTY for Windows or the Terminal app for Mac to ### Pre-install preparation / workarounds #### Network management since Bookworm +
-With Bookworm, network management has changed. Now, "NetworkManager" is used instead of "dhcpcd". +With Bookworm, network management has changed. Now, "NetworkManager" is used instead of "dhcpcd". Both methods are supported during installation, but "NetworkManager" is recommended as it is simpler to set up and use. For Bullseye, this can also be activated, though it requires a manual process before running the installation. @@ -91,32 +93,38 @@ If the settings are changed, your network will reset, and WiFi will not be confi Therefore, make sure you use a wired connection or perform the following steps in a local terminal with a connected monitor and keyboard. Change network config + * run `sudo raspi-config` * select `6 - Advanced Options` * select `AA - Network Config` * select `NetworkManager` If you need Wifi, add the information now + * select `1 - System Options` * select `1 - Wireless LAN` * enter Wifi information +
#### Workaround for 64-bit Kernels (Pi 4 and newer) +
The installation process checks if a 32-bit OS is running, as 64-bit is currently not supported. This check also fails if the kernel is running in 64-bit mode. This is the default for Raspberry Pi models 4 and newer. -To be able to run the installation, you have to switch to the 32-bit mode by modifying the `config.txt` and add/change the line `arm_64bit=0`. +To be able to run the installation, you have to switch to the 32-bit mode by modifying the `config.txt` and add/change the line `arm_64bit=0`. Up to Bullseye, the `config.txt` file is located at `/boot/`. Since Bookworm, the location changed to `/boot/firmware/` ([see here](https://www.raspberrypi.com/documentation/computers/config_txt.html)). Reboot before you proceed.
+ ## Install Phoniebox software Choose a version, run the corresponding install command in your SSH terminal and follow the instructions. + * [Stable Release](#stable-release) * [Pre-Release](#pre-release) * [Development](#development) @@ -127,6 +135,7 @@ After a successful installation, [configure your Phoniebox](configuration.md). > Depending on your hardware, this installation might last around 60 minutes (usually it's faster, 20-30 min). It updates OS packages, installs Phoniebox dependencies and applies settings. Be patient and don't let your computer go to sleep. It might disconnect your SSH connection causing the interruption of the installation process. Consider starting the installation in a terminal multiplexer like 'screen' or 'tmux' to avoid this. ### Stable Release + This will install the latest **stable release** from the *future3/main* branch. ```bash @@ -134,6 +143,7 @@ cd; bash <(wget -qO- https://raw.githubusercontent.com/MiczFlor/RPi-Jukebox-RFID ``` ### Pre-Release + This will install the latest **pre-release** from the *future3/develop* branch. ```bash @@ -141,6 +151,7 @@ cd; GIT_BRANCH='future3/develop' bash <(wget -qO- https://raw.githubusercontent. ``` ### Development + You can also install a specific branch and/or a fork repository. Update the variables to refer to your desired location. (The URL must not necessarily be updated, unless you have actually updated the file being downloaded.) > [!IMPORTANT] @@ -155,9 +166,9 @@ cd; GIT_USER='MiczFlor' GIT_BRANCH='future3/develop' bash <(wget -qO- https://ra > If you install another branch or from a fork repository, the Web App needs to be built locally. This is part of the installation process. See the the developers [Web App](../developers/webapp.md) documentation for further details. ### Logs + To follow the installation closely, use this command in another terminal. ```bash cd; tail -f INSTALL-.log ``` - diff --git a/documentation/builders/samba.md b/documentation/builders/samba.md index ac9a93bbc..8e486a181 100644 --- a/documentation/builders/samba.md +++ b/documentation/builders/samba.md @@ -4,15 +4,14 @@ To conveniently copy files to your Phoniebox via network `samba` can be configur ## Connect -To access the share open your OS network environment and select your Phoniebox device. +To access the share open your OS network environment and select your Phoniebox device. Alternatively directly access it via url with the file explorer (e.g. Windows `\\`, MacOS `smb://`). See also + * [MacOS](https://support.apple.com/lt-lt/guide/mac-help/mchlp1140/mac) ## User name / Password As login credentials use the same username you used to run the installation with. The password is `raspberry`. You can change the password anytime using the command `sudo smbpasswd -a ""`. - - diff --git a/documentation/builders/troubleshooting.md b/documentation/builders/troubleshooting.md index 5b4061aa8..a18272afb 100644 --- a/documentation/builders/troubleshooting.md +++ b/documentation/builders/troubleshooting.md @@ -47,10 +47,10 @@ The default logging config does 2 things: 1. It writes 2 log files: -```bash -shared/logs/app.log : Complete Debug Messages -shared/logs/errors.log : Only Errors and Warnings -``` + ```bash + shared/logs/app.log : Complete Debug Messages + shared/logs/errors.log : Only Errors and Warnings + ``` 2. Prints logging messages to the console. If run as a service, only error messages are emitted to console to avoid spamming the system log files. diff --git a/documentation/builders/webapp/playlists-livestreams-podcasts.md b/documentation/builders/webapp/playlists-livestreams-podcasts.md index 2b8be79a1..f45969e6e 100644 --- a/documentation/builders/webapp/playlists-livestreams-podcasts.md +++ b/documentation/builders/webapp/playlists-livestreams-podcasts.md @@ -3,11 +3,13 @@ By default, the Jukebox represents music based on its metadata like album name, artist or song name. The hierarchy and order of songs is determined by their original definition, e.g. order of songs within an album. If you prefer a specific list of songs to be played, you can use playlists (files ending with `*.m3u`). Jukebox also supports livestreams and podcasts (if connected to the internet) through playlists. ## Playlists + If you like the Jukebox to play songs in a pre-defined order, you can use .m3u playlists. A .m3u playlist is a plain text file that contains a list of file paths or URLs to multimedia files. Each entry in the playlist represents a single song, and they are listed in the order in which they should be played. ### Structure of a .m3u playlist + A .m3u playlist is a simple text document with each song file listed on a separate line. Each entry is optionally preceded by a comment line that starts with a '#' symbol. The actual file paths or URLs of the media files come after the comment. ### Creating a .m3u playlist @@ -18,7 +20,7 @@ A .m3u playlist is a simple text document with each song file listed on a separa 1. On the following lines, list the file paths or URLs of the media files you want to include in the playlist, one per line. They must refer to true files paths on your Jukebox. They can be relative or absolute paths. 1. Save the file with the .m3u extension, e.g. `my_playlist.m3u`. -``` +```text # Absolute /home//RPi-Jukebox-RFID/shared/audiofolders/Simone Sommerland/Die 30 besten Kindergartenlieder/08 - Pitsch, patsch, Pinguin.mp3 /home//RPi-Jukebox-RFID/shared/audiofolders/Simone Sommerland/Die 30 besten Spiel- Und Bewegungslieder/12 - Das rote Pferd.mp3 @@ -42,7 +44,7 @@ Based on the note above, we suggest to use m3u playlists like this, especially i #### Example folder structure -``` +```text └── audiofolders ├── wake-up-songs │ └── playlist.m3u @@ -74,9 +76,9 @@ In order to play radio livestreams on your Jukebox, you use playlists to registe You can now assign livestreams to cards [following the example](#assigning-a-m3u-playlist-to-a-card) of playlists. -#### Example folder structure and playlist names +#### Example folder structure and playlist names for livestreams -``` +```text └── audiofolders ├── wdr-kids │ └── wdr-kids-livestream.txt @@ -108,13 +110,13 @@ We will explain options 1 and 2 more closely. ### Using podcast.txt playlist in Jukebox 1. [Follow the steps above](#using-m3u-playlists-in-jukebox) to add a playlist to your Jukebox (make sure you have created individual folders). -1. When creating the playlist file, make sure it's called or at least ends with `podcasts.txt` instead of `.m3u`. (Examples: `awesome-podcast.txt`, `podcast.txt`). +1. When creating the playlist file, make sure it's called or at least ends with `podcast.txt` instead of `.m3u`. (Examples: `awesome-podcast.txt`, `podcast.txt`). 1. Add links to your individual podcast episodes just like you would with songs in .m3u playlists 1. As an alternative, you can provide a single RSS feed (XML). Jukebox will expand the file and refer to all episodes listed within this file. -#### Example folder structure and playlist names +#### Example folder structure and playlist names for podcasts -``` +```text └── audiofolders ├── die-maus │ └── die-maus-podcast.txt diff --git a/documentation/developers/README.md b/documentation/developers/README.md index 6addeaff1..ff21a8ceb 100644 --- a/documentation/developers/README.md +++ b/documentation/developers/README.md @@ -4,6 +4,7 @@ * [Development Environment](./development-environment.md) * [Python Development Notes](python.md) +* [Documentation (with Markdown)](documentatíon.md) ## Reference diff --git a/documentation/developers/docker.md b/documentation/developers/docker.md index 19a57e414..9b4db4697 100644 --- a/documentation/developers/docker.md +++ b/documentation/developers/docker.md @@ -49,17 +49,23 @@ They can be run individually or in combination. To do that, we use 1. [Install Docker & Compose (Mac)](https://docs.docker.com/docker-for-mac/install/) 2. Install pulseaudio 1. Use Homebrew to install - ``` - $ brew install pulseaudio - ``` - 2. Enable pulseaudio network capabilities. In an editor, open `/opt/homebrew/Cellar/pulseaudio/16.1/etc/pulse/default.pa` (you might need to adapt this path to your own system settings). Uncomment the following line. - ``` - load-module module-native-protocol-tcp - ``` + + ```bash + $ brew install pulseaudio + ``` + + 2. Enable pulseaudio network capabilities. In an editor, open `/opt/homebrew/Cellar/pulseaudio/16.1/etc/pulse/default.pa` (you might need to adapt this path to your own system settings). Uncomment the following line: + + ```text + load-module module-native-protocol-tcp + ``` + 3. Restart the pulseaudio service - ``` - $ brew services restart pulseaudio - ``` + + ```bash + $ brew services restart pulseaudio + ``` + 4. If you have trouble with your audio, try these resources to troubleshoot: [[1]](https://gist.github.com/seongyongkim/b7d630a03e74c7ab1c6b53473b592712), [[2]](https://devops.datenkollektiv.de/running-a-docker-soundbox-on-mac.html), [[3]](https://stackoverflow.com/a/50939994/1062438) > [!NOTE] @@ -189,7 +195,7 @@ details. If you notice the following exception while running MPD in Docker, it refers to a incorrect setup of your Mac host Pulseaudio. -``` +```text mpd | ALSA lib pulse.c:242:(pulse_connect) PulseAudio: Unable to connect: Connection refused mpd | exception: Failed to read mixer for 'Global ALSA->Pulse stream': failed to attach to pulse: Connection refused ``` @@ -197,15 +203,20 @@ mpd | exception: Failed to read mixer for 'Global ALSA->Pulse stream': fail To fix the issue, try the following. 1. Stop your Pulseaudio service - ``` + + ```bash brew service stop pulseaudio ``` + 2. Start Pulseaudio with this command - ``` + + ```bash pulseaudio --load=module-native-protocol-tcp --exit-idle-time=-1 --daemon ``` + 3. Check if daemon is working - ``` + + ```bash pulseaudio --check -v ``` @@ -213,8 +224,6 @@ Everything else should have been set up properly as a [prerequisite](#mac) * [Source](https://gist.github.com/seongyongkim/b7d630a03e74c7ab1c6b53473b592712) - - #### Other error messages When starting the `mpd` container, you will see the following errors. @@ -265,12 +274,11 @@ jukebox | 319:server.py - jb.pub.server - host.timer.cputemp If you encounter the following error, refer to [Pulseaudio issues on Mac](#pulseaudio-issue-on-mac). -``` +```text jukebox | 21.12.2023 08:50:09 - 629:plugs.py - jb.plugin - MainThread - ERROR - Ignoring failed package load finalizer: 'volume.finalize()' jukebox | 21.12.2023 08:50:09 - 630:plugs.py - jb.plugin - MainThread - ERROR - Reason: NameError: name 'pulse_control' is not defined ``` - ## Appendix ### Individual Docker Image @@ -291,10 +299,10 @@ $ docker run -it --rm \ --name jukebox jukebox ``` -## Testing EVDEV devices in Linux +## Testing ``evdev`` devices in Linux + To test the [event device capabilities](../builders/event-devices.md) in docker, the device needs to be made available to the container. -### Linux Mount the device into the container by configuring the appropriate device in a `devices` section of the `jukebox` service in the docker compose file. For example: ```yaml @@ -304,9 +312,9 @@ Mount the device into the container by configuring the appropriate device in a ` - /dev/input/event3:/dev/input/event3 ``` - ### Resources + #### Mac * @@ -320,6 +328,8 @@ Mount the device into the container by configuring the appropriate device in a ` * * + + #### Audio * diff --git a/documentation/developers/documentation.md b/documentation/developers/documentation.md new file mode 100644 index 000000000..51cd8cda2 --- /dev/null +++ b/documentation/developers/documentation.md @@ -0,0 +1,39 @@ +# Documentation with Markdown + +We use markdown for documentation. Please add/update documentation in `documentation`. + +## Linting + +To ensure a consistent documentation we lint markdown files. + +We use [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) for linting. + +`.markdownlint-cli2.yaml` configures linting consistently for the Github Action, the pre-commit hook, manual linting and the [markdownlint extension](https://github.com/DavidAnson/vscode-markdownlint) for Visual Studio Code. + +You can start a manual check, if you call `run_markdownlint.sh`. + +If markdown files are changed and the pre-commit hook is enabled, `run_markdownlint.sh` is triggered on commits. + +After creating a PR or pushing to the repo a Github Action triggers the linter, if markdown files are changed (see `.github/workflows/markdown_v3.yml`). + +### Disabling Rules + +> [!NOTE] +> Please use disabling rules with caution and always try to fix the violation first. + +A few rules are globally disabled in `.markdownlint-cli2.yaml` (see section `config`). + +If you want to disable a rule for a specific section of a markdown file you can use + +```markdown + +section where MD010 should be ignored + +``` + +### References + +* +* Rules: + * + * diff --git a/documentation/developers/rfid/README.md b/documentation/developers/rfid/README.md index 0b2df4db3..f0db4fd6a 100644 --- a/documentation/developers/rfid/README.md +++ b/documentation/developers/rfid/README.md @@ -11,4 +11,3 @@ * [Generic Readers without HID (NFCpy)](generic_nfcpy.md) * [Mock Reader](mock_reader.md) * [Template Reader](template_reader.md) - diff --git a/documentation/developers/rfid/generic_nfcpy.md b/documentation/developers/rfid/generic_nfcpy.md index 76de98d88..27c6ececb 100644 --- a/documentation/developers/rfid/generic_nfcpy.md +++ b/documentation/developers/rfid/generic_nfcpy.md @@ -11,13 +11,14 @@ driver, and thus cannot be used with the [genericusb](genericusb.md) module. Als > The setup will do this automatically, so make sure the device is connected > before running the [RFID reader configuration tool](../coreapps.md#RFID-Reader). -# Configuration +## Configuration -The installation script will scan for compatible devices and will assist in configuration. +The installation script will scan for compatible devices and will assist in configuration. By setting `rfid > readers > generic_nfcpy > config > device_path` in `shared/settings/rfid.yaml` you can override the device location. By specifying an explicit device location it is possible to use multiple readers compatible with NFCpy. Example configuration for a usb-device with vendor ID 072f and product ID 2200: + ```yaml rfid: readers: @@ -33,4 +34,4 @@ rfid: alias: pause ``` -For possible values see the `path` parameter in this [nfcpy documentation](https://nfcpy.readthedocs.io/en/latest/modules/clf.html#nfc.clf.ContactlessFrontend.open) \ No newline at end of file +For possible values see the `path` parameter in this [nfcpy documentation](https://nfcpy.readthedocs.io/en/latest/modules/clf.html#nfc.clf.ContactlessFrontend.open) diff --git a/documentation/developers/rfid/mfrc522_spi.md b/documentation/developers/rfid/mfrc522_spi.md index 8a04f729e..363df3836 100644 --- a/documentation/developers/rfid/mfrc522_spi.md +++ b/documentation/developers/rfid/mfrc522_spi.md @@ -57,7 +57,8 @@ If true all card read-outs will be logged, even when card is permanently on read The following pin-out is for the default SPI Bus 0 on Raspberry Pins. -*MFRC522 default wiring (spi_bus=0, spi_ce=0)* +### MFRC522 default wiring (spi_bus=0, spi_ce=0) + |Pin Board Name |Function |RPI GPIO |RPI Pin | |----------------|----------|----------|---------| |SDA |CE |GPIO8 |24 | diff --git a/documentation/developers/rfid/pn532_i2c.md b/documentation/developers/rfid/pn532_i2c.md index d60cb2e54..33b7e3f51 100644 --- a/documentation/developers/rfid/pn532_i2c.md +++ b/documentation/developers/rfid/pn532_i2c.md @@ -29,7 +29,7 @@ You can usually pick up a board at ## Board Connections -*Default wiring* +### Default wiring | PN532 | RPI GPIO | RPI Pin | |-------|--------------|---------| @@ -45,9 +45,9 @@ PI's own voltage regulator. ## Jumpers -*Jumper settings for I2C protocol* +### Jumper settings for I2C protocol -Jumper | Position --------|---------- -SEL0 | ON -SEL1 | OFF +| Jumper | Position | +|--------|----------| +|SEL0 | ON | +|SEL1 | OFF | diff --git a/documentation/developers/rfid/template_reader.md b/documentation/developers/rfid/template_reader.md index 5b8458691..e02f56c69 100644 --- a/documentation/developers/rfid/template_reader.md +++ b/documentation/developers/rfid/template_reader.md @@ -1,9 +1,8 @@ # Template Reader -*Template for creating and integrating a new RFID Reader* - > [!NOTE] +> Template for creating and integrating a new RFID Reader. > For developers only This template provides the skeleton API for a new Reader. If you follow diff --git a/documentation/developers/webapp.md b/documentation/developers/webapp.md index 2e8504337..0406566fa 100644 --- a/documentation/developers/webapp.md +++ b/documentation/developers/webapp.md @@ -19,7 +19,7 @@ sudo apt-get -y update && sudo apt-get -y install nodejs The Web App is a React application based on [Create React App](https://create-react-app.dev/). To start a development server, run the following command: -``` +```bash cd ~/RPi-Jukebox-RFID/src/webapp npm install # Just the first time or when dependencies change npm start @@ -37,12 +37,14 @@ cd ~/RPi-Jukebox-RFID/src/webapp; \ After a successfull build you might need to restart the web server. -``` +```bash sudo systemctl restart nginx.service ``` ## Known Issues while building + + ### JavaScript heap out of memory While (re-) building the Web App, you get the following output: @@ -71,6 +73,7 @@ Use the [provided script](#build-the-web-app) to rebuild the Web App. It sets th If you need to run the commands manually, make sure to have enough memory available (min. 512 MB). The following commands might help. Set the swapsize to 512 MB (and deactivate swapfactor). Adapt accordingly if you have a SD Card with small capacity. + ```bash sudo dphys-swapfile swapoff sudo sed -i "s|.*CONF_SWAPSIZE=.*|CONF_SWAPSIZE=512|g" /etc/dphys-swapfile @@ -80,6 +83,7 @@ sudo dphys-swapfile swapon ``` Set Node's maximum amount of memory. Memory must be available. + ``` bash export NODE_OPTIONS=--max-old-space-size=512 npm run build @@ -105,7 +109,6 @@ Node tried to allocate more memory than available on the system. See [JavaScript heap out of memory](#javascript-heap-out-of-memory) - ### Client network socket disconnected ``` {.bash emphasize-lines="8,9"} @@ -122,12 +125,12 @@ npm ERR! network 'proxy' config is set properly. See: 'npm help config' #### Reason -The network connection is too slow or has issues. -This tends to happen on `armv6l` devices where building takes significantly more time due to limited resources. +The network connection is too slow or has issues. +This tends to happen on `armv6l` devices where building takes significantly more time due to limited resources. #### Solution -Try to use an ethernet connection. A reboot and/or running the script multiple times might also help ([Build produces EOF errors](#build-produces-eof-errors) might occur). +Try to use an ethernet connection. A reboot and/or running the script multiple times might also help ([Build produces EOF errors](#build-produces-eof-errors) might occur). If the error still persists, try to raise the timeout for npm package resolution. @@ -144,6 +147,8 @@ A previous run failed during installation and left a package corrupted. #### Solution Remove the mode packages and rerun again the script. + ``` {.bash emphasize-lines="8,9"} rm -rf node_modules ``` + diff --git a/run_markdownlint.sh b/run_markdownlint.sh new file mode 100755 index 000000000..0f890590e --- /dev/null +++ b/run_markdownlint.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Runner script to ensure +# - independent from working directory + +# Change working directory to project root +SOURCE=${BASH_SOURCE[0]} +SCRIPT_DIR="$(dirname "$SOURCE")" +PROJECT_ROOT="$SCRIPT_DIR" +cd "$PROJECT_ROOT" || { echo "Could not change directory"; exit 1; } + +# Run markdownlint-cli2 +./src/webapp/node_modules/.bin/markdownlint-cli2 --config .markdownlint-cli2.yaml "#node_modules" || { echo "ERROR: markdownlint-cli2 not found"; exit 1; } diff --git a/src/webapp/package-lock.json b/src/webapp/package-lock.json index 814090555..218e67ab7 100644 --- a/src/webapp/package-lock.json +++ b/src/webapp/package-lock.json @@ -28,6 +28,9 @@ "react-scripts": "^5.0.1", "url": "^0.11.3", "uuid": "^9.0.1" + }, + "devDependencies": { + "markdownlint-cli2": "^0.12.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -4042,6 +4045,18 @@ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" }, + "node_modules/@sindresorhus/merge-streams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", + "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -12284,6 +12299,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -12525,6 +12546,15 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -12663,11 +12693,165 @@ "tmpl": "1.0.5" } }, + "node_modules/markdown-it": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.0.0.tgz", + "integrity": "sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.0.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/markdownlint": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.33.0.tgz", + "integrity": "sha512-4lbtT14A3m0LPX1WS/3d1m7Blg+ZwiLq36WvjQqFGsX3Gik99NV+VXp/PW3n+Q62xyPdbvGOCfjPqjW+/SKMig==", + "dev": true, + "dependencies": { + "markdown-it": "14.0.0", + "markdownlint-micromark": "0.1.8" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli2/-/markdownlint-cli2-0.12.1.tgz", + "integrity": "sha512-RcK+l5FjJEyrU3REhrThiEUXNK89dLYNJCYbvOUKypxqIGfkcgpz8g08EKqhrmUbYfYoLC5nEYQy53NhJSEtfQ==", + "dev": true, + "dependencies": { + "globby": "14.0.0", + "jsonc-parser": "3.2.0", + "markdownlint": "0.33.0", + "markdownlint-cli2-formatter-default": "0.0.4", + "micromatch": "4.0.5", + "yaml": "2.3.4" + }, + "bin": { + "markdownlint-cli2": "markdownlint-cli2.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli2-formatter-default": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.4.tgz", + "integrity": "sha512-xm2rM0E+sWgjpPn1EesPXx5hIyrN2ddUnUwnbCsD/ONxYtw3PX6LydvdH6dciWAoFDpwzbHM1TO7uHfcMd6IYg==", + "dev": true, + "peerDependencies": { + "markdownlint-cli2": ">=0.0.4" + } + }, + "node_modules/markdownlint-cli2/node_modules/globby": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", + "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", + "dev": true, + "dependencies": { + "@sindresorhus/merge-streams": "^1.0.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdownlint-cli2/node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "dev": true, + "engines": { + "node": ">= 14" + } + }, + "node_modules/markdownlint-micromark": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.8.tgz", + "integrity": "sha512-1ouYkMRo9/6gou9gObuMDnvZM8jC/ly3QCFQyoSPCS2XV1ZClU0xpKbL1Ar3bWWRT1RnBZkWUEiNKrI2CwiBQA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, "node_modules/mdn-data": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -14889,6 +15073,15 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -17220,6 +17413,12 @@ "node": ">=4.2.0" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -17280,6 +17479,18 @@ "node": ">=4" } }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", diff --git a/src/webapp/package.json b/src/webapp/package.json index 115b66852..1619a8c60 100644 --- a/src/webapp/package.json +++ b/src/webapp/package.json @@ -47,5 +47,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "markdownlint-cli2": "^0.12.1" } }