From 4f0eeb52d86e78c32437bd988c261a4016e2dd4f Mon Sep 17 00:00:00 2001 From: DaanSelen Date: Wed, 4 Feb 2026 15:05:31 +0100 Subject: [PATCH 1/7] chore: begin work on op_mode --- build.sh | 0 install.sh | 8 ++--- manage.sh | 49 +++++++++++++++++++++++++++++- service-files/presentation.service | 1 - service-files/video.service | 1 - 5 files changed, 52 insertions(+), 7 deletions(-) mode change 100644 => 100755 build.sh mode change 100644 => 100755 install.sh mode change 100644 => 100755 manage.sh diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 diff --git a/install.sh b/install.sh old mode 100644 new mode 100755 index d565f66..82b43c6 --- a/install.sh +++ b/install.sh @@ -22,6 +22,7 @@ if [[ ! -d /opt/${program_name} ]]; then mkdir -p /opt/${program_name}/media -m 755 fi +# THIS MUST BE THE SAME AR $REPO/service-files/presentation.service cat > /home/${userland_name}/.config/systemd/user/presentation.service << EOF [Unit] Description="Systemec RaspScreen" @@ -33,16 +34,16 @@ Type=simple Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen ExecStartPre=/usr/bin/sleep 5 -ExecStart=/bin/sh -c 'exec /usr/bin/libreoffice --impress --show --norestore \$(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \))' +ExecStart=/bin/sh -c 'exec /usr/bin/libreoffice --impress --show --norestore $(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \))' ExecStop=/usr/bin/killall libreoffice Restart=always -Restart=on-failure RestartSec=2 [Install] WantedBy=default.target EOF +# THIS MUST BE THE SAME AR $REPO/service-files/video.service cat > /home/${userland_name}/.config/systemd/user/video.service << EOF [Unit] Description="Systemec RaspScreen" @@ -54,10 +55,9 @@ Type=simple Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen ExecStartPre=/usr/bin/sleep 5 -ExecStart=/bin/sh -c 'exec /usr/bin/vlc --fullscreen --loop --no-video-title --video-on-top --no-qt-privacy-ask --no-qt-fs-controller --qt-continue=0 \$(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \))' +ExecStart=/bin/sh -c 'exec /usr/bin/vlc --fullscreen --loop --no-video-title --video-on-top --no-qt-fs-controller --qt-continue=0 $(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \))' ExecStop=/usr/bin/killall vlc Restart=always -Restart=on-failure RestartSec=2 [Install] diff --git a/manage.sh b/manage.sh old mode 100644 new mode 100755 index 0be8dd0..8a229a8 --- a/manage.sh +++ b/manage.sh @@ -6,8 +6,55 @@ # # Examples: # ./manage.sh (restart|stop|start) (presentation|video) +# +# systemctl must be reachable from the path of the executing user. runtime_id=$(id -u) if [[ "$runtime_id" -eq 0 ]]; then echo "Do not run as root. Run as the graphical user." -fi \ No newline at end of file + exit 1 +fi + +printf "Checking input..." +case "$1" in + restart|stop|start) + printf "Valid command...";; + *) + echo "Invalid command!" + exit 1;; +esac + +case "$2" in + presentation|video) + echo "Valid service...";; + *) + echo "Invalid service!" + exit 1;; +esac + +case "$3" in + --foreground) + if [[ "$2" == "presentation" ]]; then + /bin/sh -c 'exec /usr/bin/libreoffice --impress --show --norestore $(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \))' + fi + if [[ "$2" == "video" ]]; then + /bin/sh -c 'exec /usr/bin/libreoffice --impress --show --norestore $(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \))' + fi + *) + echo "Running in task mode...";; +esac + +echo "Executing task..." +cmd_result=$(systemctl --user "$1" "$2" 2>&1) +cmd_exit=$? + +if [[ "$cmd_exit" -eq 0 ]]; then + echo "Succesfully exited, see:" + if [[ -n "$cmd_result" ]]; then + echo " -> $cmd_result" + fi +else + echo "Something went wrong, see..." + echo " -> $cmd_result" +fi +exit 0 \ No newline at end of file diff --git a/service-files/presentation.service b/service-files/presentation.service index 196db8e..3e1b0bb 100644 --- a/service-files/presentation.service +++ b/service-files/presentation.service @@ -11,7 +11,6 @@ ExecStartPre=/usr/bin/sleep 5 ExecStart=/bin/sh -c 'exec /usr/bin/libreoffice --impress --show --norestore $(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \))' ExecStop=/usr/bin/killall libreoffice Restart=always -Restart=on-failure RestartSec=2 [Install] diff --git a/service-files/video.service b/service-files/video.service index cb4051c..cb3591f 100644 --- a/service-files/video.service +++ b/service-files/video.service @@ -11,7 +11,6 @@ ExecStartPre=/usr/bin/sleep 5 ExecStart=/bin/sh -c 'exec /usr/bin/vlc --fullscreen --loop --no-video-title --video-on-top --no-qt-fs-controller --qt-continue=0 $(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \))' ExecStop=/usr/bin/killall vlc Restart=always -Restart=on-failure RestartSec=2 [Install] -- 2.49.1 From a77e59929a601440969a11b60e08f242a2cb4277 Mon Sep 17 00:00:00 2001 From: DaanSelen Date: Wed, 4 Feb 2026 16:31:47 +0100 Subject: [PATCH 2/7] chore: working --- install.sh | 14 +++++---- manage.sh | 46 ++++++++++++++++++++++++++++-- service-files/presentation.service | 7 +++-- service-files/video.service | 7 +++-- 4 files changed, 59 insertions(+), 15 deletions(-) diff --git a/install.sh b/install.sh index 82b43c6..0b47511 100755 --- a/install.sh +++ b/install.sh @@ -25,7 +25,7 @@ fi # THIS MUST BE THE SAME AR $REPO/service-files/presentation.service cat > /home/${userland_name}/.config/systemd/user/presentation.service << EOF [Unit] -Description="Systemec RaspScreen" +Description="Systemec RaspScreen Presentation" Conflicts=video.service After=graphical.target @@ -34,9 +34,10 @@ Type=simple Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen ExecStartPre=/usr/bin/sleep 5 -ExecStart=/bin/sh -c 'exec /usr/bin/libreoffice --impress --show --norestore $(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \))' -ExecStop=/usr/bin/killall libreoffice +ExecStart=/opt/raspscreen/bin/manage.sh start presentation --foreground +ExecStop=/opt/raspscreen/bin/manage kill video Restart=always +Restart=on-failure RestartSec=2 [Install] @@ -46,7 +47,7 @@ EOF # THIS MUST BE THE SAME AR $REPO/service-files/video.service cat > /home/${userland_name}/.config/systemd/user/video.service << EOF [Unit] -Description="Systemec RaspScreen" +Description="Systemec RaspScreen Video" Conflicts=presentation.service After=graphical.target @@ -55,9 +56,10 @@ Type=simple Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen ExecStartPre=/usr/bin/sleep 5 -ExecStart=/bin/sh -c 'exec /usr/bin/vlc --fullscreen --loop --no-video-title --video-on-top --no-qt-fs-controller --qt-continue=0 $(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \))' -ExecStop=/usr/bin/killall vlc +ExecStart=/opt/raspscreen/bin/manage.sh start video --foreground +ExecStop=/opt/raspscreen/bin/manage kill video Restart=always +Restart=on-failure RestartSec=2 [Install] diff --git a/manage.sh b/manage.sh index 8a229a8..672c129 100755 --- a/manage.sh +++ b/manage.sh @@ -9,6 +9,14 @@ # # systemctl must be reachable from the path of the executing user. +app_name="raspscreen" + +# Fallback for display selection +if [[ -z $DISPLAY ]]; then + echo "Triggered exporting display variable fallback..." + export DISPLAY=:0 +fi + runtime_id=$(id -u) if [[ "$runtime_id" -eq 0 ]]; then echo "Do not run as root. Run as the graphical user." @@ -17,7 +25,7 @@ fi printf "Checking input..." case "$1" in - restart|stop|start) + restart|stop|start|kill) printf "Valid command...";; *) echo "Invalid command!" @@ -32,14 +40,46 @@ case "$2" in exit 1;; esac +if [[ "$1" == "kill" ]]; then + if [[ "$2" == "presentation" ]]; then + /usr/bin/killall libreoffice + exit $? + fi + if [[ "$2" == "video" ]]; then + /usr/bin/killall vlc + exit $? + fi +fi + case "$3" in --foreground) if [[ "$2" == "presentation" ]]; then - /bin/sh -c 'exec /usr/bin/libreoffice --impress --show --norestore $(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 + echo "No compatible media file found. Wrong mode?" + echo "Exiting in 20 seconds..." + sleep 20s + exit 1 + else + /usr/bin/libreoffice --impress --show --norestore "$media_file" + fi fi if [[ "$2" == "video" ]]; then - /bin/sh -c 'exec /usr/bin/libreoffice --impress --show --norestore $(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \))' + media_file=$(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \)) + + if [[ -z "$media_file" ]]; 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 "$media_file" + fi fi + echo "Process exited..." + exit 0 + ;; *) echo "Running in task mode...";; esac diff --git a/service-files/presentation.service b/service-files/presentation.service index 3e1b0bb..c9173f6 100644 --- a/service-files/presentation.service +++ b/service-files/presentation.service @@ -1,5 +1,5 @@ [Unit] -Description="Systemec RaspScreen" +Description="Systemec RaspScreen Presentation" Conflicts=video.service After=graphical.target @@ -8,9 +8,10 @@ Type=simple Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen ExecStartPre=/usr/bin/sleep 5 -ExecStart=/bin/sh -c 'exec /usr/bin/libreoffice --impress --show --norestore $(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \))' -ExecStop=/usr/bin/killall libreoffice +ExecStart=/opt/raspscreen/bin/manage.sh start presentation --foreground +ExecStop=/opt/raspscreen/bin/manage kill video Restart=always +Restart=on-failure RestartSec=2 [Install] diff --git a/service-files/video.service b/service-files/video.service index cb3591f..2071750 100644 --- a/service-files/video.service +++ b/service-files/video.service @@ -1,5 +1,5 @@ [Unit] -Description="Systemec RaspScreen" +Description="Systemec RaspScreen Video" Conflicts=presentation.service After=graphical.target @@ -8,9 +8,10 @@ Type=simple Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen ExecStartPre=/usr/bin/sleep 5 -ExecStart=/bin/sh -c 'exec /usr/bin/vlc --fullscreen --loop --no-video-title --video-on-top --no-qt-fs-controller --qt-continue=0 $(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \))' -ExecStop=/usr/bin/killall vlc +ExecStart=/opt/raspscreen/bin/manage.sh start video --foreground +ExecStop=/opt/raspscreen/bin/manage kill video Restart=always +Restart=on-failure RestartSec=2 [Install] -- 2.49.1 From 7eef1c067a9b845a6e302d749189bd1be8f469cc Mon Sep 17 00:00:00 2001 From: DaanSelen Date: Wed, 4 Feb 2026 17:00:23 +0100 Subject: [PATCH 3/7] try: to fix killing --- manage.sh | 2 +- service-files/presentation.service | 2 +- service-files/video.service | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/manage.sh b/manage.sh index 672c129..1fc9b83 100755 --- a/manage.sh +++ b/manage.sh @@ -67,7 +67,7 @@ case "$3" in fi if [[ "$2" == "video" ]]; then media_file=$(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \)) - + if [[ -z "$media_file" ]]; then echo "No compatible media file found. Wrong mode?" echo "Exiting in 20 seconds..." diff --git a/service-files/presentation.service b/service-files/presentation.service index c9173f6..8f8d24b 100644 --- a/service-files/presentation.service +++ b/service-files/presentation.service @@ -9,7 +9,7 @@ Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen ExecStartPre=/usr/bin/sleep 5 ExecStart=/opt/raspscreen/bin/manage.sh start presentation --foreground -ExecStop=/opt/raspscreen/bin/manage kill video +ExecStop=/opt/raspscreen/bin/manage.sh kill presentation Restart=always Restart=on-failure RestartSec=2 diff --git a/service-files/video.service b/service-files/video.service index 2071750..5f37617 100644 --- a/service-files/video.service +++ b/service-files/video.service @@ -9,7 +9,7 @@ Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen ExecStartPre=/usr/bin/sleep 5 ExecStart=/opt/raspscreen/bin/manage.sh start video --foreground -ExecStop=/opt/raspscreen/bin/manage kill video +ExecStop=/opt/raspscreen/bin/manage.sh kill video Restart=always Restart=on-failure RestartSec=2 -- 2.49.1 From 66cc9dae97a16e90c31ff90bd430034040c90693 Mon Sep 17 00:00:00 2001 From: DaanSelen Date: Thu, 5 Feb 2026 16:22:18 +0100 Subject: [PATCH 4/7] feat: account for post-reboot --- install.sh | 16 +++++++--------- manage.sh | 30 ++++++++++-------------------- service-files/presentation.service | 6 ++---- service-files/video.service | 6 ++---- src/action.go | 12 ++++++------ 5 files changed, 27 insertions(+), 43 deletions(-) diff --git a/install.sh b/install.sh index 0b47511..624b6cb 100755 --- a/install.sh +++ b/install.sh @@ -9,7 +9,9 @@ if [[ "$runtime_id" -ne 0 ]]; then echo "Not running as root, please run as root." exit 1 fi -apt-get -y install libreoffice-impress psmisc ssh vlc +apt-get -y install \ + default-jre libreoffice-impress libreoffice-java-common psmisc ssh vlc + systemctl enable --now ssh # Create the systemd userland folder @@ -27,16 +29,14 @@ cat > /home/${userland_name}/.config/systemd/user/presentation.service << EOF [Unit] Description="Systemec RaspScreen Presentation" Conflicts=video.service -After=graphical.target +After=graphical-session.target [Service] Type=simple Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen -ExecStartPre=/usr/bin/sleep 5 ExecStart=/opt/raspscreen/bin/manage.sh start presentation --foreground -ExecStop=/opt/raspscreen/bin/manage kill video -Restart=always +KillSignal=SIGKILL Restart=on-failure RestartSec=2 @@ -49,16 +49,14 @@ cat > /home/${userland_name}/.config/systemd/user/video.service << EOF [Unit] Description="Systemec RaspScreen Video" Conflicts=presentation.service -After=graphical.target +After=graphical-session.target [Service] Type=simple Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen -ExecStartPre=/usr/bin/sleep 5 ExecStart=/opt/raspscreen/bin/manage.sh start video --foreground -ExecStop=/opt/raspscreen/bin/manage kill video -Restart=always +KillSignal=SIGKILL Restart=on-failure RestartSec=2 diff --git a/manage.sh b/manage.sh index 1fc9b83..28c7fe2 100755 --- a/manage.sh +++ b/manage.sh @@ -11,12 +11,6 @@ app_name="raspscreen" -# Fallback for display selection -if [[ -z $DISPLAY ]]; then - echo "Triggered exporting display variable fallback..." - export DISPLAY=:0 -fi - runtime_id=$(id -u) if [[ "$runtime_id" -eq 0 ]]; then echo "Do not run as root. Run as the graphical user." @@ -25,7 +19,7 @@ fi printf "Checking input..." case "$1" in - restart|stop|start|kill) + restart|stop|start) printf "Valid command...";; *) echo "Invalid command!" @@ -40,19 +34,16 @@ case "$2" in exit 1;; esac -if [[ "$1" == "kill" ]]; then - if [[ "$2" == "presentation" ]]; then - /usr/bin/killall libreoffice - exit $? - fi - if [[ "$2" == "video" ]]; then - /usr/bin/killall vlc - exit $? - fi -fi - 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 media_file=$(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \)) @@ -64,8 +55,7 @@ case "$3" in else /usr/bin/libreoffice --impress --show --norestore "$media_file" fi - fi - if [[ "$2" == "video" ]]; then + elif [[ "$2" == "video" ]]; then media_file=$(find /opt/raspscreen/media \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \)) if [[ -z "$media_file" ]]; then diff --git a/service-files/presentation.service b/service-files/presentation.service index 8f8d24b..e676bb6 100644 --- a/service-files/presentation.service +++ b/service-files/presentation.service @@ -1,16 +1,14 @@ [Unit] Description="Systemec RaspScreen Presentation" Conflicts=video.service -After=graphical.target +After=graphical-session.target [Service] Type=simple Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen -ExecStartPre=/usr/bin/sleep 5 ExecStart=/opt/raspscreen/bin/manage.sh start presentation --foreground -ExecStop=/opt/raspscreen/bin/manage.sh kill presentation -Restart=always +KillSignal=SIGKILL Restart=on-failure RestartSec=2 diff --git a/service-files/video.service b/service-files/video.service index 5f37617..39eb977 100644 --- a/service-files/video.service +++ b/service-files/video.service @@ -1,16 +1,14 @@ [Unit] Description="Systemec RaspScreen Video" Conflicts=presentation.service -After=graphical.target +After=graphical-session.target [Service] Type=simple Environment=DISPLAY=:0 WorkingDirectory=/opt/raspscreen -ExecStartPre=/usr/bin/sleep 5 ExecStart=/opt/raspscreen/bin/manage.sh start video --foreground -ExecStop=/opt/raspscreen/bin/manage.sh kill video -Restart=always +KillSignal=SIGKILL Restart=on-failure RestartSec=2 diff --git a/src/action.go b/src/action.go index f00f9df..53e8424 100644 --- a/src/action.go +++ b/src/action.go @@ -141,14 +141,14 @@ func restartShow(targetName string, targetMode int, cfg RaspiConfig) bool { switch targetMode { case 1: log.Println("Configuring application workflow: Presentation") - _, err = runSSHCommand(sshClient, disableVideo) - _, err = runSSHCommand(sshClient, restartPresentation) - _, err = runSSHCommand(sshClient, enablePresentation) + _, 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: log.Println("Configuring application workflow: Video") - _, err = runSSHCommand(sshClient, disablePresentation) - _, err = runSSHCommand(sshClient, restartVideo) - _, err = runSSHCommand(sshClient, enableVideo) + _, 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 } if err != nil { -- 2.49.1 From a08976890d937cb2a03cdb21ae5be4f75d26c78c Mon Sep 17 00:00:00 2001 From: DaanSelen Date: Fri, 6 Feb 2026 11:34:24 +0100 Subject: [PATCH 5/7] feat: further work on the wrapper --- dyn-com-install.sh | 66 ++++++++++++++++++++++ install.sh | 133 +++++++++++++++++++++++++++++++++++++++++++-- manage.sh | 50 +++++++++++++---- src/action.go | 23 +++----- 4 files changed, 242 insertions(+), 30 deletions(-) create mode 100755 dyn-com-install.sh mode change 100755 => 100644 install.sh diff --git a/dyn-com-install.sh b/dyn-com-install.sh new file mode 100755 index 0000000..7a97a13 --- /dev/null +++ b/dyn-com-install.sh @@ -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 \ No newline at end of file diff --git a/install.sh b/install.sh old mode 100755 new mode 100644 index 624b6cb..706b478 --- a/install.sh +++ b/install.sh @@ -21,10 +21,11 @@ fi # Create the program place onto /opt 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 -# 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 [Unit] Description="Systemec RaspScreen Presentation" @@ -44,7 +45,7 @@ RestartSec=2 WantedBy=default.target 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 [Unit] Description="Systemec RaspScreen Video" @@ -64,8 +65,132 @@ RestartSec=2 WantedBy=default.target 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} /opt/${program_name} +su ${userland_name} -c "systemctl --user daemon-reload" echo "Self-destruction NOW!" -rm $(pwd)/$0 \ No newline at end of file +rm $(pwd)/$0 diff --git a/manage.sh b/manage.sh index 28c7fe2..115bf57 100755 --- a/manage.sh +++ b/manage.sh @@ -18,14 +18,17 @@ if [[ "$runtime_id" -eq 0 ]]; then fi printf "Checking input..." + +# Action performed case "$1" in - restart|stop|start) + 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...";; @@ -34,6 +37,7 @@ case "$2" in exit 1;; esac +# Foreground or operator mode case "$3" in --foreground) echo "Gathering uptime data..." @@ -45,26 +49,34 @@ case "$3" in fi if [[ "$2" == "presentation" ]]; then + echo "Finding and moving media..." 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 "Exiting in 20 seconds..." sleep 20s exit 1 else - /usr/bin/libreoffice --impress --show --norestore "$media_file" + /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" \)) - 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 "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 "$media_file" + /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..." @@ -75,14 +87,30 @@ case "$3" in esac echo "Executing task..." -cmd_result=$(systemctl --user "$1" "$2" 2>&1) -cmd_exit=$? +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, see:" - if [[ -n "$cmd_result" ]]; then - echo " -> $cmd_result" - fi + echo "Succesfully exited!" else echo "Something went wrong, see..." echo " -> $cmd_result" diff --git a/src/action.go b/src/action.go index 53e8424..9616209 100644 --- a/src/action.go +++ b/src/action.go @@ -114,13 +114,7 @@ func sftpUploadFile(targetName, localPath, remotePath string, cfg RaspiConfig) b } func restartShow(targetName string, targetMode int, cfg RaspiConfig) bool { - const restartPresentation string = "systemctl --user restart presentation" - 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" + 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 var err error sshClient, err := createSSHClient(targetName, cfg) @@ -138,18 +132,17 @@ func restartShow(targetName string, targetMode int, cfg RaspiConfig) bool { } defer session.Close() + var servName string switch targetMode { case 1: - log.Println("Configuring application workflow: 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 + servName = "presentation" case 2: - log.Println("Configuring application workflow: 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 + servName = "video" } + log.Println("Configuring application workflow:", servName) + + stitchCmd := switchCmd + servName + _, err = runSSHCommand(sshClient, stitchCmd) if err != nil { log.Printf("Failed to restart the show over SSH: %v", err) -- 2.49.1 From 52b46a6f2e9297cd906460993c5abdccf1cae4bb Mon Sep 17 00:00:00 2001 From: DaanSelen Date: Fri, 6 Feb 2026 16:37:33 +0100 Subject: [PATCH 6/7] feat: wrapper fix for moving and restarting media --- dyn-com-install.sh | 3 +++ install.sh | 19 +++++++++++++++---- manage.sh | 14 +++++++++++--- service-files/video.service | 2 +- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/dyn-com-install.sh b/dyn-com-install.sh index 7a97a13..6c8b650 100755 --- a/dyn-com-install.sh +++ b/dyn-com-install.sh @@ -56,9 +56,12 @@ sed 's/\$/\\$/g' ./manage.sh >> "$install_file" echo -e "\nEOF\n" >> ./$install_file cat >> ./$install_file << EOF +echo "alias userjournal='journalctl --user-unit'" /home/\${userland_name}/.bashrc + 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!" diff --git a/install.sh b/install.sh index 706b478..97be970 100644 --- a/install.sh +++ b/install.sh @@ -55,9 +55,9 @@ After=graphical-session.target [Service] Type=simple Environment=DISPLAY=:0 +Environment=QT_QPA_PLATFORM=xcb WorkingDirectory=/opt/raspscreen ExecStart=/opt/raspscreen/bin/manage.sh start video --foreground -KillSignal=SIGKILL Restart=on-failure RestartSec=2 @@ -120,9 +120,13 @@ case "\$3" in if [[ "\$2" == "presentation" ]]; then echo "Finding and moving media..." media_file=\$(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \)) + echo "New media file: \$media_file" - cp "\$media_file" /opt/raspscreen/media/current + old_file=\$(find /opt/raspscreen/media/current \( -name "*.pptx" -o -name "*.odp" \)) + echo "Old file: \$old_file" + cp -v "\$media_file" /opt/raspscreen/media/current current_media=\$(find /opt/raspscreen/media/current \( -name "*.pptx" -o -name "*.odp" \)) + echo "Prepared media: \$current_media" if [[ -z "\$current_media" ]]; then echo "No compatible media file found. Wrong mode?" @@ -134,10 +138,14 @@ case "\$3" in 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" \)) + media_file=\$(find /opt/raspscreen/media -path /opt/raspscreen/media/current -prune -o \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \) -print) + echo "New media file: \$media_file" - cp "\$media_file" /opt/raspscreen/media/current + old_file=\$(find /opt/raspscreen/media/current \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \)) + echo "Old file: \$old_file" + cp -v "\$media_file" /opt/raspscreen/media/current current_media=\$(find /opt/raspscreen/media/current \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \)) + echo "Prepared media: \$current_media" if [[ -z "\$current_media" ]]; then echo "No compatible media file found. Wrong mode?" @@ -187,9 +195,12 @@ fi exit 0 EOF +echo "alias userjournal='journalctl --user-unit'" /home/${userland_name}/.bashrc + 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!" diff --git a/manage.sh b/manage.sh index 115bf57..1baee7c 100755 --- a/manage.sh +++ b/manage.sh @@ -51,9 +51,13 @@ case "$3" in if [[ "$2" == "presentation" ]]; then echo "Finding and moving media..." media_file=$(find /opt/raspscreen/media \( -name "*.pptx" -o -name "*.odp" \)) + echo "New media file: $media_file" - cp "$media_file" /opt/raspscreen/media/current + old_file=$(find /opt/raspscreen/media/current \( -name "*.pptx" -o -name "*.odp" \)) + echo "Old file: $old_file" + cp -v "$media_file" /opt/raspscreen/media/current current_media=$(find /opt/raspscreen/media/current \( -name "*.pptx" -o -name "*.odp" \)) + echo "Prepared media: $current_media" if [[ -z "$current_media" ]]; then echo "No compatible media file found. Wrong mode?" @@ -65,10 +69,14 @@ case "$3" in 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" \)) + media_file=$(find /opt/raspscreen/media -path /opt/raspscreen/media/current -prune -o \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \) -print) + echo "New media file: $media_file" - cp "$media_file" /opt/raspscreen/media/current + old_file=$(find /opt/raspscreen/media/current \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \)) + echo "Old file: $old_file" + cp -v "$media_file" /opt/raspscreen/media/current current_media=$(find /opt/raspscreen/media/current \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \)) + echo "Prepared media: $current_media" if [[ -z "$current_media" ]]; then echo "No compatible media file found. Wrong mode?" diff --git a/service-files/video.service b/service-files/video.service index 39eb977..bc80510 100644 --- a/service-files/video.service +++ b/service-files/video.service @@ -6,9 +6,9 @@ After=graphical-session.target [Service] Type=simple Environment=DISPLAY=:0 +Environment=QT_QPA_PLATFORM=xcb WorkingDirectory=/opt/raspscreen ExecStart=/opt/raspscreen/bin/manage.sh start video --foreground -KillSignal=SIGKILL Restart=on-failure RestartSec=2 -- 2.49.1 From 8ba479e45abdc1a394bb671b60831fe6f787ac28 Mon Sep 17 00:00:00 2001 From: DaanSelen Date: Mon, 9 Feb 2026 14:35:24 +0100 Subject: [PATCH 7/7] feat: add better handling --- install.sh | 8 +++++--- manage.sh | 8 +++++--- src/draw.go | 7 ++++++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/install.sh b/install.sh index 97be970..b2c709c 100644 --- a/install.sh +++ b/install.sh @@ -119,12 +119,13 @@ case "\$3" in 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 -path /opt/raspscreen/media/current -prune -o \( -name "*.pptx" -o -name "*.odp" \) -type f -print) echo "New media file: \$media_file" old_file=\$(find /opt/raspscreen/media/current \( -name "*.pptx" -o -name "*.odp" \)) echo "Old file: \$old_file" - cp -v "\$media_file" /opt/raspscreen/media/current + echo "Copying new media into staging area..." + cp "\$media_file" /opt/raspscreen/media/current current_media=\$(find /opt/raspscreen/media/current \( -name "*.pptx" -o -name "*.odp" \)) echo "Prepared media: \$current_media" @@ -143,7 +144,8 @@ case "\$3" in old_file=\$(find /opt/raspscreen/media/current \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \)) echo "Old file: \$old_file" - cp -v "\$media_file" /opt/raspscreen/media/current + echo "Copying new media into staging area..." + 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" \)) echo "Prepared media: \$current_media" diff --git a/manage.sh b/manage.sh index 1baee7c..337c3f8 100755 --- a/manage.sh +++ b/manage.sh @@ -50,12 +50,13 @@ case "$3" in 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 -path /opt/raspscreen/media/current -prune -o \( -name "*.pptx" -o -name "*.odp" \) -type f -print) echo "New media file: $media_file" old_file=$(find /opt/raspscreen/media/current \( -name "*.pptx" -o -name "*.odp" \)) echo "Old file: $old_file" - cp -v "$media_file" /opt/raspscreen/media/current + echo "Copying new media into staging area..." + cp "$media_file" /opt/raspscreen/media/current current_media=$(find /opt/raspscreen/media/current \( -name "*.pptx" -o -name "*.odp" \)) echo "Prepared media: $current_media" @@ -74,7 +75,8 @@ case "$3" in old_file=$(find /opt/raspscreen/media/current \( -name "*.mp4" -o -name "*.mkv" -o -name "*.mov" -o -name "*.webm" \)) echo "Old file: $old_file" - cp -v "$media_file" /opt/raspscreen/media/current + echo "Copying new media into staging area..." + 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" \)) echo "Prepared media: $current_media" diff --git a/src/draw.go b/src/draw.go index a2856a8..5346655 100644 --- a/src/draw.go +++ b/src/draw.go @@ -137,6 +137,8 @@ func drawTargetSection(raspiNames []string, raspiTarget *string, uploadBtn, relo previousTarget = selected *raspiTarget = selected + uploadBtn.Disable() + reloadBtn.Disable() refreshButtons(verifyBtn, uploadBtn, reloadBtn) }) @@ -246,8 +248,11 @@ func drawFooter(app fyne.App, raspiTarget, localUploadPath *string, targetMode * // Configuration of the bottom of the application var uploadBtn *widget.Button + var reloadBtn *widget.Button + uploadBtn = widget.NewButton("Upload File", func() { uploadBtn.Importance = widget.HighImportance + reloadBtn.Disable() refreshButtons(uploadBtn) go func() { @@ -255,6 +260,7 @@ func drawFooter(app fyne.App, raspiTarget, localUploadPath *string, targetMode * if ok { flashColor(uploadBtn, FlashSuccess) + reloadBtn.Enable() } else { flashColor(uploadBtn, FlashError) } @@ -265,7 +271,6 @@ func drawFooter(app fyne.App, raspiTarget, localUploadPath *string, targetMode * uploadBtn, ) - var reloadBtn *widget.Button reloadBtn = widget.NewButton("Restart Program", func() { reloadBtn.Importance = widget.HighImportance refreshButtons(uploadBtn) -- 2.49.1