feat: further work on the wrapper
All checks were successful
Cross-Compile Binaries / compile-linux (push) Successful in 3m57s
Cross-Compile Binaries / compile-windows (push) Successful in 9m27s

This commit is contained in:
2026-02-06 11:34:24 +01:00
parent 66cc9dae97
commit a08976890d
4 changed files with 242 additions and 30 deletions

66
dyn-com-install.sh Executable file
View File

@@ -0,0 +1,66 @@
#!/bin/bash
#
# Development builder
#
install_file="install.sh"
cat > ./$install_file << EOF
#!/bin/bash
program_name="raspscreen"
runtime_id=\$(id -u)
userland_name="\${1-systemec}"
# Check if the user is right (root) for the program
if [[ "\$runtime_id" -ne 0 ]]; then
echo "Not running as root, please run as root."
exit 1
fi
apt-get -y install \\
default-jre libreoffice-impress libreoffice-java-common psmisc ssh vlc
systemctl enable --now ssh
# Create the systemd userland folder
if [[ ! -d /home/\${userland_name}/.config/systemd/user ]]; then
mkdir -p /home/\${userland_name}/.config/systemd/user -m 755
fi
# Create the program place onto /opt
if [[ ! -d /opt/\${program_name} ]]; then
mkdir -p /opt/\${program_name}/media/current -m 755
mkdir -p /opt/\${program_name}/bin -m 755
fi
# THIS MUST BE THE SAME AS \$REPO/service-files/presentation.service
cat > /home/\${userland_name}/.config/systemd/user/presentation.service << EOF
EOF
cat ./service-files/presentation.service >> ./$install_file
echo -e "\nEOF\n" >> ./$install_file
cat >> ./$install_file << EOF
# THIS MUST BE THE SAME AS \$REPO/service-files/video.service
cat > /home/\${userland_name}/.config/systemd/user/video.service << EOF
EOF
cat ./service-files/video.service >> ./$install_file
echo -e "\nEOF\n" >> ./$install_file
cat >> ./$install_file << EOF
# THIS MUST BE THE AS \$REPO/manage.sh
cat > /opt/raspscreen/bin/manage.sh << EOF
EOF
# Make sure to prefix all $ with a \
sed 's/\$/\\$/g' ./manage.sh >> "$install_file"
echo -e "\nEOF\n" >> ./$install_file
cat >> ./$install_file << EOF
chmod +x /opt/raspscreen/bin/manage.sh
chown -Rv \${userland_name}:\${userland_name} /home/\${userland_name}/.config/systemd
chown -Rv \${userland_name}:\${userland_name} /opt/\${program_name}
su \${userland_name} -c "systemctl --user daemon-reload"
echo "Self-destruction NOW!"
rm \$(pwd)/\$0
EOF

133
install.sh Executable file → Normal file
View File

