Make sure expected directories exist in home.
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Create Stormux user directories
|
||||||
|
RequiresMountsFor=/home/stormux
|
||||||
|
After=local-fs.target user@1000.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
User=stormux
|
||||||
|
Environment=HOME=/home/stormux
|
||||||
|
ExecStart=/usr/bin/xdg-user-dirs-update
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -5,31 +5,47 @@ download_with_fallback() {
|
|||||||
local outputPath="$1"
|
local outputPath="$1"
|
||||||
local sourceUrl="$2"
|
local sourceUrl="$2"
|
||||||
local errorFile=""
|
local errorFile=""
|
||||||
|
local curlArgs=(
|
||||||
|
--fail
|
||||||
|
--show-error
|
||||||
|
--location
|
||||||
|
--connect-timeout 20
|
||||||
|
--speed-limit 1024
|
||||||
|
--speed-time 30
|
||||||
|
--retry 3
|
||||||
|
--retry-connrefused
|
||||||
|
--retry-delay 2
|
||||||
|
)
|
||||||
local curlExitCode=0
|
local curlExitCode=0
|
||||||
local retryExitCode=0
|
local retryExitCode=0
|
||||||
local fallbackExitCode=0
|
local fallbackExitCode=0
|
||||||
local wgetExitCode=0
|
local wgetExitCode=0
|
||||||
|
local totalBytes=0
|
||||||
|
|
||||||
downloadAttemptExitCodes=""
|
downloadAttemptExitCodes=""
|
||||||
downloadErrorLog=""
|
downloadErrorLog=""
|
||||||
|
|
||||||
errorFile="$(mktemp)" || return 1
|
errorFile="$(mktemp)" || return 1
|
||||||
|
totalBytes="$(get_remote_file_size "${sourceUrl}")"
|
||||||
|
|
||||||
if curl -L4 -C - --retry 10 --output "${outputPath}" "${sourceUrl}" 2> "${errorFile}"; then
|
printf 'Trying curl with resume support: %s\n' "${sourceUrl}" >&2
|
||||||
|
if run_download_command "${outputPath}" "${totalBytes}" "${errorFile}" curl -4 -C - "${curlArgs[@]}" --output "${outputPath}" "${sourceUrl}"; then
|
||||||
rm -f "${errorFile}"
|
rm -f "${errorFile}"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
curlExitCode=$?
|
curlExitCode=$?
|
||||||
|
|
||||||
rm -f "${outputPath}"
|
rm -f "${outputPath}"
|
||||||
if curl -L4 --retry 10 --output "${outputPath}" "${sourceUrl}" 2>> "${errorFile}"; then
|
printf 'Trying fresh IPv4 curl download: %s\n' "${sourceUrl}" >&2
|
||||||
|
if run_download_command "${outputPath}" "${totalBytes}" "${errorFile}" curl -4 "${curlArgs[@]}" --output "${outputPath}" "${sourceUrl}"; then
|
||||||
rm -f "${errorFile}"
|
rm -f "${errorFile}"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
retryExitCode=$?
|
retryExitCode=$?
|
||||||
|
|
||||||
rm -f "${outputPath}"
|
rm -f "${outputPath}"
|
||||||
if curl -L --retry 10 --output "${outputPath}" "${sourceUrl}" 2>> "${errorFile}"; then
|
printf 'Trying fresh curl download with any address family: %s\n' "${sourceUrl}" >&2
|
||||||
|
if run_download_command "${outputPath}" "${totalBytes}" "${errorFile}" curl "${curlArgs[@]}" --output "${outputPath}" "${sourceUrl}"; then
|
||||||
rm -f "${errorFile}"
|
rm -f "${errorFile}"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -37,7 +53,8 @@ download_with_fallback() {
|
|||||||
|
|
||||||
if command -v wget > /dev/null 2>&1; then
|
if command -v wget > /dev/null 2>&1; then
|
||||||
rm -f "${outputPath}"
|
rm -f "${outputPath}"
|
||||||
if wget --tries=10 --output-document="${outputPath}" "${sourceUrl}" 2>> "${errorFile}"; then
|
printf 'Trying wget fallback: %s\n' "${sourceUrl}" >&2
|
||||||
|
if run_download_command "${outputPath}" "${totalBytes}" "${errorFile}" wget --tries=3 --timeout=20 --read-timeout=30 --output-document="${outputPath}" "${sourceUrl}"; then
|
||||||
rm -f "${errorFile}"
|
rm -f "${errorFile}"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -58,6 +75,102 @@ download_with_fallback() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_remote_file_size() {
|
||||||
|
local sourceUrl="$1"
|
||||||
|
local headerOutput
|
||||||
|
|
||||||
|
headerOutput="$(curl --fail --silent --show-error --location --head --max-redirs 10 --max-time 20 "${sourceUrl}" 2> /dev/null || true)"
|
||||||
|
awk '
|
||||||
|
BEGIN { IGNORECASE = 1 }
|
||||||
|
/^content-length:/ {
|
||||||
|
gsub("\r", "", $2)
|
||||||
|
if ($2 ~ /^[0-9]+$/) {
|
||||||
|
contentLength = $2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
if (contentLength != "") {
|
||||||
|
print contentLength
|
||||||
|
} else {
|
||||||
|
print 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' <<< "${headerOutput}"
|
||||||
|
}
|
||||||
|
|
||||||
|
beep_download_progress() {
|
||||||
|
local percent="$1"
|
||||||
|
local frequency
|
||||||
|
|
||||||
|
[[ "${STORMUX_DOWNLOAD_BEEPS:-1}" == "1" ]] || return 0
|
||||||
|
command -v play > /dev/null 2>&1 || return 0
|
||||||
|
|
||||||
|
frequency="$((220 + (percent * 7)))"
|
||||||
|
play -q -n synth 0.06 sine "${frequency}" vol 0.12 > /dev/null 2>&1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor_download_progress() {
|
||||||
|
local outputPath="$1"
|
||||||
|
local totalBytes="$2"
|
||||||
|
local doneFile="$3"
|
||||||
|
local currentBytes=0
|
||||||
|
local percent=0
|
||||||
|
local lastAnnouncedPercent=-10
|
||||||
|
local tickCount=0
|
||||||
|
|
||||||
|
while [[ ! -e "$doneFile" ]]; do
|
||||||
|
if [[ -f "$outputPath" ]]; then
|
||||||
|
currentBytes="$(stat -c '%s' "$outputPath" 2> /dev/null || printf '0')"
|
||||||
|
else
|
||||||
|
currentBytes=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$totalBytes" -gt 0 ]]; then
|
||||||
|
percent="$(((currentBytes * 100) / totalBytes))"
|
||||||
|
if [[ "$percent" -gt 100 ]]; then
|
||||||
|
percent=100
|
||||||
|
fi
|
||||||
|
if [[ "$percent" -ge $((lastAnnouncedPercent + 10)) ]]; then
|
||||||
|
printf 'Downloaded %s%% (%s/%s bytes)\n' "$percent" "$currentBytes" "$totalBytes" >&2
|
||||||
|
beep_download_progress "$percent"
|
||||||
|
lastAnnouncedPercent="$percent"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
tickCount="$((tickCount + 1))"
|
||||||
|
if [[ "$tickCount" -ge 5 ]]; then
|
||||||
|
printf 'Downloaded %s bytes\n' "$currentBytes" >&2
|
||||||
|
beep_download_progress 50
|
||||||
|
tickCount=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
run_download_command() {
|
||||||
|
local outputPath="$1"
|
||||||
|
local totalBytes="$2"
|
||||||
|
local errorFile="$3"
|
||||||
|
local doneFile
|
||||||
|
local monitorPid
|
||||||
|
local commandStatus=0
|
||||||
|
shift 3
|
||||||
|
|
||||||
|
doneFile="$(mktemp)" || return 1
|
||||||
|
rm -f "$doneFile"
|
||||||
|
monitor_download_progress "$outputPath" "$totalBytes" "$doneFile" &
|
||||||
|
monitorPid="$!"
|
||||||
|
|
||||||
|
"$@" 2> >(tee -a "$errorFile" >&2)
|
||||||
|
commandStatus="$?"
|
||||||
|
|
||||||
|
touch "$doneFile"
|
||||||
|
wait "$monitorPid" 2> /dev/null || true
|
||||||
|
rm -f "$doneFile"
|
||||||
|
|
||||||
|
return "$commandStatus"
|
||||||
|
}
|
||||||
|
|
||||||
validate_downloaded_cache_file() {
|
validate_downloaded_cache_file() {
|
||||||
local dest="$1"
|
local dest="$1"
|
||||||
local downloadError=0
|
local downloadError=0
|
||||||
|
|||||||
@@ -583,11 +583,13 @@ class VoicedMenu:
|
|||||||
# Add the appropriate items based on current status for each service
|
# Add the appropriate items based on current status for each service
|
||||||
for friendlyName, serviceName in self.systemMenuServices.items():
|
for friendlyName, serviceName in self.systemMenuServices.items():
|
||||||
isActive = self.check_service_status(serviceName)
|
isActive = self.check_service_status(serviceName)
|
||||||
|
startLabel = "Start" if friendlyName == "Fenrir Screen Reader" else "Enable"
|
||||||
|
stopLabel = "Stop" if friendlyName == "Fenrir Screen Reader" else "Disable"
|
||||||
if isActive:
|
if isActive:
|
||||||
self.add_item("System", f"Disable {friendlyName}",
|
self.add_item("System", f"{stopLabel} {friendlyName}",
|
||||||
lambda fn=friendlyName: self.toggle_service(fn))
|
lambda fn=friendlyName: self.toggle_service(fn))
|
||||||
else:
|
else:
|
||||||
self.add_item("System", f"Enable {friendlyName}",
|
self.add_item("System", f"{startLabel} {friendlyName}",
|
||||||
lambda fn=friendlyName: self.toggle_service(fn))
|
lambda fn=friendlyName: self.toggle_service(fn))
|
||||||
|
|
||||||
def install_and_launch(self, executable_name, launch_mode="gui"):
|
def install_and_launch(self, executable_name, launch_mode="gui"):
|
||||||
|
|||||||
Reference in New Issue
Block a user