More work on the speech selector.
This commit is contained in:
@@ -104,6 +104,13 @@ EndSection
|
||||
EOF
|
||||
}
|
||||
|
||||
restart_fenrir_speech() {
|
||||
if systemctl is-active --quiet fenrirscreenreader.service; then
|
||||
killall speech-dispatcher 2>/dev/null || true
|
||||
systemctl restart fenrirscreenreader.service
|
||||
fi
|
||||
}
|
||||
|
||||
set_timezone() {
|
||||
# Get the list of timezones
|
||||
mapfile -t regions < <(timedatectl --no-pager list-timezones | cut -d '/' -f1 | sort -u)
|
||||
@@ -136,8 +143,8 @@ set_timezone() {
|
||||
if read_yes_no "Would you like to switch Fenrir to laptop layout?"; then
|
||||
sed -i 's/=desktop/=laptop/' /etc/fenrirscreenreader/settings/settings.conf
|
||||
clear
|
||||
systemctl restart fenrirscreenreader.service
|
||||
fi
|
||||
restart_fenrir_speech
|
||||
|
||||
if command -v i3 > /dev/null 2>&1 && systemctl list-unit-files nodm.service > /dev/null 2>&1; then
|
||||
if read_yes_no "Will this Pi be connected to a physical screen?"; then
|
||||
|
||||
@@ -6,9 +6,11 @@ speechConfig="${STORMUX_SPEECH_CONFIG:-/etc/speech-dispatcher/speechd.conf}"
|
||||
selectionFile=""
|
||||
spdSayCommand="${STORMUX_SPD_SAY:-spd-say}"
|
||||
systemctlCommand="${STORMUX_SYSTEMCTL:-systemctl}"
|
||||
killallCommand="${STORMUX_KILLALL:-killall}"
|
||||
socatCommand="${STORMUX_SOCAT:-socat}"
|
||||
fenrirSocket="${STORMUX_FENRIR_SOCKET:-/tmp/fenrirscreenreader-daemon.sock}"
|
||||
scriptPath="$(readlink -f "$0")"
|
||||
runtimeDir="${STORMUX_RUNTIME_DIR:-/run/stormux}"
|
||||
fenrirSpeechMuted=false
|
||||
|
||||
is_safe_module() {
|
||||
[[ "$1" =~ ^[A-Za-z0-9][A-Za-z0-9_.-]*$ ]]
|
||||
@@ -149,16 +151,30 @@ announce_failure() {
|
||||
printf '%s\n' "$message" >&2
|
||||
}
|
||||
|
||||
restart_speech() {
|
||||
"${sudoCommand[@]}" "$killallCommand" speech-dispatcher
|
||||
set_fenrir_speech() {
|
||||
local enabled="$1"
|
||||
|
||||
printf 'setting set speech#enabled=%s\n' "$enabled" | \
|
||||
"$socatCommand" - UNIX-CLIENT:"$fenrirSocket" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
restart_fenrir_if_active() {
|
||||
if "$systemctlCommand" is-active --quiet fenrirscreenreader.service 2>/dev/null; then
|
||||
"${sudoCommand[@]}" "$systemctlCommand" restart fenrirscreenreader.service
|
||||
mute_fenrir_speech() {
|
||||
if "$systemctlCommand" is-active --quiet fenrirscreenreader.service 2>/dev/null && \
|
||||
set_fenrir_speech False; then
|
||||
fenrirSpeechMuted=true
|
||||
fi
|
||||
}
|
||||
|
||||
restore_fenrir_speech() {
|
||||
if [[ "$fenrirSpeechMuted" == true ]]; then
|
||||
set_fenrir_speech True || true
|
||||
fenrirSpeechMuted=false
|
||||
fi
|
||||
}
|
||||
|
||||
trap restore_fenrir_speech EXIT
|
||||
trap 'exit 130' HUP INT TERM
|
||||
|
||||
discover_modules() {
|
||||
local output line candidate
|
||||
local skippedHeading=false
|
||||
@@ -246,6 +262,7 @@ read_menu_key() {
|
||||
|
||||
declare -a modules=()
|
||||
previousModule="$(configured_module)"
|
||||
mute_fenrir_speech
|
||||
if ! discover_modules; then
|
||||
announce_failure "$previousModule"
|
||||
exit 0
|
||||
@@ -260,7 +277,7 @@ if ! selectedIndex="$(module_index "$previousModule")"; then
|
||||
fi
|
||||
|
||||
draw_menu
|
||||
"$spdSayCommand" "Speech engine selection. ${modules[$selectedIndex]} is highlighted. Use up and down to preview engines, Enter to select, or Escape to keep the current engine." >/dev/null 2>&1 || true
|
||||
"$spdSayCommand" "Use up and down arrows to select the default voice for this computer. ${modules[$selectedIndex]} is highlighted. Press Enter to select, or Escape to keep the current voice." >/dev/null 2>&1 || true
|
||||
|
||||
while true; do
|
||||
if ! keyName="$(read_menu_key)"; then
|
||||
@@ -303,19 +320,9 @@ if ! "${sudoCommand[@]}" "$scriptPath" --apply-module "$selectedModule" "$speech
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! restart_speech || ! restart_fenrir_if_active; then
|
||||
"${sudoCommand[@]}" "$scriptPath" --restore-config "$speechConfig" "$backupFile" >/dev/null 2>&1 || true
|
||||
restart_speech >/dev/null 2>&1 || true
|
||||
restart_fenrir_if_active >/dev/null 2>&1 || true
|
||||
announce_failure "$previousModule"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -n "$selectionFile" ]]; then
|
||||
if ! "${sudoCommand[@]}" "$scriptPath" --write-selection "$selectedModule" "$selectionFile"; then
|
||||
"${sudoCommand[@]}" "$scriptPath" --restore-config "$speechConfig" "$backupFile" >/dev/null 2>&1 || true
|
||||
restart_speech >/dev/null 2>&1 || true
|
||||
restart_fenrir_if_active >/dev/null 2>&1 || true
|
||||
announce_failure "$previousModule"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@@ -36,12 +36,10 @@ fi
|
||||
exit 0
|
||||
EOF
|
||||
|
||||
cat > "$mockBin/killall" <<'EOF'
|
||||
cat > "$mockBin/socat" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
printf 'killall %s\n' "$*" >> "$MOCK_LOG"
|
||||
if [[ "${MOCK_KILLALL_FAIL:-no}" == "yes" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
read -r command
|
||||
printf 'socat %s: %s\n' "$*" "$command" >> "$MOCK_LOG"
|
||||
EOF
|
||||
|
||||
cat > "$mockBin/systemctl" <<'EOF'
|
||||
@@ -104,13 +102,12 @@ run_selector() {
|
||||
MOCK_LOG="$mockLog" \
|
||||
MOCK_MODULES="$modulesFile" \
|
||||
MOCK_DISCOVERY_STATUS="${MOCK_DISCOVERY_STATUS:-0}" \
|
||||
MOCK_KILLALL_FAIL="${MOCK_KILLALL_FAIL:-no}" \
|
||||
MOCK_FENRIR_ACTIVE="${MOCK_FENRIR_ACTIVE:-no}" \
|
||||
MOCK_SUDO_FAIL_WRITE="${MOCK_SUDO_FAIL_WRITE:-no}" \
|
||||
STORMUX_SPEECH_CONFIG="$configFile" \
|
||||
STORMUX_RUNTIME_DIR="$caseDir/runtime" \
|
||||
STORMUX_SPD_SAY=spd-say \
|
||||
STORMUX_KILLALL=killall \
|
||||
STORMUX_SOCAT=socat \
|
||||
STORMUX_SYSTEMCTL=systemctl \
|
||||
"$selector" --selection-file "$selectionFile" >/dev/null
|
||||
}
|
||||
@@ -122,7 +119,12 @@ MOCK_FENRIR_ACTIVE=yes run_selector '\n'
|
||||
assert_equals 1 "$(grep -c '^DefaultModule ' "$configFile")" "initial selection should leave one active default"
|
||||
assert_file_contains "$configFile" '^DefaultModule rhvoice$' "initial selection should retain rhvoice"
|
||||
assert_equals rhvoice "$(< "$selectionFile")" "initial selection should be recorded"
|
||||
assert_file_contains "$mockLog" '^systemctl restart fenrirscreenreader\.service$' "active Fenrir should restart"
|
||||
assert_file_contains "$mockLog" 'speech#enabled=False' "active Fenrir speech should be muted"
|
||||
assert_file_contains "$mockLog" 'speech#enabled=True' "active Fenrir speech should be restored"
|
||||
assert_file_contains "$mockLog" 'Use up and down arrows to select the default voice for this computer\.' "the selector should voice its own instructions"
|
||||
if grep -q '^systemctl restart ' "$mockLog"; then
|
||||
fail "the selector should defer the Fenrir restart until after layout selection"
|
||||
fi
|
||||
|
||||
# Down previews and selects the next module.
|
||||
reset_case
|
||||
@@ -163,16 +165,10 @@ fi
|
||||
# A missing configuration simulates failed persistence and remains nonfatal.
|
||||
reset_case
|
||||
rm -f "$configFile"
|
||||
run_selector '\n'
|
||||
MOCK_FENRIR_ACTIVE=yes run_selector '\n'
|
||||
assert_file_absent "$selectionFile" "failed persistence should not record a selection"
|
||||
assert_file_contains "$mockLog" 'selection failed' "failed persistence should be announced"
|
||||
|
||||
# A restart failure restores the byte-for-byte original configuration.
|
||||
reset_case
|
||||
cp "$configFile" "$caseDir/original.conf"
|
||||
MOCK_KILLALL_FAIL=yes run_selector '\033[B\n'
|
||||
cmp -s "$configFile" "$caseDir/original.conf" || fail "restart failure should roll back the configuration"
|
||||
assert_file_absent "$selectionFile" "restart failure should not record a selection"
|
||||
assert_file_contains "$mockLog" 'speech#enabled=True' "failed persistence should restore Fenrir speech"
|
||||
|
||||
# Failure to record the live choice also rolls the system configuration back.
|
||||
reset_case
|
||||
|
||||
@@ -37,6 +37,14 @@ set_timezone() {
|
||||
ln -sf /usr/share/zoneinfo/"${region}"/"${city}" /etc/localtime
|
||||
timedatectl set-ntp true
|
||||
}
|
||||
|
||||
restart_fenrir_speech() {
|
||||
if systemctl is-active --quiet fenrirscreenreader.service; then
|
||||
killall speech-dispatcher 2>/dev/null || true
|
||||
systemctl restart fenrirscreenreader.service
|
||||
fi
|
||||
}
|
||||
|
||||
# Offer to switch fenrir layout.
|
||||
echo "Would you like to switch Fenrir to laptop layout?"
|
||||
echo "Press y for yes or n for no followed by enter."
|
||||
@@ -45,8 +53,8 @@ continue="${continue::1}"
|
||||
if [[ "${continue,}" == "y" ]];then
|
||||
sed -i 's/=desktop/=laptop/' /etc/fenrirscreenreader/settings/settings.conf
|
||||
clear
|
||||
systemctl restart fenrirscreenreader.service
|
||||
fi
|
||||
restart_fenrir_speech
|
||||
|
||||
if ! ping -c1 stormux.org &> /dev/null ; then
|
||||
echo "No internet connection detected. Press enter to open NetworkManager."
|
||||
|
||||
@@ -6,9 +6,11 @@ speechConfig="${STORMUX_SPEECH_CONFIG:-/etc/speech-dispatcher/speechd.conf}"
|
||||
selectionFile=""
|
||||
spdSayCommand="${STORMUX_SPD_SAY:-spd-say}"
|
||||
systemctlCommand="${STORMUX_SYSTEMCTL:-systemctl}"
|
||||
killallCommand="${STORMUX_KILLALL:-killall}"
|
||||
socatCommand="${STORMUX_SOCAT:-socat}"
|
||||
fenrirSocket="${STORMUX_FENRIR_SOCKET:-/tmp/fenrirscreenreader-daemon.sock}"
|
||||
scriptPath="$(readlink -f "$0")"
|
||||
runtimeDir="${STORMUX_RUNTIME_DIR:-/run/stormux}"
|
||||
fenrirSpeechMuted=false
|
||||
|
||||
is_safe_module() {
|
||||
[[ "$1" =~ ^[A-Za-z0-9][A-Za-z0-9_.-]*$ ]]
|
||||
@@ -149,16 +151,30 @@ announce_failure() {
|
||||
printf '%s\n' "$message" >&2
|
||||
}
|
||||
|
||||
restart_speech() {
|
||||
"${sudoCommand[@]}" "$killallCommand" speech-dispatcher
|
||||
set_fenrir_speech() {
|
||||
local enabled="$1"
|
||||
|
||||
printf 'setting set speech#enabled=%s\n' "$enabled" | \
|
||||
"$socatCommand" - UNIX-CLIENT:"$fenrirSocket" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
restart_fenrir_if_active() {
|
||||
if "$systemctlCommand" is-active --quiet fenrirscreenreader.service 2>/dev/null; then
|
||||
"${sudoCommand[@]}" "$systemctlCommand" restart fenrirscreenreader.service
|
||||
mute_fenrir_speech() {
|
||||
if "$systemctlCommand" is-active --quiet fenrirscreenreader.service 2>/dev/null && \
|
||||
set_fenrir_speech False; then
|
||||
fenrirSpeechMuted=true
|
||||
fi
|
||||
}
|
||||
|
||||
restore_fenrir_speech() {
|
||||
if [[ "$fenrirSpeechMuted" == true ]]; then
|
||||
set_fenrir_speech True || true
|
||||
fenrirSpeechMuted=false
|
||||
fi
|
||||
}
|
||||
|
||||
trap restore_fenrir_speech EXIT
|
||||
trap 'exit 130' HUP INT TERM
|
||||
|
||||
discover_modules() {
|
||||
local output line candidate
|
||||
local skippedHeading=false
|
||||
@@ -246,6 +262,7 @@ read_menu_key() {
|
||||
|
||||
declare -a modules=()
|
||||
previousModule="$(configured_module)"
|
||||
mute_fenrir_speech
|
||||
if ! discover_modules; then
|
||||
announce_failure "$previousModule"
|
||||
exit 0
|
||||
@@ -260,7 +277,7 @@ if ! selectedIndex="$(module_index "$previousModule")"; then
|
||||
fi
|
||||
|
||||
draw_menu
|
||||
"$spdSayCommand" "Speech engine selection. ${modules[$selectedIndex]} is highlighted. Use up and down to preview engines, Enter to select, or Escape to keep the current engine." >/dev/null 2>&1 || true
|
||||
"$spdSayCommand" "Use up and down arrows to select the default voice for this computer. ${modules[$selectedIndex]} is highlighted. Press Enter to select, or Escape to keep the current voice." >/dev/null 2>&1 || true
|
||||
|
||||
while true; do
|
||||
if ! keyName="$(read_menu_key)"; then
|
||||
@@ -303,19 +320,9 @@ if ! "${sudoCommand[@]}" "$scriptPath" --apply-module "$selectedModule" "$speech
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! restart_speech || ! restart_fenrir_if_active; then
|
||||
"${sudoCommand[@]}" "$scriptPath" --restore-config "$speechConfig" "$backupFile" >/dev/null 2>&1 || true
|
||||
restart_speech >/dev/null 2>&1 || true
|
||||
restart_fenrir_if_active >/dev/null 2>&1 || true
|
||||
announce_failure "$previousModule"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -n "$selectionFile" ]]; then
|
||||
if ! "${sudoCommand[@]}" "$scriptPath" --write-selection "$selectedModule" "$selectionFile"; then
|
||||
"${sudoCommand[@]}" "$scriptPath" --restore-config "$speechConfig" "$backupFile" >/dev/null 2>&1 || true
|
||||
restart_speech >/dev/null 2>&1 || true
|
||||
restart_fenrir_if_active >/dev/null 2>&1 || true
|
||||
announce_failure "$previousModule"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user