@@ -21,10 +21,11 @@ fi
# Create the program place onto /opt # Create the program place onto /opt
if [[ ! -d /opt/${program_name} ]]; then if [[ ! -d /opt/${program_name} ]]; then
mkdir -p /opt/${program_name}/media -m 755 mkdir -p /opt/${program_name}/media/current -m 755
mkdir -p /opt/${program_name}/bin -m 755
fi fi
# THIS MUST BE THE SAME AR $REPO/service-files/presentation.service # THIS MUST BE THE SAME AS $REPO/service-files/presentation.service
cat > /home/${userland_name}/.config/systemd/user/presentation.service << EOF cat > /home/${userland_name}/.config/systemd/user/presentation.service << EOF
[Unit] [Unit]
Description="Systemec RaspScreen Presentation" Description="Systemec RaspScreen Presentation"
@@ -44,7 +45,7 @@ RestartSec=2
WantedBy=default.target WantedBy=default.target
EOF EOF
# THIS MUST BE THE SAME AR $REPO/service-files/video.service # THIS MUST BE THE SAME AS $REPO/service-files/video.service
cat > /home/${userland_name}/.config/systemd/user/video.service << EOF cat > /home/${userland_name}/.config/systemd/user/video.service << EOF
[Unit] [Unit]
Description="Systemec RaspScreen Video" Description="Systemec RaspScreen Video"
@@ -64,8 +65,132 @@ RestartSec=2
WantedBy=default.target WantedBy=default.target
EOF EOF
# THIS MUST BE THE AS $REPO/manage.sh
cat > /opt/raspscreen/bin/manage.sh << EOF
#!/bin/bash
#
# Utility to manage the userland program called RaspScreen by Systemec B.V.
#
# Where it should live: /opt/raspscreen/bin/manage.sh
#
# Examples:
# ./manage.sh (restart|stop|start) (presentation|video)
#
# systemctl must be reachable from the path of the executing user.
app_name="raspscreen"
runtime_id=\$(id -u)
if [[ "\$runtime_id" -eq 0 ]]; then
echo "Do not run as root. Run as the graphical user."
exit 1
fi
printf "Checking input..."
# Action performed
case "\$1" in
restart|stop|start|switch-state)
printf "Valid command...";;
*)
echo "Invalid command!"
exit 1;;
esac
# Type to select
case "\$2" in
presentation|video)
echo "Valid service...";;
*)
echo "Invalid service!"
exit 1;;
esac
# Foreground or operator mode
case "\$3" in
--foreground)
echo "Gathering uptime data..."
sys_uptime=\$(cat /proc/uptime | awk '{print int(\$1)}')
if [[ "\$sys_uptime" -lt 60 ]]; then
echo "Detected a recent restart - giving the operating system some time..."
sleep 10s
fi
if [[ "\$2" == "presentation" ]]; then
echo "Finding and moving media..."
media_file=\$(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \))
cp "\$media_file" /opt/raspscreen/media/current
current_media=\$(find /opt/raspscreen/media/current \( -name "*.pptx" -o -name "*.odp" \))
if [[ -z "\$current_media" ]]; then
echo "No compatible media file found. Wrong mode?"
echo "Exiting in 20 seconds..."
sleep 20s
exit 1
else
/usr/bin/libreoffice --impress --show --norestore "\$current_media"
fi
elif [[ "\$2" == "video" ]]; then
echo "Finding and moving media..."
media_file=\$(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \))
cp "\$media_file" /opt/raspscreen/media/current
current_media=\$(find /opt/raspscreen/media/current \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \))
if [[ -z "\$current_media" ]]; then
echo "No compatible media file found. Wrong mode?"
echo "Exiting in 20 seconds..."
sleep 20s
exit 1
else
/usr/bin/vlc --fullscreen --loop --no-video-title --video-on-top --no-qt-fs-controller --qt-continue=0 "\$current_media"
fi
fi
echo "Process exited..."
exit 0
;;
*)
echo "Running in task mode...";;
esac
echo "Executing task..."
if [[ "\$1" != "switch-state" ]]; then
cmd_result=\$(systemctl --user "\$1" "\$2" 2>&1)
cmd_exit=\$?
elif [[ "\$1" == "switch-state" ]]; then
last_state=\$(cat /opt/raspscreen/currentstate.txt)
if [[ "\$2" == "video" ]]; then
alt_serv="presentation"
elif [[ "\$2" == "presentation" ]]; then
alt_serv="video"
fi
echo "alt_serv: \$alt_serv"
if [ "\$last_state" != "\$2" ] || [ -z "\$last_state" ]; then
systemctl --user disable "\$alt_serv"
systemctl --user enable "\$2"
fi
systemctl --user restart "\$2"
echo "\$2" > /opt/raspscreen/currentstate.txt
fi
if [[ "\$cmd_exit" -eq 0 ]]; then
echo "Succesfully exited!"
else
echo "Something went wrong, see..."
echo " -> \$cmd_result"
fi
exit 0
EOF
chmod +x /opt/raspscreen/bin/manage.sh
chown -Rv ${userland_name}:${userland_name} /home/${userland_name}/.config/systemd chown -Rv ${userland_name}:${userland_name} /home/${userland_name}/.config/systemd
chown -Rv ${userland_name}:${userland_name} /opt/${program_name} chown -Rv ${userland_name}:${userland_name} /opt/${program_name}
su ${userland_name} -c "systemctl --user daemon-reload"
echo "Self-destruction NOW!" echo "Self-destruction NOW!"
rm $(pwd)/$0 rm $(pwd)/$0

View File

