updater: allow selecting what to update

pull/684/head
Botspot 4 years ago
parent e17bc06b7d
commit aa60e839d3

@ -7,6 +7,13 @@ function error {
exit 1 exit 1
} }
#for the will_reinstall() and list_intersect() functions
source "${DIRECTORY}/api" || error "failed to source ${DIRECTORY}/api"
#NOTE TO SELF BOTSPOT: REMOVE THE FASTMODE VARIABLE SETTING!!!
#fastmode=1
{ # Determine if checking for updates today
lastupdatecheck="$(cat "${DIRECTORY}/data/last-update-check")" lastupdatecheck="$(cat "${DIRECTORY}/data/last-update-check")"
if [ -z $lastupdatecheck ];then if [ -z $lastupdatecheck ];then
echo "Warning: ${DIRECTORY}/data/last-update-check does not exist!" echo "Warning: ${DIRECTORY}/data/last-update-check does not exist!"
@ -43,6 +50,11 @@ if [ "$lastupdatecheck" -gt "$(date +%j)" ];then
nocheck=0 nocheck=0
fi fi
#forcibly check if fastmode variable is 1
if [ "$fastmode" == 1 ];then
nocheck=0
fi
#hidden flag: if $1 is 'onboot', then check for updates only for those apps that are installed. #hidden flag: if $1 is 'onboot', then check for updates only for those apps that are installed.
onboot="$1" onboot="$1"
if [ "$onboot" == 'onboot' ] || [ "$onboot" == 'installedonly' ];then if [ "$onboot" == 'onboot' ] || [ "$onboot" == 'installedonly' ];then
@ -59,20 +71,26 @@ fi
if [ $nocheck == 1 ];then if [ $nocheck == 1 ];then
echo "Won"\'"t check for updates today, because of the update interval is set to $updateinterval in Settings. echo "Won"\'"t check for updates today, because of the update interval is set to $updateinterval in Settings.
To forcibly check for updates now, press any key within the next 20 seconds." To forcibly check for updates now, press any key within the next 20 seconds."
read -n 1 -t 20 || exit 0 read -n 1 -t 20 || exit 0
echo '' echo ''
fi fi
#write today's date to file. Format is "number of days since jan 1" #write today's date to file. Format is "number of days since jan 1"
echo "$(date +%j)" > "${DIRECTORY}/data/last-update-check" echo "$(date +%j)" > "${DIRECTORY}/data/last-update-check"
}
#generate app update status info #if fastmode is 1, then rely on previously gathered updatable app information. This information is located in data/update-status.
updatable="$("${DIRECTORY}/manage" check-all)" if [ "$fastmode" == 1 ];then
updatable="$("${DIRECTORY}/manage" check-all nogenerate 2>/dev/null)"
else
#otherwise, re-download apps to update folder and hash them all to determine which apps can be updated
updatable="$("${DIRECTORY}/manage" check-all)"
fi
[ $? -ne 0 ] && error "check-all failed! Full output: $updatable" [ $? -ne 0 ] && error "check-all failed! Full output: $updatable"
#shorten to last line #shorten to last line
updatable="$(echo "$updatable" | tail -1)" updatable="$(echo "$updatable")"
if [ "$updatable" == '.' ];then if [ "$updatable" == '.' ];then
updatable='' updatable=''
fi fi
@ -80,80 +98,81 @@ fi
echo "updatable: $updatable" echo "updatable: $updatable"
#if check-all succeeded to download the repo to the update folder #if check-all succeeded to download the repo to the update folder
if [ -d "${DIRECTORY}/update" ];then if [ ! -d "${DIRECTORY}/update" ];then
error "${DIRECTORY}/update does not exist. Most likely there is no Internet connection."
#mainfiles="$(echo -e "$(ls -Rp "${DIRECTORY}/update/pi-apps")\n$(ls -Rp "${DIRECTORY}")" | grep -v '/' | sort | uniq | tr '\n' '|')" fi
#list all files in update folder #mainfiles="$(echo -e "$(ls -Rp "${DIRECTORY}/update/pi-apps")\n$(ls -Rp "${DIRECTORY}")" | grep -v '/' | sort | uniq | tr '\n' '|')"
cd "${DIRECTORY}/update/pi-apps" || error "Failed to enter update directory!"
updatefiles="$(find . -type f | cut -c 3- | grep -v '.git/' | grep -v 'apps/' | grep -v 'data/')" #list all files in update folder
cd "${DIRECTORY}/update/pi-apps" || error "Failed to enter update directory!"
#list all files in main folder updatefiles="$(find . -type f | cut -c 3- | grep -v '.git/' | grep -v 'apps/' | grep -v 'data/')"
cd "${DIRECTORY}"
localfiles="$(find . -type f | cut -c 3- | grep -v '.git/' | grep -v 'apps/' | grep -v 'data/' | grep -v 'xlunch/')"
mergedfiles="$(echo -e "${localfiles}\n${updatefiles}" | sort | uniq)"
#exclude files mentioned in data/update-exclusion file
IFS=$'\n' #exclude commented lines
for file in $(cat "${DIRECTORY}/data/update-exclusion" | grep "^[^#;]")
do
mergedfiles="$(echo "$mergedfiles" | grep -v "$file")"
echo "Excluding '$file' from the mergedlist."
done
IFS="|" # back to IFS='|'
mergedfiles="$(echo "$mergedfiles" | tr '\n' '|')"
for file in $mergedfiles
do
newhash=$(cat "${DIRECTORY}/update/pi-apps/${file}" 2>/dev/null | sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}')
oldhash=$(cat "${DIRECTORY}/${file}" 2>/dev/null | sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}')
#echo -e "newhash: $newhash\noldhash: $oldhash"
if [ "$newhash" == "$oldhash" ];then
echo -e "${file} is identical\e[90m to the online version. Nothing to do!\e[39m"
else
if [ ! -f "${DIRECTORY}/${file}" ];then
echo -e "\e[97m${file} does not exist locally.\e[39m Adding to updatable list."
#in this case, add to updatable list
mainupdate="${mainupdate}|${file}"
elif [ ! -f "${DIRECTORY}/update/pi-apps/${file}" ];then
echo -e "\e[97m${file} only exists locally.\e[39m Will not add to updatable list."
#in this case, do not add to updatable list
else
echo -e "\e[97m${file} exists in both locations, but online version is newer\e[39m. Adding to updatable list."
#in this case, add to updatable list
mainupdate="${mainupdate}|${file}"
fi
#list all files in main folder
cd "${DIRECTORY}"
localfiles="$(find . -type f | cut -c 3- | grep -v '.git/' | grep -v 'apps/' | grep -v 'data/' | grep -v 'xlunch/')"
mergedfiles="$(echo -e "${localfiles}\n${updatefiles}" | sort | uniq)"
#exclude files mentioned in data/update-exclusion file
IFS=$'\n' #exclude commented lines
for file in $(cat "${DIRECTORY}/data/update-exclusion" | grep "^[^#;]")
do
mergedfiles="$(echo "$mergedfiles" | grep -v "$file")"
echo "Excluding '$file' from the mergedlist."
done
mergedfiles="$(echo "$mergedfiles")"
for file in $mergedfiles
do
newhash=$(cat "${DIRECTORY}/update/pi-apps/${file}" 2>/dev/null | sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}')
oldhash=$(cat "${DIRECTORY}/${file}" 2>/dev/null | sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}')
#echo -e "newhash: $newhash\noldhash: $oldhash"
if [ "$newhash" == "$oldhash" ];then
true
#echo -e "${file} is identical\e[90m to the online version. Nothing to do!\e[39m"
else
if [ ! -f "${DIRECTORY}/${file}" ];then
echo -e "\e[97m${file} does not exist locally.\e[39m Adding to updatable list."
#in this case, add to updatable list
mainupdate="${mainupdate}|${file}"
elif [ ! -f "${DIRECTORY}/update/pi-apps/${file}" ];then
echo -e "\e[97m${file} only exists locally.\e[39m Will not add to updatable list."
#in this case, do not add to updatable list
else
echo -e "\e[97m${file} exists in both locations, but files do not match.\e[39m Adding to updatable list."
#in this case, add to updatable list
mainupdate="${mainupdate}
${file}"
fi fi
done
IFS="$PREIFS"
#remove initial '|' character fi
mainupdate="${mainupdate:1}" done
else IFS="$PREIFS"
error "${DIRECTORY}/update does not exist. Most likely there is no Internet connection." #remove initial newline character
fi mainupdate="${mainupdate:1}"
LIST='' LIST=''
PREIFS="$IFS" PREIFS="$IFS"
IFS="|" IFS=$'\n'
for i in $updatable for app in $updatable #repeat for every updatable app
do do
LIST="${LIST}${DIRECTORY}/update/pi-apps/apps/${i}/icon-24.png LIST="${LIST}TRUE
$i "\("$([ "$(cat "${DIRECTORY}/data/update-status/${i}")" == 'new' ] && echo 'new ')app$([ "$(cat "${DIRECTORY}/data/status/${i}" 2>/dev/null)" == 'installed' ] && echo ', <b>will be reinstalled</b>')"\)" ${DIRECTORY}/update/pi-apps/apps/${app}/icon-24.png
$app "\("$([ "$(cat "${DIRECTORY}/data/update-status/${app}")" == 'new' ] && echo 'new ')app$(will_reinstall "$app" && echo ', <b>will be reinstalled</b>')"\)"
$app
" "
done done
for i in $mainupdate for file in $mainupdate #repeat for every updatable file
do do
#determine mimetype of updatable file to display an informative icon in the list #determine mimetype of updatable file to display an informative icon in the list
if [ "$(file -b --mime-type "${DIRECTORY}/${i}")" == 'text/x-shellscript' ];then if [ "$(file -b --mime-type "${DIRECTORY}/${file}")" == 'text/x-shellscript' ];then
#if updatable file in question is a shell script, then display shellscript icon. #if updatable file in question is a shell script, then display shellscript icon.
mimeicon="${DIRECTORY}/icons/shellscript.png" mimeicon="${DIRECTORY}/icons/shellscript.png"
mimetype='script' mimetype='script'
elif [[ "${DIRECTORY}/${i}" == *.png ]];then elif [[ "${DIRECTORY}/${file}" == *.png ]];then
mimeicon="${DIRECTORY}/icons/image.png" mimeicon="${DIRECTORY}/icons/image.png"
mimetype='image' mimetype='image'
else else
@ -162,8 +181,10 @@ do
mimetype='file' mimetype='file'
fi fi
LIST="${LIST}${mimeicon} LIST="${LIST}TRUE
$i "\("$mimetype"\)" ${mimeicon}
$file "\("$mimetype"\)"
${file}
" "
done done
IFS="$PREIFS" IFS="$PREIFS"
@ -172,35 +193,52 @@ if [ -z "$LIST" ];then
echo -e '\e[92mNothing to update. Nothing to do!\e[39m' echo -e '\e[92mNothing to update. Nothing to do!\e[39m'
exit 0 exit 0
fi fi
LIST="${LIST::-1}" LIST="${LIST::-1}" #remove last newline
#echo "List: ${LIST}EOL" #echo "List: ${LIST}EOL"
screen_width="$(xrandr | grep "HDMI-1" | awk '{print $4}' | tr 'x+' ' ' | awk '{print $1}')" screen_width="$(xrandr | grep "HDMI-1" | awk '{print $4}' | tr 'x+' ' ' | awk '{print $1}')"
screen_height="$(xrandr | grep "HDMI-1" | awk '{print $4}' | tr 'x+' ' ' | awk '{print $2}')" screen_height="$(xrandr | grep "HDMI-1" | awk '{print $4}' | tr 'x+' ' ' | awk '{print $2}')"
yad --form --text='Pi-Apps updates available.' \ #display notification in lower-right, only if fastmode variable is not 1
--on-top --skip-taskbar --undecorated --close-on-unfocus \ if [ "$fastmode" != 1 ];then
--geometry=260+$((screen_width-262))+$((screen_height-150)) \ yad --form --text='Pi-Apps updates available.' \
--image="${DIRECTORY}/icons/logo-64.png" \ --on-top --skip-taskbar --undecorated --close-on-unfocus \
--button="Details!${DIRECTORY}/icons/info.png":0 --button="Close!${DIRECTORY}/icons/exit.png":1 || exit 0 --geometry=260+$((screen_width-262))+$((screen_height-150)) \
--image="${DIRECTORY}/icons/logo-64.png" \
--button="Details!${DIRECTORY}/icons/info.png":0 --button="Close!${DIRECTORY}/icons/exit.png":1 || exit 0
fi
echo -e "$LIST" | yad --center --title='Pi-Apps' --width=310 --height=300 --no-headers \ #If user clicks 'Details', then display a list of evrything updatable
--list --separator='\n' --window-icon="${DIRECTORY}/icons/logo.png" \ output="$(echo -e "$LIST" | yad --center --title='Pi-Apps' \
--text='Updates available:' \ --window-icon="${DIRECTORY}/icons/logo.png" --width=310 --height=300 \
--column=:IMG --column=Name \ --list --checklist --separator='\n' --print-column=4 --no-headers \
--text="Updates available:"$'\n'"Uncheck an item to skip updating it." \
--column=:CHK --column=:IMG --column=Name --column=ID:HD \
--button='Later'!"${DIRECTORY}/icons/exit.png"!"Remind me later":1 \ --button='Later'!"${DIRECTORY}/icons/exit.png"!"Remind me later":1 \
--button='Update now'!"${DIRECTORY}/icons/download.png":0 || exit 0 --button='Update now'!"${DIRECTORY}/icons/download.png":0)" || exit 0
PREIFS="$IFS" PREIFS="$IFS"
IFS="|" IFS=$'\n'
for i in $mainupdate
#remove empty newlines from output
output="$(echo "$output" | grep .)"
echo "$output" > ~/output.log
#limit list of update files to those selected by user.
#Edge case: if a file and app are named the same, they will appear in both lists if either one was selected.
updatable="$(echo "$updatable" | list_intersect "$output")"
#echo -e "\nWill update these apps:\n$updatable EOAPPS"
mainupdate="$(echo "$mainupdate" | list_intersect "$output")"
#echo "Will update these files:\n$mainupdate EOFILES"
for file in $mainupdate
do do
mkdir -p "$(dirname "${DIRECTORY}/${i}")" mkdir -p "$(dirname "${DIRECTORY}/${file}")"
#copy new version to apps/ #copy new version to apps/
cp -f "${DIRECTORY}/update/pi-apps/${i}" "${DIRECTORY}/${i}" || echo "\e[91mFailed to copy ${DIRECTORY}/update/pi-apps/${i}\e[39m!" cp -f "${DIRECTORY}/update/pi-apps/${file}" "${DIRECTORY}/${file}" || echo "\e[91mFailed to copy ${DIRECTORY}/update/pi-apps/${file}\e[39m!"
echo -e "\e[92m${i} was updated successfully.\e[39m" echo -e "\e[92m${file} file was copied successfully.\e[39m"
done done
IFS="$PREIFS" IFS="$PREIFS"
if [ ! -z "$updatable" ];then if [ ! -z "$updatable" ];then
@ -209,26 +247,27 @@ if [ ! -z "$updatable" ];then
updatable="'"$updatable"'" updatable="'"$updatable"'"
trap "sleep 10" EXIT trap "sleep 10" EXIT
PREIFS="$IFS" PREIFS="$IFS"
IFS="|" IFS=$'\''\n'\''
for i in $updatable for i in $updatable
do do
"${DIRECTORY}/manage" update "$i" nofetch "${DIRECTORY}/manage" update "$i" nofetch
echo -e "\e[92m${i} was updated successfully.\e[39m"
done done
IFS="$PREIFS" IFS="$PREIFS"
echo -e "\e[92mAll updates complete. Closing in 10 seconds.\e[39m" echo -e "\e[92mAll updates complete. Closing in 10 seconds.\e[39m"
' 'Updating apps...' ' 'Updating apps...'
fi fi
#.git folder #.git folder
#move old .git folder to trash #delete .git folder, then copy the new one
gio trash "${DIRECTORY}/.git" 2>/dev/null rm -rf "${DIRECTORY}/.git"
cp -rf "${DIRECTORY}/update/pi-apps/.git" "${DIRECTORY}/.git" || error "Failed to copy new .git!" cp -rf "${DIRECTORY}/update/pi-apps/.git" "${DIRECTORY}/.git" || error "Failed to copy new .git folder!"
sleep 1 sleep 1
while ps -C manage &>/dev/null while ps -C manage &>/dev/null
do do
sleep 0.1 sleep 0.1
done done
#exit before displaying "Updates complete." window
exit 0
yad --text="Updates complete. yad --text="Updates complete.
Please close all instances of Pi-Apps to apply the update." \ Please close all instances of Pi-Apps to apply the update." \

Loading…
Cancel
Save