diff --git a/.gitignore b/.gitignore index 04d9c5d32..593e3b75b 100755 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,8 @@ settings/Playlists_Folders_Path settings/rfid_trigger_play.conf settings/Second_Swipe settings/ShowCover +settings/sync-shared.conf +settings/sync-shared-enabled settings/version htdocs/config.php scripts/deviceName.txt diff --git a/components/synchronisation/sync-shared/README.md b/components/synchronisation/sync-shared/README.md new file mode 100644 index 000000000..d55b61b0c --- /dev/null +++ b/components/synchronisation/sync-shared/README.md @@ -0,0 +1,61 @@ +# Synchronize shared files from a server + +This component activates a synchronisation from a server to the Phoniebox for the shared folders 'shortcuts' and 'audiofolders'. +It allows to manage the shortcuts and audiofiles of one to many Phonieboxes in a central place (e.g. NAS, one main Phoniebox, ...) in the network, but keeps the possibility to play audio offline once the data where synced. + +The synchronisation can be initiated as a "full-sync" command and optionally on every RFID scan for the particular CardID (and corresponding audiofolder). +For the "full-sync" bind a CardId to the command "SYNCSHAREDFULL". +For the "RFID scan sync" feature, activate the option in the configuration. There is also a command to toggle the activation of the "RFID scan sync" feature via CardId (bind to command "SYNCSHAREDONRFIDSCANTOGGLE"). + +## Synchronisation + +The synchronisation will be FROM a server TO the Phoniebox, overriding existing files. So configuration of audiofiles / -folders made locally will be lost after sync. +If you want to make the initial setup e.g. via WebUi copy the files and use it as a base for the server. +The "folder.conf" files will be synced if present on the server, but not delete if not (they are automatically generated on playback). + +To access the files on the server two modes are supported: SSH or MOUNT. +Please make sure you have the correct access rights for the source and use key-based authentication for SSH. + +### RFID scan sync +If the feature "RFID scan sync" is activated, there will be a check on every RFID scan against the server if a matching shortcut and audiofolder is found and the changes will be transfered. +The playback will be delayed for the time the data are transfered (see "SYNCSHAREDFULL" to use a full-sync if a lot of new files have been added). +If the server is not reachable the check will be aborted after the timeout. So an unreachable server will cause a delay (see command "SYNCSHAREDONRFIDSCANTOGGLE" to toggle activation state). +Deleted shortcuts / audiofolders (not the contained items) will not be purged locally if deleted on remote. This is also true for changed shortcuts (the old audiofolder / -files will remain). To also delete not existing items us a "full-sync". + +## Installation + +Run the 'install-sync-shared.sh' script. This will install all required packages and rights. +Please configure all settings according to your setup. + + +## Configuration + +If your configuration has changed, run the script 'change_configuration.sh' to update the settings. This lets you also deactivate this feature. +You may also change the settings in the according files directly. + +### Settings: + +**{INSTALLATION_ROOT}/settings/sync-shared-enabled** + +Holds the activation state of this feature. Values are "TRUE" or "FALSE" + + +**{INSTALLATION_ROOT}/settings/sync-shared.conf** + +SYNCSHAREDMODE: The mode to access the server files. SSH or MOUNT + +SYNCSHAREDREMOTESSHUSER: The username if SSH mode is used. + +SYNCSHAREDREMOTESERVER: The IP or hostname of the server (used to check connectivity and SSH mode). e.g. "192.168.0.2" or "myhomeserver.local" + +SYNCSHAREDREMOTEPORT: The port of the server (used to check connectivity and SSH mode). e.g. "80" or "22" + +SYNCSHAREDREMOTETIMOUT: The timeout to reach the server (in seconds) (used to check connectivity). e.g. 1 + +SYNCSHAREDREMOTEPATH: The path to the shared files to sync (without trailing slash) (remote path for SSH mode or local path for MOUNT mode). e.g. "/mnt/Phoniebox" + +SYNCSHAREDONRFIDSCAN: Holds the activation state of the optional feature "RFID scan sync". Values are "TRUE" or "FALSE" + + +## Special Thanks +inspired by [splitti - phoniebox_rsync](https://github.com/splitti/phoniebox_rsync) diff --git a/components/synchronisation/sync-shared/change-configuration.sh b/components/synchronisation/sync-shared/change-configuration.sh new file mode 100755 index 000000000..078c531dd --- /dev/null +++ b/components/synchronisation/sync-shared/change-configuration.sh @@ -0,0 +1,139 @@ +#!/bin/bash + +PATHDATA="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJROOTPATH="${PATHDATA}/../../.." +STATEFILE="${PROJROOTPATH}/settings/sync-shared-enabled" +CONFFILE="${PROJROOTPATH}/settings/sync-shared.conf" +SKIP_INITIAL_CHECK="$1" + + +############################################################# +# Functions + +set_activation() { + local SETTINGVALUE="$1" + + local SETTINGSTATE="activated" + if [ "$SETTINGVALUE" != "TRUE" ]; then + SETTINGSTATE="deactivated" + fi + + # Let global controls know this feature is enabled + echo -e "\nLet global controls know this feature is ${SETTINGSTATE}. (sync-shared-enabled -> ${SETTINGVALUE})" + + echo "$SETTINGVALUE" > "$STATEFILE" + sudo chgrp www-data "$STATEFILE" + sudo chmod 775 "$STATEFILE" +} + +init_settings() { + # Init config from sample if not present + if [ ! -f "$CONFFILE" ]; then + cp "${PATHDATA}/settings/sync-shared.conf.sample" "$CONFFILE" + # change the read/write so that later this might also be editable through the web app + sudo chgrp www-data "$CONFFILE" + sudo chmod 775 "$CONFFILE" + fi + . "$CONFFILE" +} + +set_setting() { + local SETTINGNAME="$1" + local SETTINGVALUE="$2" + + # check if value is set and not equal to the current settings value + if [ ! -z "$SETTINGVALUE" -a "${!SETTINGNAME}" != "$SETTINGVALUE" ]; then + sed -i "s|^${SETTINGNAME}=.*|${SETTINGNAME}=\"${SETTINGVALUE}\"|g" "$CONFFILE" + echo "New value: \"${SETTINGVALUE}\"" + fi +} + +read_setting() { + local SETTINGNAME="$1" + local TEXT="$2" + + local READ_PROMPT=$'\n'"${TEXT} Leave blank for no change." + READ_PROMPT="${READ_PROMPT}"$'\n'"Current value = \"${SETTINGNAME}\""$'\n' + + read -rp "$READ_PROMPT" response +} + +read_all_settings() { + + read_setting "$SYNCSHAREDMODE" "Choose synchronisation mode to access the server (m[ount]/s[sh])." + case "$response" in + [mM][oO][uU][nN][tT]|[mM][nN][tT]|[mM]) + response="MOUNT" + ;; + [sS][sS][hH]|[sS]) + response="SSH" + ;; + *) + # no change + ;; + esac + set_setting "SYNCSHAREDMODE" "$response" + + if [ "$response" == "SSH" ]; then + read_setting "$SYNCSHAREDREMOTESSHUSER" "Please enter SSH user." + set_setting "SYNCSHAREDREMOTESSHUSER" "$response" + fi + + read_setting "$SYNCSHAREDREMOTESERVER" "Please enter your servers adresse (IP/Hostname)." + set_setting "SYNCSHAREDREMOTESERVER" "$response" + + read_setting "$SYNCSHAREDREMOTEPORT" "Please enter your servers port." + set_setting "SYNCSHAREDREMOTEPORT" "$response" + + read_setting "$SYNCSHAREDREMOTETIMOUT" "Please enter the timeout to try to reach the server (in seconds)." + set_setting "SYNCSHAREDREMOTETIMOUT" "$response" + + read_setting "$SYNCSHAREDREMOTEPATH" "Please enter the path to the shared files to sync (without trailing slash)." + # Make sure paths dont have a trailing slash ({VAR%/}) + set_setting "SYNCSHAREDREMOTEPATH" "${response%/}" + + read_setting "$SYNCSHAREDONRFIDSCAN" "Do you want to activate the syncronisation on RFID scan (y[es]/n[o])." + case "$response" in + [yY][eE][sS]|[yY]) + response="TRUE" + ;; + [nN][oO]|[nN]) + response="FALSE" + ;; + *) + ;; + esac + set_setting "SYNCSHAREDONRFIDSCAN" "$response" +} + +############################################################# + +# If intial check is skipped, asume the component shall be activated +if [ -z "$SKIP_INITIAL_CHECK" ]; then + read -rp "Do you want to activate the sync-shared component? [Y/n] " response +else + response="yes" +fi + +case "$response" in + [nN][oO]|[nN]) + set_activation "FALSE" + ;; + *) + set_activation "TRUE" + + # Ensure start was intended + read -rp "Do you want to change the configuration? [Y/n] " response + case "$response" in + [nN][oO]|[nN]) + exit + ;; + *) + ;; + esac + init_settings + read_all_settings + ;; +esac + +echo -e "\nConfiguration finished" diff --git a/components/synchronisation/sync-shared/install-sync-shared.sh b/components/synchronisation/sync-shared/install-sync-shared.sh new file mode 100755 index 000000000..aa2f96e05 --- /dev/null +++ b/components/synchronisation/sync-shared/install-sync-shared.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Ensure start was intended +read -rp "Start installation? [Y/n] " response +case "$response" in + [nN][oO]|[nN]) + echo "Installation aborted..." + exit + ;; + *) + ;; +esac + +PATHDATA="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJROOTPATH="${PATHDATA}/../../.." + +# Ensure script is executable for everyone +sudo chmod ugo+rx "${PATHDATA}/sync-shared.sh" + +# Make sure required packages are installed +echo -e "\nChecking rsync package" +sudo apt install rsync -y +echo -e "\nChecking ssh package" +sudo apt install openssh-client -y + +"${PATHDATA}"/change-configuration.sh "SkipInitialCheck" + +echo -e "\n\nFINAL NOTE:\nPlease check README.md for further configuration" diff --git a/components/synchronisation/sync-shared/settings/sync-shared.conf.sample b/components/synchronisation/sync-shared/settings/sync-shared.conf.sample new file mode 100755 index 000000000..f77ad8289 --- /dev/null +++ b/components/synchronisation/sync-shared/settings/sync-shared.conf.sample @@ -0,0 +1,14 @@ +# The mode to access the server files. SSH or MOUNT +SYNCSHAREDMODE="MOUNT" +# The username if SSH mode is used +SYNCSHAREDREMOTESSHUSER="" +# The IP or hostname of the server (used to check connectivity and SSH mode) +SYNCSHAREDREMOTESERVER="" +# The port of the server (used to check connectivity and SSH mode) +SYNCSHAREDREMOTEPORT="" +# The timeout to reach the server (in seconds) (used to check connectivity) +SYNCSHAREDREMOTETIMOUT="1" +# The path to the shared files to sync (without trailing slash) (remote path for SSH mode or local path for MOUNT mode) +SYNCSHAREDREMOTEPATH="" +# Holds the activation state of the optional feature "RFID scan sync" +SYNCSHAREDONRFIDSCAN="FALSE" diff --git a/components/synchronisation/sync-shared/sync-shared.sh b/components/synchronisation/sync-shared/sync-shared.sh new file mode 100755 index 000000000..dca8f07bf --- /dev/null +++ b/components/synchronisation/sync-shared/sync-shared.sh @@ -0,0 +1,324 @@ +#!/bin/bash + +# This script synchronises shortcuts and/or audiofolders from a server to the local storage. + +# VALID COMMANDS: +# shortcuts (with -i) +# audiofolders (with -d) +# full +# changeOnRfidScan(with -v=on | off | toogle) + +# USAGE EXAMPLES: +# +# sync shortcuts: +# ./sync_shared.sh -c=shortcuts -i=xxx +# +# sync audiofolders: +# ./sync_shared.sh -c=audiofolders -d=xxx +# +# sync full: +# ./sync_shared.sh -c=full +# +# toggle sync OnRfidScan: +# ./sync_shared.sh -c=changeOnRfidScan -v=toggle + +# Set the date and time of now +NOW=`date +%Y-%m-%d.%H:%M:%S` + +# The absolute path to the folder which contains all the scripts. +# Unless you are working with symlinks, leave the following line untouched. +PATHDATA="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJROOTPATH="${PATHDATA}/../../.." + +############################################################# +# $DEBUG TRUE|FALSE +# Read debug logging configuration file +. "${PROJROOTPATH}"/settings/debugLogging.conf + +if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "########### SCRIPT sync_shared.sh (${NOW}) ##" >> "${PROJROOTPATH}"/logs/debug.log; fi + +####################### +# Activation status of component sync-shared +SYNCSHAREDENABLED="FALSE" +if [ -f "${PROJROOTPATH}/settings/sync-shared-enabled" ]; then + SYNCSHAREDENABLED=`cat "${PROJROOTPATH}/settings/sync-shared-enabled"` +fi + + +if [ "$SYNCSHAREDENABLED" != "TRUE" ]; then + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: disabled" >> "${PROJROOTPATH}"/logs/debug.log; fi + +else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: enabled" >> "${PROJROOTPATH}"/logs/debug.log; fi + + ############################################################# + # Read global configuration file + if [ ! -f "${PROJROOTPATH}/settings/global.conf" ]; then + echo "Global settingsfile does not exist. Please call the script from a defined entrypoint" + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Global settingsfile does not exist. Please call the script from a defined entrypoint" >> "${PROJROOTPATH}"/logs/debug.log; fi + exit + fi + . "${PROJROOTPATH}"/settings/global.conf + + ############################################################# + # Read configuration file + CONFFILE="${PROJROOTPATH}/settings/sync-shared.conf" + if [ ! -f "$CONFFILE" ]; then + echo "Settingsfile does not exist. Please read ${PATHDATA}/README.md to set configuration" + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Settingsfile does not exist. Please read ${PATHDATA}/README.md to set configuration" >> "${PROJROOTPATH}"/logs/debug.log; fi + exit + fi + . "$CONFFILE" + + ############################################################# + # Get args from command line (see Usage above) + # Read the args passed on by the command line + # see following file for details: + . "${PROJROOTPATH}"/scripts/inc.readArgsFromCommandLine.sh + + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "VAR COMMAND: ${COMMAND}" >> "${PROJROOTPATH}"/logs/debug.log; fi + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "VAR CARDID: ${CARDID}" >> "${PROJROOTPATH}"/logs/debug.log; fi + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "VAR FOLDER: ${FOLDER}" >> "${PROJROOTPATH}"/logs/debug.log; fi + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "VAR VALUE: ${VALUE}" >> "${PROJROOTPATH}"/logs/debug.log; fi + + ############################################################# + # Set local vars after confs are read + # Make sure paths dont have a trailing slash ({VAR%/}) + SYNCSHAREDREMOTEPATH="${SYNCSHAREDREMOTEPATH%/}" + SYNCSHORTCUTSPATH="${SYNCSHAREDREMOTEPATH}/shortcuts" + SYNCAUDIOFOLDERSPATH="${SYNCSHAREDREMOTEPATH}/audiofolders" + + LOCAL_SHORTCUTSPATH="${PROJROOTPATH}/shared/shortcuts" + LOCAL_AUDIOFOLDERSPATH="${AUDIOFOLDERSPATH%/}" + + ############################################################# + # Functions + + # Check if the sync mode is SSH + is_mode_ssh() { + [ "$SYNCSHAREDMODE" == "SSH" ] + } + + # Executes the command for the current mode + exec_for_mode() { + if is_mode_ssh ; then + # Quote every param to deal with whitespaces in paths + local quotedparams + for var in "$@" + do + quotedparams="${quotedparams} '${var}'" + done + + # Execute remote via SSH + ssh "$SYNCSHAREDREMOTESSHUSER"@"$SYNCSHAREDREMOTESERVER" -p "$SYNCSHAREDREMOTEPORT" "$quotedparams" + else + # Execute local on mount + "$@" + fi + } + + # Check if server is reachable on port + is_server_reachable() { + return `nc -z "$SYNCSHAREDREMOTESERVER" -w "$SYNCSHAREDREMOTETIMOUT" "$SYNCSHAREDREMOTEPORT"` + } + + # Check if first parameter ends with the character second parameter + endswith() { + case "$1" in *"$2") true;; *) false;; esac; + } + + # Sync all files from source to destination + # Some special options are needed as the 'folder.conf' file will be generated on playback. + # Explanation for rsync options: + # "--itemize-changes" print a summary of copied files. Used for determination if files where changed (empty if no syncing performed). Useful for debug.log + # "--safe-links" ignore symlinks that point outside the tree + # "--times" preserve modification times from source. Recommended option to efficiently identify unchanged files + # "--omit-dir-times" ignore modification time on dirs (see --times). Needed to ignore the creation of 'folder.conf' which alters the modification time of dirs + # "--delete" delete files that no longer exist in source + # "--prune-empty-dirs" delete empty dirs (incl. subdirs) + # "--filter='-rp folder.conf' exclude (option '-') 'folder.conf' file from deletion on receiving side (option 'r'). Delete anyway if folder will be deleted (option 'p' (perishable)). + # "--exclude='placeholder' exclude 'placeholder' file from syncing, especially deletion + # "--exclude='.*/' exclude special 'hidden' folders from syncing + # "--exclude='@*/' exclude special folders from syncing + sync_from_server() { + local src_path="$1" + local dst_path="$2" + local update_db="$3" + + if is_mode_ssh ; then + # Quote source path to deal with whitespaces in paths + src_path="'${src_path}'" + + local ssh_port=(-e "ssh -p ${SYNCSHAREDREMOTEPORT}") + local ssh_conn="${SYNCSHAREDREMOTESSHUSER}@${SYNCSHAREDREMOTESERVER}:" + fi + + if endswith "$dst_path" "/" ; then + mkdir -p "$dst_path" + fi + rsync_changes=$(rsync --compress --recursive --itemize-changes --safe-links --times --omit-dir-times --delete --prune-empty-dirs --filter='-rp folder.conf' --exclude='placeholder' --exclude='.*/' --exclude='@*/' "${ssh_port[@]}" "${ssh_conn}""${src_path}" "${dst_path}") + + if [ $? -eq 0 -a -n "$rsync_changes" ]; then + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo -e "Sync: executed rsync \n${rsync_changes}" >> "${PROJROOTPATH}"/logs/debug.log; fi + + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: files copied. change access of files" >> "${PROJROOTPATH}"/logs/debug.log; fi + change_access "$dst_path" "www-data" "775" + + if [ ! -z "$update_db" ]; then + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: update database" >> "${PROJROOTPATH}"/logs/debug.log; fi + # if spotify edition is installed, update via mopidy as mpc update doesnt work + if [ "$EDITION" == "plusSpotify" ]; then + # don't stop / start service (like in payout_controls scan) as all mpd calls after will fail + # (or an artifical sleep time would be needed to make sure mpd is started) + sudo mopidyctl local scan > /dev/null 2>&1 + else + mpc update --wait > /dev/null 2>&1 + fi + fi + + else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: nothing changed" >> "${PROJROOTPATH}"/logs/debug.log; fi + fi + } + + # Sync shortcut for CARDID + handle_shortcuts() { + if [ "$SYNCSHAREDONRFIDSCAN" == "TRUE" ]; then + if is_server_reachable ; then + + if exec_for_mode [ ! -d "$SYNCSHORTCUTSPATH" ] ; then + exec_for_mode mkdir "$SYNCSHORTCUTSPATH" + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Folder ${SYNCSHORTCUTSPATH} does not exist. created" >> "${PROJROOTPATH}"/logs/debug.log; fi + + elif exec_for_mode [ -f "${SYNCSHORTCUTSPATH}/${CARDID}" ] ; then + sync_from_server "${SYNCSHORTCUTSPATH}/${CARDID}" "${LOCAL_SHORTCUTSPATH}/${CARDID}" + + else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Shortcut for $CARDID not found in REMOTE $SYNCSHORTCUTSPATH" >> "${PROJROOTPATH}"/logs/debug.log; fi + fi + + else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Server is NOT reachable" >> "${PROJROOTPATH}"/logs/debug.log; fi + fi + + else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Sync on RFID scan deactivated" >> "${PROJROOTPATH}"/logs/debug.log; fi + fi + } + + # Sync audiofolder FOLDER + handle_audiofolders() { + if [ "$SYNCSHAREDONRFIDSCAN" == "TRUE" ]; then + if is_server_reachable ; then + + if exec_for_mode [ ! -d "$SYNCAUDIOFOLDERSPATH" ] ; then + exec_for_mode mkdir "$SYNCAUDIOFOLDERSPATH" + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Folder ${SYNCAUDIOFOLDERSPATH} does not exist. created" >> "${PROJROOTPATH}"/logs/debug.log; fi + + elif exec_for_mode [ -d "${SYNCAUDIOFOLDERSPATH}/${FOLDER}" ] ; then + sync_from_server "${SYNCAUDIOFOLDERSPATH}/${FOLDER}/" "${LOCAL_AUDIOFOLDERSPATH}/${FOLDER}/" "UpdateDB" + + else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Folder $FOLDER not found in REMOTE $SYNCAUDIOFOLDERSPATH" >> "${PROJROOTPATH}"/logs/debug.log; fi + fi + + else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Server is NOT reachable" >> "${PROJROOTPATH}"/logs/debug.log; fi + fi + + else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Sync on RFID scan deactivated" >> "${PROJROOTPATH}"/logs/debug.log; fi + fi + } + + # Sync full (shortcuts and audiofolders) + handle_full() { + if is_server_reachable ; then + + if exec_for_mode [ ! -d "$SYNCSHORTCUTSPATH" ] ; then + exec_for_mode mkdir "$SYNCSHORTCUTSPATH" + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Folder ${SYNCSHORTCUTSPATH} does not exist. created" >> "${PROJROOTPATH}"/logs/debug.log; fi + else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Folder ${SYNCSHORTCUTSPATH}" >> "${PROJROOTPATH}"/logs/debug.log; fi + sync_from_server "${SYNCSHORTCUTSPATH}/" "${LOCAL_SHORTCUTSPATH}/" + + fi + + if exec_for_mode [ ! -d "$SYNCAUDIOFOLDERSPATH" ] ; then + exec_for_mode mkdir "$SYNCAUDIOFOLDERSPATH" + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Folder ${SYNCAUDIOFOLDERSPATH} does not exist. created" >> "${PROJROOTPATH}"/logs/debug.log; fi + else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Folder ${SYNCAUDIOFOLDERSPATH}" >> "${PROJROOTPATH}"/logs/debug.log; fi + sync_from_server "${SYNCAUDIOFOLDERSPATH}/" "${LOCAL_AUDIOFOLDERSPATH}/" "UpdateDB" + + fi + + else + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Server is NOT reachable" >> "${PROJROOTPATH}"/logs/debug.log; fi + fi + } + + # Change setting for Sync on RFID scan + handle_changeOnRfidScan() { + case "$VALUE" in + on) + SYNCSHAREDONRFIDSCAN_NEW="TRUE" + ;; + off) + SYNCSHAREDONRFIDSCAN_NEW="FALSE" + ;; + toggle) + if [ "$SYNCSHAREDONRFIDSCAN" == "TRUE" ]; then + SYNCSHAREDONRFIDSCAN_NEW="FALSE" + else + SYNCSHAREDONRFIDSCAN_NEW="TRUE" + fi + ;; + *) + echo "Unknown VALUE ${VALUE} for COMMAND ${COMMAND}" + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Unknown VALUE ${VALUE} for COMMAND ${COMMAND}" >> "${PROJROOTPATH}"/logs/debug.log; fi + ;; + esac + + if [ ! -z "${SYNCSHAREDONRFIDSCAN_NEW}" ]; then + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Sync: Set SYNCSHAREDONRFIDSCAN to ${SYNCSHAREDONRFIDSCAN_NEW}" >> "${PROJROOTPATH}"/logs/debug.log; fi + sed -i "s|^SYNCSHAREDONRFIDSCAN=.*|SYNCSHAREDONRFIDSCAN=\"${SYNCSHAREDONRFIDSCAN_NEW}\"|g" "$CONFFILE" + fi + } + + # Change access of file or dir + # only changes group as the user should be correctly taken from caller context (logged in user or service) + change_access() { + local file_or_dir="$1" + local group="$2" + local mod="$3" + + sudo chgrp -R "$group" "$file_or_dir" + sudo chmod -R "$mod" "$file_or_dir" + } + + ############################################################# + + ############################################################# + # Main switch + case "$COMMAND" in + shortcuts) + handle_shortcuts + ;; + audiofolders) + handle_audiofolders + ;; + full) + handle_full + ;; + changeOnRfidScan) + handle_changeOnRfidScan + ;; + *) + echo "Unknown COMMAND {$COMMAND}" + if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "Unknown COMMAND ${COMMAND} CARDID ${CARDID} FOLDER ${FOLDER} VALUE ${VALUE}" >> "${PROJROOTPATH}"/logs/debug.log; fi + ;; + esac + +fi +if [ "${DEBUG_sync_shared_sh}" == "TRUE" ]; then echo "########### SCRIPT sync_shared.sh ##" >> "${PROJROOTPATH}"/logs/debug.log; fi diff --git a/htdocs/inc.header.php b/htdocs/inc.header.php index 2b101cf69..858e17aac 100755 --- a/htdocs/inc.header.php +++ b/htdocs/inc.header.php @@ -75,6 +75,7 @@ "DEBUG_rfid_trigger_play_sh", "DEBUG_shuffle_play_sh", "DEBUG_single_play_sh", +"DEBUG_sync_shared_sh", ); $debugOptions = array("TRUE", "FALSE"); diff --git a/scripts/playout_controls.sh b/scripts/playout_controls.sh index 0bc6a3a67..a02ba9fd5 100755 --- a/scripts/playout_controls.sh +++ b/scripts/playout_controls.sh @@ -73,6 +73,8 @@ NOW=`date +%Y-%m-%d.%H:%M:%S` # readwifiipoverspeaker # bluetoothtoggle # switchaudioiface +# sharedsyncfull +# sharedsyncchangeonrfidscan # The absolute path to the folder which contains all the scripts. # Unless you are working with symlinks, leave the following line untouched. @@ -285,7 +287,7 @@ case $COMMAND in # schedule shutdown after VALUE minutes echo "${PATHDATA}/playout_controls.sh -c=shutdownsilent" | at -q q now + ${VALUE} minute fi - ;; + ;; reboot) if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo " ${COMMAND}" >> ${PATHDATA}/../logs/debug.log; fi ${PATHDATA}/resume_play.sh -c=savepos && mpc clear @@ -1136,6 +1138,12 @@ case $COMMAND in dbg "Command requires \"amixer\" as volume manager." fi ;; + sharedsyncfull) + $PATHDATA/../components/synchronisation/sync-shared/sync-shared.sh -c=full + ;; + sharedsyncchangeonrfidscan) + $PATHDATA/../components/synchronisation/sync-shared/sync-shared.sh -c=changeOnRfidScan -v="$VALUE" + ;; *) echo Unknown COMMAND $COMMAND VALUE $VALUE if [ "${DEBUG_playout_controls_sh}" == "TRUE" ]; then echo "Unknown COMMAND ${COMMAND} VALUE ${VALUE}" >> ${PATHDATA}/../logs/debug.log; fi diff --git a/scripts/rfid_trigger_play.sh b/scripts/rfid_trigger_play.sh index 0b2700dee..8e56c075f 100755 --- a/scripts/rfid_trigger_play.sh +++ b/scripts/rfid_trigger_play.sh @@ -63,6 +63,14 @@ fi # see following file for details: . $PATHDATA/inc.readArgsFromCommandLine.sh +####################### +# Activation status of component sync-shared-from-server +SYNCSHAREDENABLED="FALSE" +if [ -f $PATHDATA/../settings/sync-shared-enabled ]; then + SYNCSHAREDENABLED=`cat $PATHDATA/../settings/sync-shared-enabled` +fi +if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "Sync: SYNCSHAREDENABLED=$SYNCSHAREDENABLED" >> $PATHDATA/../logs/debug.log; fi + ################################################################## # Check if we got the card ID or the audio folder from the prompt. # Sloppy error check, because we assume the best. @@ -306,12 +314,23 @@ if [ "$CARDID" ]; then $CMDBLUETOOTHTOGGLE) $PATHDATA/playout_controls.sh -c=bluetoothtoggle -v=toggle ;; + $SYNCSHAREDFULL) + $PATHDATA/playout_controls.sh -c=sharedsyncfull + ;; + $SYNCSHAREDONRFIDSCANTOGGLE) + $PATHDATA/playout_controls.sh -c=sharedsyncchangeonrfidscan -v=toggle + ;; *) # We checked if the card was a special command, seems it wasn't. # Now we expect it to be a trigger for one or more audio file(s). # Let's look at the ID, write a bit of log information and then try to play audio. + # If enabled sync shortcut $CARDID + if [ "${SYNCSHAREDENABLED}" == "TRUE" ]; then + $PATHDATA/../components/synchronisation/sync-shared/sync-shared.sh -c=shortcuts -i="$CARDID" + fi + # Look for human readable shortcut in folder 'shortcuts' # check if CARDID has a text file by the same name - which would contain the human readable folder name if [ -f $PATHDATA/../shared/shortcuts/$CARDID ] @@ -345,172 +364,179 @@ fi if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "# Attempting to play: $AUDIOFOLDERSPATH/$FOLDER" >> $PATHDATA/../logs/debug.log; fi if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "# Type of play \$VALUE: $VALUE" >> $PATHDATA/../logs/debug.log; fi -# check if -# - $FOLDER is not empty (! -z "$FOLDER") -# - AND (-a) -# - and points to existing directory (-d "${AUDIOFOLDERSPATH}/${FOLDER}") -if [ ! -z "$FOLDER" -a -d "${AUDIOFOLDERSPATH}/${FOLDER}" ]; then - - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "\$FOLDER set, not empty and dir exists: ${AUDIOFOLDERSPATH}/${FOLDER}" >> $PATHDATA/../logs/debug.log; fi - - # if we play a folder the first time, add some sensible information to the folder.conf - if [ ! -f "${AUDIOFOLDERSPATH}/${FOLDER}/folder.conf" ]; then - # now we create a default folder.conf file by calling this script - # with the command param createDefaultFolderConf - # (see script for details) - # the $FOLDER would not need to be passed on, because it is already set in this script - # see inc.writeFolderConfig.sh for details - . $PATHDATA/inc.writeFolderConfig.sh -c=createDefaultFolderConf -d="${FOLDER}" - fi +# check if $FOLDER is not empty +if [ ! -z "$FOLDER" ]; then - # get the name of the last folder played. As mpd doesn't store the name of the last - # playlist, we have to keep track of it via the Latest_Folder_Played file - LASTFOLDER=$(cat $PATHDATA/../settings/Latest_Folder_Played) - LASTPLAYLIST=$(cat $PATHDATA/../settings/Latest_Playlist_Played) - # this might need to go? resume not working... echo ${FOLDER} > $PATHDATA/../settings/Latest_Folder_Played - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Var \$LASTFOLDER: $LASTFOLDER" >> $PATHDATA/../logs/debug.log; fi - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Var \$LASTPLAYLIST: $LASTPLAYLIST" >> $PATHDATA/../logs/debug.log; fi - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "Checking 'recursive' list? VAR \$VALUE: $VALUE" >> $PATHDATA/../logs/debug.log; fi - - if [ "$VALUE" == "recursive" ]; then - # set path to playlist - # replace subfolder slashes with " % " - PLAYLISTPATH="${PLAYLISTSFOLDERPATH}/${FOLDER//\//\ %\ }-%RCRSV%.m3u" - PLAYLISTNAME="${FOLDER//\//\ %\ }-%RCRSV%" - $PATHDATA/playlist_recursive_by_folder.php --folder "${FOLDER}" --list 'recursive' > "${PLAYLISTPATH}" - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "recursive? YES" >> $PATHDATA/../logs/debug.log; fi - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "$PATHDATA/playlist_recursive_by_folder.php --folder \"${FOLDER}\" --list 'recursive' > \"${PLAYLISTPATH}\"" >> $PATHDATA/../logs/debug.log; fi - else - # set path to playlist - # replace subfolder slashes with " % " - PLAYLISTPATH="${PLAYLISTSFOLDERPATH}/${FOLDER//\//\ %\ }.m3u" - PLAYLISTNAME="${FOLDER//\//\ %\ }" - $PATHDATA/playlist_recursive_by_folder.php --folder "${FOLDER}" > "${PLAYLISTPATH}" - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "recursive? NO" >> $PATHDATA/../logs/debug.log; fi - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "$PATHDATA/playlist_recursive_by_folder.php --folder \"${FOLDER}\" > \"${PLAYLISTPATH}\"" >> $PATHDATA/../logs/debug.log; fi + # If enabled sync audio folder $FOLDER + if [ "${SYNCSHAREDENABLED}" == "TRUE" ]; then + $PATHDATA/../components/synchronisation/sync-shared/sync-shared.sh -c=audiofolders -d="$FOLDER" fi - # Second Swipe value - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Var \$SECONDSWIPE: ${SECONDSWIPE}" >> $PATHDATA/../logs/debug.log; fi - # Playlist name - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Var \$PLAYLISTNAME: ${PLAYLISTNAME}" >> $PATHDATA/../logs/debug.log; fi - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Var \$LASTPLAYLIST: ${LASTPLAYLIST}" >> $PATHDATA/../logs/debug.log; fi - - # Setting a VAR to start "play playlist from start" - # This will be changed in the following checks "if this is the second swipe" - PLAYPLAYLIST=yes - - # Check if the second swipe happened - # - The same playlist is cued up ("$LASTPLAYLIST" == "$PLAYLISTNAME") - if [ "$LASTPLAYLIST" == "$PLAYLISTNAME" ] - then - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Second Swipe DID happen: \$LASTPLAYLIST == \$PLAYLISTNAME" >> $PATHDATA/../logs/debug.log; fi - - # check if - # - $SECONDSWIPE is set to toggle pause/play ("$SECONDSWIPE" == "PAUSE") - # - AND (-a) - # - check the length of the playlist, if =0 then it was cleared before, a state, which should only - # be possible after a reboot ($PLLENGTH -gt 0) - PLLENGTH=$(echo -e "status\nclose" | nc -w 1 localhost 6600 | grep -o -P '(?<=playlistlength: ).*') - if [ $PLLENGTH -eq 0 ] - then - # after a reboot we want to play the playlist once no matter what the setting is - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Take second wipe as first after fresh boot" >> $PATHDATA/../logs/debug.log; fi - elif [ "$SECONDSWIPE" == "PAUSE" -a $PLLENGTH -gt 0 ] - then - # The following involves NOT playing the playlist, so we set: - PLAYPLAYLIST=no + # check if $FOLDER points to existing directory + if [ -d "${AUDIOFOLDERSPATH}/${FOLDER}" ]; then + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "\$FOLDER not empty and dir exists: ${AUDIOFOLDERSPATH}/${FOLDER}" >> $PATHDATA/../logs/debug.log; fi + + # if we play a folder the first time, add some sensible information to the folder.conf + if [ ! -f "${AUDIOFOLDERSPATH}/${FOLDER}/folder.conf" ]; then + # now we create a default folder.conf file by calling this script + # with the command param createDefaultFolderConf + # (see script for details) + # the $FOLDER would not need to be passed on, because it is already set in this script + # see inc.writeFolderConfig.sh for details + . $PATHDATA/inc.writeFolderConfig.sh -c=createDefaultFolderConf -d="${FOLDER}" + fi + + # get the name of the last folder played. As mpd doesn't store the name of the last + # playlist, we have to keep track of it via the Latest_Folder_Played file + LASTFOLDER=$(cat $PATHDATA/../settings/Latest_Folder_Played) + LASTPLAYLIST=$(cat $PATHDATA/../settings/Latest_Playlist_Played) + # this might need to go? resume not working... echo ${FOLDER} > $PATHDATA/../settings/Latest_Folder_Played + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Var \$LASTFOLDER: $LASTFOLDER" >> $PATHDATA/../logs/debug.log; fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Var \$LASTPLAYLIST: $LASTPLAYLIST" >> $PATHDATA/../logs/debug.log; fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "Checking 'recursive' list? VAR \$VALUE: $VALUE" >> $PATHDATA/../logs/debug.log; fi + + if [ "$VALUE" == "recursive" ]; then + # set path to playlist + # replace subfolder slashes with " % " + PLAYLISTPATH="${PLAYLISTSFOLDERPATH}/${FOLDER//\//\ %\ }-%RCRSV%.m3u" + PLAYLISTNAME="${FOLDER//\//\ %\ }-%RCRSV%" + $PATHDATA/playlist_recursive_by_folder.php --folder "${FOLDER}" --list 'recursive' > "${PLAYLISTPATH}" + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "recursive? YES" >> $PATHDATA/../logs/debug.log; fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "$PATHDATA/playlist_recursive_by_folder.php --folder \"${FOLDER}\" --list 'recursive' > \"${PLAYLISTPATH}\"" >> $PATHDATA/../logs/debug.log; fi + else + # set path to playlist + # replace subfolder slashes with " % " + PLAYLISTPATH="${PLAYLISTSFOLDERPATH}/${FOLDER//\//\ %\ }.m3u" + PLAYLISTNAME="${FOLDER//\//\ %\ }" + $PATHDATA/playlist_recursive_by_folder.php --folder "${FOLDER}" > "${PLAYLISTPATH}" + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "recursive? NO" >> $PATHDATA/../logs/debug.log; fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "$PATHDATA/playlist_recursive_by_folder.php --folder \"${FOLDER}\" > \"${PLAYLISTPATH}\"" >> $PATHDATA/../logs/debug.log; fi + fi + + # Second Swipe value + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Var \$SECONDSWIPE: ${SECONDSWIPE}" >> $PATHDATA/../logs/debug.log; fi + # Playlist name + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Var \$PLAYLISTNAME: ${PLAYLISTNAME}" >> $PATHDATA/../logs/debug.log; fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Var \$LASTPLAYLIST: ${LASTPLAYLIST}" >> $PATHDATA/../logs/debug.log; fi + + # Setting a VAR to start "play playlist from start" + # This will be changed in the following checks "if this is the second swipe" + PLAYPLAYLIST=yes - STATE=$(echo -e "status\nclose" | nc -w 1 localhost 6600 | grep -o -P '(?<=state: ).*') - if [ $STATE == "play" ] + # Check if the second swipe happened + # - The same playlist is cued up ("$LASTPLAYLIST" == "$PLAYLISTNAME") + if [ "$LASTPLAYLIST" == "$PLAYLISTNAME" ] + then + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Second Swipe DID happen: \$LASTPLAYLIST == \$PLAYLISTNAME" >> $PATHDATA/../logs/debug.log; fi + + # check if + # - $SECONDSWIPE is set to toggle pause/play ("$SECONDSWIPE" == "PAUSE") + # - AND (-a) + # - check the length of the playlist, if =0 then it was cleared before, a state, which should only + # be possible after a reboot ($PLLENGTH -gt 0) + PLLENGTH=$(echo -e "status\nclose" | nc -w 1 localhost 6600 | grep -o -P '(?<=playlistlength: ).*') + if [ $PLLENGTH -eq 0 ] then - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " MPD playing, pausing the player" >> $PATHDATA/../logs/debug.log; fi - sudo $PATHDATA/playout_controls.sh -c=playerpause &>/dev/null - else - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "MPD not playing, start playing" >> $PATHDATA/../logs/debug.log; fi + # after a reboot we want to play the playlist once no matter what the setting is + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Take second wipe as first after fresh boot" >> $PATHDATA/../logs/debug.log; fi + elif [ "$SECONDSWIPE" == "PAUSE" -a $PLLENGTH -gt 0 ] + then + # The following involves NOT playing the playlist, so we set: + PLAYPLAYLIST=no + + STATE=$(echo -e "status\nclose" | nc -w 1 localhost 6600 | grep -o -P '(?<=state: ).*') + if [ $STATE == "play" ] + then + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " MPD playing, pausing the player" >> $PATHDATA/../logs/debug.log; fi + sudo $PATHDATA/playout_controls.sh -c=playerpause &>/dev/null + else + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "MPD not playing, start playing" >> $PATHDATA/../logs/debug.log; fi + sudo $PATHDATA/playout_controls.sh -c=playerplay &>/dev/null + fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Completed: toggle pause/play" >> $PATHDATA/../logs/debug.log; fi + elif [ "$SECONDSWIPE" == "PLAY" -a $PLLENGTH -gt 0 ] + then + # The following involves NOT playing the playlist, so we set: + PLAYPLAYLIST=no sudo $PATHDATA/playout_controls.sh -c=playerplay &>/dev/null + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Completed: Resume playback" >> $PATHDATA/../logs/debug.log; fi + elif [ "$SECONDSWIPE" == "NOAUDIOPLAY" ] + then + # The following involves NOT playing the playlist, so we set: + PLAYPLAYLIST=no + # following needs testing (see https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/914) + # Special case for NOAUDIOPLAY because once the playlist has finished, + # it needs to be noted by the system that the second swipe is like a *first* swipe. + currentSong=`mpc current` + if [[ -z "$currentSong" ]]; then + #end of playlist (EOPL) reached. Ignore last played playlist + PLAYPLAYLIST=yes + fi + + # "$SECONDSWIPE" == "NOAUDIOPLAY" + # "$LASTPLAYLIST" == "$PLAYLISTNAME" => same playlist triggered again + # => do nothing + # echo "do nothing" > /dev/null 2>&1 + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Completed: do nothing" >> $PATHDATA/../logs/debug.log; fi + elif [ "$SECONDSWIPE" == "SKIPNEXT" ] + then + # We will not play the playlist but skip to the next track: + PLAYPLAYLIST=skipnext + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Completed: skip next track" >> $PATHDATA/../logs/debug.log; fi fi - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Completed: toggle pause/play" >> $PATHDATA/../logs/debug.log; fi - elif [ "$SECONDSWIPE" == "PLAY" -a $PLLENGTH -gt 0 ] + fi + # now we check if we are still on for playing what we got passed on: + if [ "$PLAYPLAYLIST" == "yes" ] then - # The following involves NOT playing the playlist, so we set: - PLAYPLAYLIST=no - sudo $PATHDATA/playout_controls.sh -c=playerplay &>/dev/null - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Completed: Resume playback" >> $PATHDATA/../logs/debug.log; fi - elif [ "$SECONDSWIPE" == "NOAUDIOPLAY" ] + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "We must play the playlist no matter what: \$PLAYPLAYLIST == yes" >> $PATHDATA/../logs/debug.log; fi + + # Above we already checked if the folder exists -d "$AUDIOFOLDERSPATH/$FOLDER" + # + # the process is as such - because of the recursive play option: + # - each folder can be played. + # - a single folder will create a playlist with the same name as the folder + # - because folders can live inside other folders, the relative path might contain + # slashes (e.g. audiobooks/Moby Dick/) + # - because slashes can not be in the playlist name, slashes are replaced with " % " + # - the "recursive" option means that the content of the folder AND all subfolders + # is being played + # - in this case, the playlist is related to the same folder name, which means we need + # to make a different name for "recursive" playout + # - a recursive playlist has the suffix " %RCRSV%" - keeping it cryptic to avoid clashes + # with a possible "real" name for a folder + # - with this new logic, there are no more SPECIALFORMAT playlists. Live streams and podcasts + # are now all unfolded into the playlist + # - creating the playlist is now done in the php script with parameters: + # $PATHDATA/playlist_recursive_by_folder.php --folder "${FOLDER}" --list 'recursive' + + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " VAR FOLDER: $FOLDER" >> $PATHDATA/../logs/debug.log; fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " VAR PLAYLISTPATH: $PLAYLISTPATH" >> $PATHDATA/../logs/debug.log; fi + + # save position of current playing list "stop" + $PATHDATA/playout_controls.sh -c=playerstop + # play playlist + # the variable passed on to play is the playlist name -v (NOT the folder name) + # because (see above) a folder can be played recursively (including subfolders) or flat (only containing files) + # load new playlist and play + $PATHDATA/playout_controls.sh -c=playlistaddplay -v="${PLAYLISTNAME}" -d="${FOLDER}" + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Command: $PATHDATA/playout_controls.sh -c=playlistaddplay -v=\"${PLAYLISTNAME}\" -d=\"${FOLDER}\"" >> $PATHDATA/../logs/debug.log; fi + # save latest playlist not to file + sudo echo ${PLAYLISTNAME} > $PATHDATA/../settings/Latest_Playlist_Played + sudo chown pi:www-data $PATHDATA/../settings/Latest_Playlist_Played + sudo chmod 777 $PATHDATA/../settings/Latest_Playlist_Played + fi + if [ "$PLAYPLAYLIST" == "skipnext" ] then - # The following involves NOT playing the playlist, so we set: - PLAYPLAYLIST=no - # following needs testing (see https://github.com/MiczFlor/RPi-Jukebox-RFID/issues/914) - # Special case for NOAUDIOPLAY because once the playlist has finished, - # it needs to be noted by the system that the second swipe is like a *first* swipe. - currentSong=`mpc current` - if [[ -z "$currentSong" ]]; then - #end of playlist (EOPL) reached. Ignore last played playlist - PLAYPLAYLIST=yes - fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "Skip to the next track in the playlist: \$PLAYPLAYLIST == skipnext" >> $PATHDATA/../logs/debug.log; fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " VAR FOLDER: $FOLDER" >> $PATHDATA/../logs/debug.log; fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " VAR PLAYLISTPATH: $PLAYLISTPATH" >> $PATHDATA/../logs/debug.log; fi - # "$SECONDSWIPE" == "NOAUDIOPLAY" - # "$LASTPLAYLIST" == "$PLAYLISTNAME" => same playlist triggered again - # => do nothing - # echo "do nothing" > /dev/null 2>&1 - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Completed: do nothing" >> $PATHDATA/../logs/debug.log; fi - elif [ "$SECONDSWIPE" == "SKIPNEXT" ] - then - # We will not play the playlist but skip to the next track: - PLAYPLAYLIST=skipnext - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Completed: skip next track" >> $PATHDATA/../logs/debug.log; fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Command: $PATHDATA/playout_controls.sh -c=playernext" >> $PATHDATA/../logs/debug.log; fi + $PATHDATA/playout_controls.sh -c=playernext fi - fi - # now we check if we are still on for playing what we got passed on: - if [ "$PLAYPLAYLIST" == "yes" ] - then - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "We must play the playlist no matter what: \$PLAYPLAYLIST == yes" >> $PATHDATA/../logs/debug.log; fi - - # Above we already checked if the folder exists -d "$AUDIOFOLDERSPATH/$FOLDER" - # - # the process is as such - because of the recursive play option: - # - each folder can be played. - # - a single folder will create a playlist with the same name as the folder - # - because folders can live inside other folders, the relative path might contain - # slashes (e.g. audiobooks/Moby Dick/) - # - because slashes can not be in the playlist name, slashes are replaced with " % " - # - the "recursive" option means that the content of the folder AND all subfolders - # is being played - # - in this case, the playlist is related to the same folder name, which means we need - # to make a different name for "recursive" playout - # - a recursive playlist has the suffix " %RCRSV%" - keeping it cryptic to avoid clashes - # with a possible "real" name for a folder - # - with this new logic, there are no more SPECIALFORMAT playlists. Live streams and podcasts - # are now all unfolded into the playlist - # - creating the playlist is now done in the php script with parameters: - # $PATHDATA/playlist_recursive_by_folder.php --folder "${FOLDER}" --list 'recursive' - - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " VAR FOLDER: $FOLDER" >> $PATHDATA/../logs/debug.log; fi - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " VAR PLAYLISTPATH: $PLAYLISTPATH" >> $PATHDATA/../logs/debug.log; fi - - # save position of current playing list "stop" - $PATHDATA/playout_controls.sh -c=playerstop - # play playlist - # the variable passed on to play is the playlist name -v (NOT the folder name) - # because (see above) a folder can be played recursively (including subfolders) or flat (only containing files) - # load new playlist and play - $PATHDATA/playout_controls.sh -c=playlistaddplay -v="${PLAYLISTNAME}" -d="${FOLDER}" - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Command: $PATHDATA/playout_controls.sh -c=playlistaddplay -v=\"${PLAYLISTNAME}\" -d=\"${FOLDER}\"" >> $PATHDATA/../logs/debug.log; fi - # save latest playlist not to file - sudo echo ${PLAYLISTNAME} > $PATHDATA/../settings/Latest_Playlist_Played - sudo chown pi:www-data $PATHDATA/../settings/Latest_Playlist_Played - sudo chmod 777 $PATHDATA/../settings/Latest_Playlist_Played - fi - if [ "$PLAYPLAYLIST" == "skipnext" ] - then - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "Skip to the next track in the playlist: \$PLAYPLAYLIST == skipnext" >> $PATHDATA/../logs/debug.log; fi - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " VAR FOLDER: $FOLDER" >> $PATHDATA/../logs/debug.log; fi - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " VAR PLAYLISTPATH: $PLAYLISTPATH" >> $PATHDATA/../logs/debug.log; fi - - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo " Command: $PATHDATA/playout_controls.sh -c=playernext" >> $PATHDATA/../logs/debug.log; fi - $PATHDATA/playout_controls.sh -c=playernext + else + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "Path not found $AUDIOFOLDERSPATH/$FOLDER" >> $PATHDATA/../logs/debug.log; fi fi else - if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "Path not found $AUDIOFOLDERSPATH/$FOLDER" >> $PATHDATA/../logs/debug.log; fi + if [ "${DEBUG_rfid_trigger_play_sh}" == "TRUE" ]; then echo "var FOLDER empty" >> $PATHDATA/../logs/debug.log; fi fi diff --git a/settings/debugLogging.conf.sample b/settings/debugLogging.conf.sample index 9494224e3..1cece8131 100755 --- a/settings/debugLogging.conf.sample +++ b/settings/debugLogging.conf.sample @@ -10,3 +10,4 @@ DEBUG_resume_play_sh="FALSE" DEBUG_rfid_trigger_play_sh="FALSE" DEBUG_shuffle_play_sh="FALSE" DEBUG_single_play_sh="FALSE" +DEBUG_sync_shared_sh="FALSE" diff --git a/settings/rfid_trigger_play.conf.sample b/settings/rfid_trigger_play.conf.sample index 9b99fa7a2..b9eb6843a 100755 --- a/settings/rfid_trigger_play.conf.sample +++ b/settings/rfid_trigger_play.conf.sample @@ -16,7 +16,7 @@ # A section starts with ## # Example: ## Audio player # A command's description is *above* the command and starts with ### -# Example: +# Example: # ### Stop player # CMDSTOP="%CMDSTOP%" # This structuring was introduced to have a human readable display in the Web UI @@ -146,7 +146,7 @@ TOGGLEWIFI="%TOGGLEWIFI%" ### Read out the Wifi IP over the Phoniebox speakers CMDREADWIFIIP="%CMDREADWIFIIP%" -## Recording audio commands +## Recording audio commands ### Start recording for 10 sec. duration RECORDSTART10="%RECORDSTART10%" ### Start recording for 60 sec. duration @@ -157,3 +157,9 @@ RECORDSTART600="%RECORDSTART600%" RECORDSTOP="%RECORDSTOP%" ### Replay latest recording RECORDPLAYBACKLATEST="%RECORDPLAYBACKLATEST%" + +## Synchronisation +### Synchronise all shared files +SYNCSHAREDFULL="%SYNCSHAREDFULL%" +### Toggle activation of 'sync on RFID scan' +SYNCSHAREDONRFIDSCANTOGGLE="%SYNCSHAREDONRFIDSCANTOGGLE%"