diff --git a/app-updater b/app-updater new file mode 100755 index 0000000..3c83c0b --- /dev/null +++ b/app-updater @@ -0,0 +1,123 @@ +#!/bin/bash + +DIRECTORY="$(readlink -f "$(dirname "$0")")" + +function error { + echo -e "\e[91m$1\e[39m" + exit 1 +} + +#generate app update status info +updatable="$("${DIRECTORY}/manage" check-all | tail -1)" + +#if check-all succeeded to download the repo to the update folder +if [ -d "${DIRECTORY}/update" ];then + PREIFS="$IFS" + IFS="|" + + mainfiles="$(echo -e "$(ls -p "${DIRECTORY}/update/pi-apps")\n$(ls -p "${DIRECTORY}")" | grep -v '/' | sort | uniq | tr '\n' '|')" + for file in $mainfiles + 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 + + fi + done + IFS="$PREIFS" + + #remove initial '|' character + mainupdate="${mainupdate:1}" +else + error "${DIRECTORY}/update does not exist. Most likely there is no Internet connection." +fi + +LIST='' + +PREIFS="$IFS" +IFS="|" +for i in $updatable +do + LIST="${LIST}${DIRECTORY}/update/pi-apps/apps/${i}/icon-24.png +$i "\("$([ $(cat "${DIRECTORY}/data/update-status/${i}") == 'new' ]&&echo 'new ')app"\)" +" +done +for i in $mainupdate +do + LIST="${LIST}$(if [ "$(file -b --mime-type "${DIRECTORY}/${i}")" == 'text/x-shellscript' ];then + #if updatable file in question is a shell script, then display shellscript icon. + echo "${DIRECTORY}/icons/shellscript.png" +else + #otherwise display txt icon. + echo "${DIRECTORY}/icons/txt.png" +fi) +$i "\("file"\)" +" +done +IFS="$PREIFS" + +if [ -z "$LIST" ];then + echo -e '\e[92mNothing to update. Nothing to do!\e[39m' + exit 0 +fi +LIST="${LIST::-1}" +#echo "List: ${LIST}EOL" + +echo -e "$LIST" | yad --center --title='Pi-Apps' --width=300 --height=300 --no-headers \ + --list --separator='\n' --window-icon="${DIRECTORY}/icons/logo.png" \ + --text='Updates available:' \ + --column=:IMG --column=Name \ + --button=Cancel!"${DIRECTORY}/icons/exit.png":1 \ + --button='Update now'!"${DIRECTORY}/icons/download.png":0 \ + 2>/dev/null + +button=$? #get exit code to determine which button was pressed +echo "Button: ${button}" +[ ! "$button" -eq 0 ] && error 'User cancelled' #exit now if anything but Update was clicked + + +PREIFS="$IFS" +IFS="|" +for i in $updatable +do + "${DIRECTORY}/manage" update "$i" nofetch + echo -e "\e[92m${i} was updated successfully.\e[39m" +done + +for i in $mainupdate +do + #move old program to trash + gio trash "${DIRECTORY}/${i}" 2>/dev/null + + #failsafe + [ -f "${DIRECTORY}/${i}" ] && error "${DIRECTORY}/apps/${2} still exists, despite trying to delete it!" + + #copy new version to apps/ + cp -f "${DIRECTORY}/update/pi-apps/${i}" "${DIRECTORY}/${i}" || error "Failed to copy ${DIRECTORY}/update/pi-apps/${i}!" + + echo -e "\e[92m${i} was updated successfully.\e[39m" +done +IFS="$PREIFS" + +#.git folder +#move old .git folder to trash +gio trash "${DIRECTORY}/.git" 2>/dev/null +cp -f "${DIRECTORY}/update/pi-apps/.git" "${DIRECTORY}/.git" || error "Failed to copy new .git!" + + diff --git a/data/update-status/Arduino b/data/update-status/Arduino new file mode 100644 index 0000000..d669e17 --- /dev/null +++ b/data/update-status/Arduino @@ -0,0 +1 @@ +updatable diff --git a/data/update-status/Arduino2 b/data/update-status/Arduino2 new file mode 100644 index 0000000..4083037 --- /dev/null +++ b/data/update-status/Arduino2 @@ -0,0 +1 @@ +local diff --git a/data/update-status/BalenaEtcher b/data/update-status/BalenaEtcher new file mode 100644 index 0000000..a0f9a4b --- /dev/null +++ b/data/update-status/BalenaEtcher @@ -0,0 +1 @@ +latest diff --git a/data/update-status/Chromium Media Edition b/data/update-status/Chromium Media Edition new file mode 100644 index 0000000..3e75765 --- /dev/null +++ b/data/update-status/Chromium Media Edition @@ -0,0 +1 @@ +new diff --git a/data/update-status/CommanderPi b/data/update-status/CommanderPi new file mode 100644 index 0000000..a0f9a4b --- /dev/null +++ b/data/update-status/CommanderPi @@ -0,0 +1 @@ +latest diff --git a/data/update-status/Cool Retro Term b/data/update-status/Cool Retro Term new file mode 100644 index 0000000..a0f9a4b --- /dev/null +++ b/data/update-status/Cool Retro Term @@ -0,0 +1 @@ +latest diff --git a/data/update-status/Cura b/data/update-status/Cura new file mode 100644 index 0000000..a0f9a4b --- /dev/null +++ b/data/update-status/Cura @@ -0,0 +1 @@ +latest diff --git a/data/update-status/FreeCAD b/data/update-status/FreeCAD new file mode 100644 index 0000000..a0f9a4b --- /dev/null +++ b/data/update-status/FreeCAD @@ -0,0 +1 @@ +latest diff --git a/data/update-status/FreeCAD (precompiled) b/data/update-status/FreeCAD (precompiled) new file mode 100644 index 0000000..a0f9a4b --- /dev/null +++ b/data/update-status/FreeCAD (precompiled) @@ -0,0 +1 @@ +latest diff --git a/data/update-status/Pi Power Tools b/data/update-status/Pi Power Tools new file mode 100644 index 0000000..a0f9a4b --- /dev/null +++ b/data/update-status/Pi Power Tools @@ -0,0 +1 @@ +latest diff --git a/data/update-status/Raspi2png b/data/update-status/Raspi2png new file mode 100644 index 0000000..a0f9a4b --- /dev/null +++ b/data/update-status/Raspi2png @@ -0,0 +1 @@ +latest diff --git a/data/update-status/TBOPlayer b/data/update-status/TBOPlayer new file mode 100644 index 0000000..a0f9a4b --- /dev/null +++ b/data/update-status/TBOPlayer @@ -0,0 +1 @@ +latest diff --git a/data/update-status/Windows 10 Theme b/data/update-status/Windows 10 Theme new file mode 100644 index 0000000..a0f9a4b --- /dev/null +++ b/data/update-status/Windows 10 Theme @@ -0,0 +1 @@ +latest diff --git a/gui b/gui index 823d26c..5336259 100755 --- a/gui +++ b/gui @@ -16,14 +16,13 @@ while true;do for i in $APPS do - LIST="$LIST$(echo "${DIRECTORY}/icons/$(cat "${DIRECTORY}/data/status/${i}" || echo "none").png") + LIST="${LIST}$(echo "${DIRECTORY}/icons/$(cat "${DIRECTORY}/data/status/${i}" || echo "none").png") ${DIRECTORY}/apps/${i}/icon-24.png $i "\("$(cat "${DIRECTORY}/data/status/${i}" || echo "Unknown state")"\)" $(echo "$(cat "${DIRECTORY}/apps/${i}/description" || echo "Description unavailable")" | head -n1) " done IFS="$PREIFS" - LIST="$(echo -e "$LIST")" #echo "$LIST" output="$(echo -e "$LIST" | yad --center --title='Pi-Apps' --width=300 --height=300 --no-headers \ --list --separator='\n' --window-icon="${DIRECTORY}/icons/logo.png" \ diff --git a/icons/new.png b/icons/new.png new file mode 100644 index 0000000..8410a71 Binary files /dev/null and b/icons/new.png differ diff --git a/icons/shellscript.png b/icons/shellscript.png new file mode 100644 index 0000000..1d85932 Binary files /dev/null and b/icons/shellscript.png differ diff --git a/icons/txt.png b/icons/txt.png new file mode 100644 index 0000000..aab61a4 Binary files /dev/null and b/icons/txt.png differ diff --git a/icons/uninstalled.png b/icons/uninstalled.png index 4ff9ba4..1942003 100644 Binary files a/icons/uninstalled.png and b/icons/uninstalled.png differ diff --git a/icons/updatable.png b/icons/updatable.png new file mode 100644 index 0000000..07e2076 Binary files /dev/null and b/icons/updatable.png differ diff --git a/install b/install new file mode 100755 index 0000000..1ed819a --- /dev/null +++ b/install @@ -0,0 +1,31 @@ +#!/bin/bash + +#has newline chars to display properly +packagelist="$(echo "yad" | tr ' ' '\n')" + +DIRECTORY="$(readlink -f "$(dirname "$0")")" + +echo -e "$packagelist" | zenity --title='Pi-Apps' --window-icon="${DIRECTORY}/icons/logo.png" \ + --list --text=" These packages are required but not installed. \n Install them now?" \ + --ok-label=Yes --cancel-label=No \ + --column=foo --hide-header 2>/dev/null +button=$? + +#echo $button +if [ ! $button -eq 0 ];then + echo "User declined." + exit 1 +fi +#else +lxterminal --title="Installing $packagelist" -e "sudo apt install -y $PKG_LIST;echo -e '\nInstallation finished.\nClosing in 5 seconds.';sleep 5" + +echo "Creating menu button..." +echo -n '' > ${HOME}/.local/share/applications/pi-apps.desktop +echo "[Desktop Entry] +Name=Pi Apps +Comment=Raspberry Pi App Store for open source projects +Exec=${DIRECTORY}/gui +Icon=${DIRECTORY}/icons/logo.png +Terminal=false +Type=Application +Categories=Utility;" >> ${HOME}/.local/share/applications/pi-apps.desktop diff --git a/manage b/manage index e80cecd..6610bad 100755 --- a/manage +++ b/manage @@ -15,13 +15,13 @@ if [ -z "$1" ];then fi if [ "$1" == 'install' ];then + #INSTALL #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 - #INSTALL #ensure an install script is not already running if ps -C install ;then echo "An install script is already running. @@ -43,8 +43,8 @@ Pi-Apps will wait until that one finishes before installing $2." | yad --text-in echo 'corrupted' > \"${DIRECTORY}/data/status/${2}\" if \"${DIRECTORY}/apps/${2}/install\" ; then echo 'installed' > \"${DIRECTORY}/data/status/${2}\" - echo -en '\n\e[42m\e[30mCommand succeeded.\e[39m\e[49m\nClose this window to exit.' - read enter #technically you could press Enter to exit. + echo -en '\n\e[42m\e[30mCommand succeeded.\e[39m\e[49m\nClosing in 10 seconds.' + sleep 10 else echo 'corrupted' > \"${DIRECTORY}/data/status/${2}\" echo -en '\n\e[41m\e[30mCommand failed!\e[39m\e[49m\nClose this window to exit.' @@ -55,15 +55,15 @@ Pi-Apps will wait until that one finishes before installing $2." | yad --text-in while ps -C install >/dev/null;do sleep 1; done elif [ "$1" == 'uninstall' ];then + #UNINSTALL #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 - #UNINSTALL #ensure an uninstall script is not already running - if ps -C install ;then + if ps -C uninstall ;then 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 \ @@ -83,8 +83,8 @@ Pi-Apps will wait until that one finishes before starting this one." | yad --tex echo 'corrupted' > \"${DIRECTORY}/data/status/${2}\" if \"${DIRECTORY}/apps/${2}/uninstall\" ; then echo 'uninstalled' > \"${DIRECTORY}/data/status/${2}\" - echo -en '\n\e[42m\e[30mCommand succeeded.\e[39m\e[49m\nClose this window to exit.' - read enter #technically you could press Enter to exit. + echo -en '\n\e[42m\e[30mCommand succeeded.\e[39m\e[49m\nClosing in 10 seconds..' + sleep 10 else echo 'corrupted' > \"${DIRECTORY}/data/status/${2}\" echo -en '\n\e[41m\e[30mCommand failed!\e[39m\e[49m\nClose this window to exit.' @@ -94,14 +94,19 @@ Pi-Apps will wait until that one finishes before starting this one." | yad --tex sleep 2 while ps -C uninstall >/dev/null;do sleep 1; done elif [ "$1" == 'update' ];then + #UPDATE #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 - #UPDATE - rm -rf "${DIRECTORY}/update" && mkdir "${DIRECTORY}/update" && cd "${DIRECTORY}/update" || error "failed to enter the update directory!" - git clone https://github.com/Botspot/pi-apps || error "failed to clone repository!" + #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 https://github.com/Botspot/pi-apps || error "failed to clone repository!" + fi 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}') @@ -125,7 +130,10 @@ elif [ "$1" == 'update' ];then fi #move old program to trash - gio trash "${DIRECTORY}/apps/${2}" + gio trash "${DIRECTORY}/apps/${2}" 2>/dev/null + + #failsafe + [ -d "${DIRECTORY}/apps/${2}" ] && error "${DIRECTORY}/apps/${2} still exists, despite trying to delete it!" #copy new version to apps/ cp -rf "${DIRECTORY}/update/pi-apps/apps/${2}" "${DIRECTORY}/apps/${2}" @@ -135,39 +143,56 @@ elif [ "$1" == 'update' ];then #install it using a recursive script instance "${DIRECTORY}/manage" install "$2" fi + echo -e '\e[92m${2} was updated successfully.\e[39m' elif [ "$1" == 'check-all' ];then - #for this operation, a program name cannot be specified. #CHECK-ALL + #for this operation, a program name cannot be specified. rm -rf "${DIRECTORY}/update" && mkdir "${DIRECTORY}/update" && cd "${DIRECTORY}/update" || error "failed to enter the update directory!" git clone https://github.com/Botspot/pi-apps || error "failed to clone repository!" updatable='' - echo "app list: $(echo "$(ls "${DIRECTORY}/update/pi-apps/apps")" | grep -v 'template')" PREIFS="$IFS" IFS="|" - newapps="$(echo "$(ls "${DIRECTORY}/update/pi-apps/apps")" | grep -v 'template' | tr '\n' '|')" + newapps="$(echo -e "$(ls "${DIRECTORY}/update/pi-apps/apps")\n$(ls "${DIRECTORY}/apps")" | grep -v 'template' | sort | uniq | tr '\n' '|')" for newapp in $newapps do - echo "newapp: $newapp" - newhash=$(find "${DIRECTORY}/update/pi-apps/apps/${newapp}" -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}') - oldhash=$(find "${DIRECTORY}/apps/${newapp}" -type f -print0 | xargs -0 sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}') - echo -e "newhash: $newhash\noldhash: $oldhash" + #echo "newapp: $newapp" + newhash=$(find "${DIRECTORY}/update/pi-apps/apps/${newapp}" -type f -print0 2>/dev/null | xargs -0 sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}') + oldhash=$(find "${DIRECTORY}/apps/${newapp}" -type f -print0 2>/dev/null | xargs -0 sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}') + #echo -e "newhash: $newhash\noldhash: $oldhash" if [ "$newhash" == "$oldhash" ];then - echo "${newapp} is identical to the online version. Nothing to do!" + echo -e "${newapp} is identical\e[90m to the online version. Nothing to do!\e[39m" + echo 'latest' > "${DIRECTORY}/data/update-status/${newapp}" else - echo "${newapp} is not identical to the online version. Adding to updatable list..." - updatable="${updatable}|${newapp}" + if [ ! -d "${DIRECTORY}/apps/${newapp}" ];then + echo -e "\e[97m${newapp} does not exist locally.\e[39m Adding to updatable list." + echo 'new' > "${DIRECTORY}/data/update-status/${newapp}" + #in this case, add to updatable list + updatable="${updatable}|${newapp}" + elif [ ! -d "${DIRECTORY}/update/pi-apps/apps/${newapp}" ];then + echo -e "\e[97m${newapp} only exists locally.\e[39m Will not add to updatable list." + echo 'local' > "${DIRECTORY}/data/update-status/${newapp}" + #in this case, do not add to updatable list + else + echo -e "\e[97m${newapp} exists in both locations, but online version is newer\e[39m. Adding to updatable list." + echo 'updatable' > "${DIRECTORY}/data/update-status/${newapp}" + #in this case, add to updatable list + updatable="${updatable}|${newapp}" + fi + fi - done + done + IFS="$PREIFS" + #remove initial '|' character updatable="${updatable:1}" - IFS="$PREIFS" - echo -e "These apps can be updated:\n${updatable}" + echo -e "\e[97mThese apps can be updated:\n${updatable}" elif [ "$1" == 'update-all' ];then + #UPDATE-ALL #for this operation, a program name cannot be specified. PREIFS="$IFS" IFS='|' @@ -178,9 +203,10 @@ elif [ "$1" == 'update-all' ];then echo "updating $updateapp" #update it using a recursive script instance echo "${DIRECTORY}/manage update $updateapp" - "${DIRECTORY}/manage" update "$updateapp" + "${DIRECTORY}/manage" update "$updateapp" || exit 1 done IFS="$PREIFS" + echo -e '\e[92mOperation completed successfully!\e[39m' else - error "Did not understand ${1}. It must be either "\'"install"\'", "\'"uninstall"\'", "\'"update"\'", or "\'"check-all"\'"." + error "Did not understand ${1}. It must be either "\'"install"\'", "\'"uninstall"\'", "\'"update"\'", "\'"check-all"\'", or "\'"update-all"\'"." fi diff --git a/update/pi-apps b/update/pi-apps index 637d24d..d51045e 160000 --- a/update/pi-apps +++ b/update/pi-apps @@ -1 +1 @@ -Subproject commit 637d24d884a25d46012a5b5ab6fb876686fe6bdf +Subproject commit d51045ef79db9abef2578e8c21c9eb9c49eb2057