@@ -18,14 +18,17 @@ if [[ "$runtime_id" -eq 0 ]]; then
fi fi
printf "Checking input..." printf "Checking input..."
# Action performed
case "$1" in case "$1" in
restart|stop|start) restart|stop|start|switch-state)
printf "Valid command...";; printf "Valid command...";;
*) *)
echo "Invalid command!" echo "Invalid command!"
exit 1;; exit 1;;
esac esac
# Type to select
case "$2" in case "$2" in
presentation|video) presentation|video)
echo "Valid service...";; echo "Valid service...";;
@@ -34,6 +37,7 @@ case "$2" in
exit 1;; exit 1;;
esac esac
# Foreground or operator mode
case "$3" in case "$3" in
--foreground) --foreground)
echo "Gathering uptime data..." echo "Gathering uptime data..."
@@ -45,26 +49,34 @@ case "$3" in
fi fi
if [[ "$2" == "presentation" ]]; then if [[ "$2" == "presentation" ]]; then
echo "Finding and moving media..."
media_file=$(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \)) media_file=$(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \))
if [[ -z "$media_file" ]]; then cp "$media_file" /opt/raspscreen/media/current
current_media=$(find /opt/raspscreen/media/current \( -name "*.pptx" -o -name "*.odp" \))
if [[ -z "$current_media" ]]; then
echo "No compatible media file found. Wrong mode?" echo "No compatible media file found. Wrong mode?"
echo "Exiting in 20 seconds..." echo "Exiting in 20 seconds..."
sleep 20s sleep 20s
exit 1 exit 1
else else
/usr/bin/libreoffice --impress --show --norestore "$media_file" /usr/bin/libreoffice --impress --show --norestore "$current_media"
fi fi
elif [[ "$2" == "video" ]]; then elif [[ "$2" == "video" ]]; then
echo "Finding and moving media..."
media_file=$(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \)) media_file=$(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \))
if [[ -z "$media_file" ]]; then cp "$media_file" /opt/raspscreen/media/current
current_media=$(find /opt/raspscreen/media/current \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \))
if [[ -z "$current_media" ]]; then
echo "No compatible media file found. Wrong mode?" echo "No compatible media file found. Wrong mode?"
echo "Exiting in 20 seconds..." echo "Exiting in 20 seconds..."
sleep 20s sleep 20s
exit 1 exit 1
else else
/usr/bin/vlc --fullscreen --loop --no-video-title --video-on-top --no-qt-fs-controller --qt-continue=0 "$media_file" /usr/bin/vlc --fullscreen --loop --no-video-title --video-on-top --no-qt-fs-controller --qt-continue=0 "$current_media"
fi fi
fi fi
echo "Process exited..." echo "Process exited..."
@@ -75,14 +87,30 @@ case "$3" in
esac esac
echo "Executing task..." echo "Executing task..."
cmd_result=$(systemctl --user "$1" "$2" 2>&1) if [[ "$1" != "switch-state" ]]; then
cmd_exit=$? cmd_result=$(systemctl --user "$1" "$2" 2>&1)
cmd_exit=$?
elif [[ "$1" == "switch-state" ]]; then
last_state=$(cat /opt/raspscreen/currentstate.txt)
if [[ "$2" == "video" ]]; then
alt_serv="presentation"
elif [[ "$2" == "presentation" ]]; then
alt_serv="video"
fi
echo "alt_serv: $alt_serv"
if [ "$last_state" != "$2" ] || [ -z "$last_state" ]; then
systemctl --user disable "$alt_serv"
systemctl --user enable "$2"
fi
systemctl --user restart "$2"
echo "$2" > /opt/raspscreen/currentstate.txt
fi
if [[ "$cmd_exit" -eq 0 ]]; then if [[ "$cmd_exit" -eq 0 ]]; then
echo "Succesfully exited, see:" echo "Succesfully exited!"
if [[ -n "$cmd_result" ]]; then
echo " -> $cmd_result"
fi
else else
echo "Something went wrong, see..." echo "Something went wrong, see..."
echo " -> $cmd_result" echo " -> $cmd_result"

View File

@@ -114,13 +114,7 @@ func sftpUploadFile(targetName, localPath, remotePath string, cfg RaspiConfig) b
} }
func restartShow(targetName string, targetMode int, cfg RaspiConfig) bool { func restartShow(targetName string, targetMode int, cfg RaspiConfig) bool {
const restartPresentation string = "systemctl --user restart presentation" const switchCmd string = "/opt/raspscreen/bin/manage.sh switch-state " // add a blank/whitespace at the end to make the formatting valid for manage.sh
const enablePresentation string = "systemctl --user enable presentation"
const disablePresentation string = "systemctl --user disable presentation"
const restartVideo string = "systemctl --user restart video"
const enableVideo string = "systemctl --user enable video"
const disableVideo string = "systemctl --user disable video"
var err error var err error
sshClient, err := createSSHClient(targetName, cfg) sshClient, err := createSSHClient(targetName, cfg)
@@ -138,18 +132,17 @@ func restartShow(targetName string, targetMode int, cfg RaspiConfig) bool {
} }
defer session.Close() defer session.Close()
var servName string
switch targetMode { switch targetMode {
case 1: case 1:
log.Println("Configuring application workflow: Presentation") servName = "presentation"
_, err = runSSHCommand(sshClient, disableVideo) // Disable the conflicting service
_, err = runSSHCommand(sshClient, restartPresentation) // Restart the wanted service (which MUST be a restart because the media might have changed)
_, err = runSSHCommand(sshClient, enablePresentation) // Make sure the wanted service starts on reboot
case 2: case 2:
log.Println("Configuring application workflow: Video") servName = "video"
_, err = runSSHCommand(sshClient, disablePresentation) // Disable the conflicting service
_, err = runSSHCommand(sshClient, restartVideo) // Restart the wanted service (which MUST be a restart because the media might have changed)
_, err = runSSHCommand(sshClient, enableVideo) // Make sure the wanted service starts on reboot
} }
log.Println("Configuring application workflow:", servName)
stitchCmd := switchCmd + servName
_, err = runSSHCommand(sshClient, stitchCmd)
if err != nil { if err != nil {
log.Printf("Failed to restart the show over SSH: %v", err) log.Printf("Failed to restart the show over SSH: %v", err)