You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Botspot-Pi-Apps/manage

288 lines
12 KiB
Plaintext

4 years ago
#!/bin/bash
4 years ago
#$1 is an action, like install
#$2 is app name, like Arduino
4 years ago
DIRECTORY="$(readlink -f "$(dirname "$0")")"
function error {
4 years ago
echo -e "\e[91m$1\e[39m"
4 years ago
exit 1
}
if [ -z "$1" ];then
4 years ago
error "You need to specify an operation, and in most cases, which app to operate on."
4 years ago
fi
mkdir -p "${DIRECTORY}/data/status" "${DIRECTORY}/data/update-status"
4 years ago
#determine if host system is 64 bit arm64 or 32 bit armhf
if [ ! -z "$(file "$(readlink -f "${mntpnt}/sbin/init")" | grep 64)" ];then
arch=64
elif [ ! -z "$(file "$(readlink -f "${mntpnt}/sbin/init")" | grep 32)" ];then
arch=32
else
error "Failed to detect OS CPU architecture! Something is very wrong."
fi
4 years ago
if [ "$1" == 'install' ];then
4 years ago
#INSTALL
4 years ago
#for this operation, a program name must be specified.
if [ -z "$2" ];then
error "For this operation, you must specify which app to operate on."
elif [ ! -d "${DIRECTORY}/apps/$2" ];then
error "${DIRECTORY}/apps/$2 does not exist!"
fi
4 years ago
#ensure an install script is not already running
if ps -C install || ps -C install-32 || ps -C install-64;then
4 years ago
echo "An install script is already running.
4 years ago
Pi-Apps will wait until that one finishes before installing $2." | yad --text-info \
4 years ago
--title="Waiting" --window-icon="${DIRECTORY}/icons/logo.png" --center --width=500 --height=100 \
--button=OK!"${DIRECTORY}/icons/check.png":0 --fontname=12 --timeout=10 --timeout-indicator=top
while ps -C install ;do sleep 1; done
fi
#if already installed then ask for confirmation
4 years ago
if [ "$(cat "${DIRECTORY}/data/status/${2}" )" == 'installed' ];then
yad --text="$2 is already installed. Are you sure you want to install it again?" \
4 years ago
--text-align=center --center --title='Quick question' --window-icon="${DIRECTORY}/icons/logo.png" \
--button=No!"${DIRECTORY}/icons/exit.png":1 --button=Yes!"${DIRECTORY}/icons/check.png":0 || exit 0
fi
4 years ago
#analytics
if [ "$(cat "${DIRECTORY}/data/settings/Enable analytics")" == 'Yes' ];then
#this is used to let Botspot see the daily installs for each app.
#Botspot created an individual bitly link for each app. When you install an app, the cooresponding bit.ly link is "clicked" by a headless chromium-browser instance.
#Chromium accesses the bit.ly link, then exits.
#Allowing analytics does not identify you, or any personal information about you. Botspot can only see the number of "clicks" per day, as well as the top 10 countries of origin.
bitlylink="https://bit.ly/pi-apps-install-$(echo "$2" | tr -d ' ' | sed 's/[^a-zA-Z]//g')"
chromium-browser --headless "$bitlylink" &>/dev/null &
fi
#determine which script to run
if [ -f "${DIRECTORY}/apps/${2}/install" ];then
installscript="${DIRECTORY}/apps/${2}/install"
elif [ -f "${DIRECTORY}/apps/${2}/install-64" ] && [ $arch == 64 ];then
installscript="${DIRECTORY}/apps/${2}/install-64"
elif [ -f "${DIRECTORY}/apps/${2}/install-32" ] && [ $arch == 32 ];then
installscript="${DIRECTORY}/apps/${2}/install-32"
else
error "It appears $2 does not have an install-${arch} script suitable for your ${arch}-bit OS."
fi
lxterminal --title="Installing $2 ${arch}-bit" -e "
4 years ago
cd $HOME
4 years ago
echo 'corrupted' > \"${DIRECTORY}/data/status/${2}\"
if \"$installscript\" ; then
4 years ago
echo 'installed' > \"${DIRECTORY}/data/status/${2}\"
4 years ago
echo -en '\n\e[42m\e[30mCommand succeeded.\e[39m\e[49m\nClosing in 10 seconds.'
sleep 10
4 years ago
else
echo -en '\n\e[41m\e[30mCommand failed!\e[39m\e[49m\nClose this window to exit.'
read enter #technically you could press Enter to exit.
fi"
#wait until script is done before this command exits
sleep 2
while ps -C install >/dev/null;do sleep 1; done
4 years ago
elif [ "$1" == 'uninstall' ];then
4 years ago
#UNINSTALL
4 years ago
#for this operation, a program name must be specified.
if [ -z "$2" ];then
error "For this operation, you must specify which app to operate on."
elif [ ! -d "${DIRECTORY}/apps/$2" ];then
error "${DIRECTORY}/apps/$2 does not exist!"
fi
4 years ago
#ensure an uninstall script is not already running
4 years ago
if ps -C uninstall ;then
4 years ago
echo "An uninstall script is already running.
Pi-Apps will wait until that one finishes before starting this one." | yad --text-info \
--title="Waiting" --window-icon="${DIRECTORY}/icons/logo.png" --center --width=500 --height=100 \
--button=OK!"${DIRECTORY}/icons/check.png":0 --fontname=12 --timeout=10 --timeout-indicator=top
while ps -C uninstall ;do sleep 1; done
fi
#if already uninstalled then ask for confirmation
4 years ago
if [ "$(cat "${DIRECTORY}/data/status/${2}" )" == 'uninstalled' ];then
yad --text="$2 is already uninstalled. Are you sure you want to uninstall it again?" \
4 years ago
--text-align=center --center --title='Quick question' --window-icon="${DIRECTORY}/icons/logo.png" \
--button=No!"${DIRECTORY}/icons/exit.png":1 --button=Yes!"${DIRECTORY}/icons/check.png":0 || exit 0
fi
4 years ago
lxterminal --title="Uninstalling $2" -e "
4 years ago
cd $HOME
4 years ago
echo 'corrupted' > \"${DIRECTORY}/data/status/${2}\"
if \"${DIRECTORY}/apps/${2}/uninstall\" ; then
echo 'uninstalled' > \"${DIRECTORY}/data/status/${2}\"
4 years ago
echo -en '\n\e[42m\e[30mCommand succeeded.\e[39m\e[49m\nClosing in 10 seconds..'
sleep 10
4 years ago
else
4 years ago
echo 'corrupted' > \"${DIRECTORY}/data/status/${2}\"
4 years ago
echo -en '\n\e[41m\e[30mCommand failed!\e[39m\e[49m\nClose this window to exit.'
read enter #technically you could press Enter to exit.
fi"
#wait until script is done before this command exits
sleep 2
while ps -C uninstall >/dev/null;do sleep 1; done
4 years ago
elif [ "$1" == 'update' ];then
4 years ago
#UPDATE
4 years ago
#for this operation, a program name must be specified.
if [ -z "$2" ];then
error "For this operation, you must specify which app to operate on."
fi
4 years ago
#HIDDEN FEATURE - if $3 equals nofetch, then don't download github repo. Useful for updating multiple apps at maximum speed
if [ "$3" == 'nofetch' ] && [ -d "${DIRECTORY}/update" ];then
true
else
rm -rf "${DIRECTORY}/update" && mkdir "${DIRECTORY}/update" && cd "${DIRECTORY}/update" || error "failed to enter the update directory!"
git clone "$(cat "${DIRECTORY}/etc/git_url")" || error "failed to clone repository!"
4 years ago
fi
4 years ago
newhash=$(find "${DIRECTORY}/update/pi-apps/apps/${2}" -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}')
oldhash=$(find "${DIRECTORY}/apps/${2}" -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}')
4 years ago
#detect which installation script exists and get the hash for that one
if [ -f "${DIRECTORY}/update/pi-apps/apps/${2}/install" ];then
scriptname='install'
elif [ -f "${DIRECTORY}/update/pi-apps/apps/${2}/install-32" ];then
scriptname='install-32'
elif [ -f "${DIRECTORY}/update/pi-apps/apps/${2}/install-64" ];then
scriptname='install-64'
else
error "No install script found for the $2 app! Please report this to Botspot."
fi
newinstallhash=$(sha1sum "${DIRECTORY}/update/pi-apps/apps/${2}/${scriptname}" | awk '{print $1}')
oldinstallhash=$(sha1sum "${DIRECTORY}/apps/${2}/${scriptname}" | awk '{print $1}')
#echo -e "newinstallhash: $newinstallhash\noldinstallhash: $oldinstallhash"
#echo -e "newhash: $newhash\noldhash: $oldhash"
4 years ago
if [ "$newhash" == "$oldhash" ];then
echo "$2 is identical to the online version. Nothing to do!"
exit 0
else
echo "$2 is not identical to the online version. Reinstalling..."
fi
#else
installback=no
#if install was changed
if [ ! "$newinstallhash" == "$oldinstallhash" ];then
#if installed already
if [ "$(cat "${DIRECTORY}/data/status/${2}")" == 'installed' ];then
installback=yes
#uninstall it using a recursive script instance
"${DIRECTORY}/manage" uninstall "$2"
fi
4 years ago
fi
#move old program to trash
4 years ago
gio trash "${DIRECTORY}/apps/${2}" 2>/dev/null
#failsafe
[ -d "${DIRECTORY}/apps/${2}" ] && error "${DIRECTORY}/apps/${2} still exists, despite trying to delete it!"
4 years ago
#copy new version to apps/
cp -rf "${DIRECTORY}/update/pi-apps/apps/${2}" "${DIRECTORY}/apps/${2}"
if [ "$installback" == 'yes' ] && [ "$(cat "${DIRECTORY}/data/settings/Reinstall after update")" != 'No' ];then
4 years ago
echo "$2 was originally installed before updating. Reinstalling the new version now."
#install it using a recursive script instance
"${DIRECTORY}/manage" install "$2"
fi
echo -e "\e[92m${2} was updated successfully.\e[39m"
4 years ago
elif [ "$1" == 'check-all' ];then
#CHECK-ALL
4 years ago
#for this operation, a program name cannot be specified.
4 years ago
#hidden flag: if $2 is 'installedonly', then only check for updates for those apps that are installed
if [ "$2" == 'installedonly' ];then
installedonly=1
else
installedonly=0
fi
rm -rf "${DIRECTORY}/update" && mkdir "${DIRECTORY}/update" && cd "${DIRECTORY}/update" || error "failed to enter the update directory!"
git clone "$(cat "${DIRECTORY}/etc/git_url")" || error "failed to clone repository!"
#generate entire app list, combine local apps and online apps to one list
applist="$(echo -e "$(ls "${DIRECTORY}/update/pi-apps/apps")\n$(ls "${DIRECTORY}/apps")" | sort | uniq)"
if [ $installedonly == 1 ];then
#installedonly flag enabled. Remove apps that are uninstalled
echo "installedonly flag set to 1" 1>&2
PREIFS="$IFS"
IFS=$'\n'
for app in $applist
do
if [ ! -f "${DIRECTORY}/data/status/${app}" ] || [ "$(cat "${DIRECTORY}/data/status/${app}")" == 'uninstalled' ];then
#if app is uninstalled, then remove it from the list.
applist="$(echo "$applist" | grep -vx "$app")"
echo "Removing ${app} from list because it is uninstalled." 1>&2
fi
done
IFS="$PREIFS"
fi
applist="$(echo "$applist" | tr '\n' '|')"
#echo "App list: $applist" 1>&2
4 years ago
updatable=''
PREIFS="$IFS"
IFS="|"
for app in $applist
4 years ago
do
#echo "app: $app"
newhash=$(find "${DIRECTORY}/update/pi-apps/apps/${app}" -type f -print0 2>/dev/null | xargs -0 sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}')
oldhash=$(find "${DIRECTORY}/apps/${app}" -type f -print0 2>/dev/null | xargs -0 sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}')
#echo -e "newhash: $newhash\noldhash: $oldhash" 1>&2
4 years ago
if [ "$newhash" == "$oldhash" ];then
echo -e "${app} is identical\e[90m to the online version. Nothing to do!\e[39m" 1>&2
echo 'latest' > "${DIRECTORY}/data/update-status/${app}"
4 years ago
else
if [ ! -d "${DIRECTORY}/apps/${app}" ];then
echo -e "\e[97m${app} does not exist locally.\e[39m Adding to updatable list." 1>&2
echo 'new' > "${DIRECTORY}/data/update-status/${app}"
4 years ago
#in this case, add to updatable list
updatable="${updatable}|${app}"
elif [ ! -d "${DIRECTORY}/update/pi-apps/apps/${app}" ];then
echo -e "\e[97m${app} only exists locally.\e[39m Will not add to updatable list." 1>&2
echo 'local' > "${DIRECTORY}/data/update-status/${app}"
4 years ago
#in this case, do not add to updatable list
else
echo -e "\e[97m${app} exists in both locations, but online version is newer\e[39m. Adding to updatable list." 1>&2
echo 'updatable' > "${DIRECTORY}/data/update-status/${app}"
4 years ago
#in this case, add to updatable list
updatable="${updatable}|${app}"
4 years ago
fi
4 years ago
fi
4 years ago
done
IFS="$PREIFS"
4 years ago
#remove initial '|' character
updatable="${updatable:1}"
4 years ago
echo -e "\e[97mThese apps can be updated:\n${updatable}"
4 years ago
elif [ "$1" == 'update-all' ];then
4 years ago
#UPDATE-ALL
4 years ago
#for this operation, a program name cannot be specified.
PREIFS="$IFS"
IFS='|'
updatable="$("${DIRECTORY}/manage" check-all | tail -1)"
echo "Updatable: ${updatable}EOU"
for updateapp in $updatable
do
echo "updating $updateapp"
#update it using a recursive script instance
echo "${DIRECTORY}/manage update $updateapp"
4 years ago
"${DIRECTORY}/manage" update "$updateapp" || exit 1
4 years ago
done
IFS="$PREIFS"
4 years ago
echo -e '\e[92mOperation completed successfully!\e[39m'
4 years ago
else
4 years ago
error "Did not understand ${1}. It must be either "\'"install"\'", "\'"uninstall"\'", "\'"update"\'", "\'"check-all"\'", or "\'"update-all"\'"."
4 years ago
fi