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/preload

249 lines
6.9 KiB
Bash

#!/bin/bash
#this generates a yad-friendly app list. This is run every time the gui script is executed.
#if this script detects nothing has changed since last run, then it will echo back the app list that was generated last time.
DIRECTORY="$(readlink -f "$(dirname "$0")")"
function error {
echo -e "\e[91m$1\e[39m" 1>&2
exit 1
}
source "${DIRECTORY}/api" || error "failed to source ${DIRECTORY}/api"
#yad or xlunch format
format="$1"
if [ -z "$format" ];then
format=yad
elif [[ "$format" = xlunch* ]];then
format=xlunch
elif [ "$format" != 'yad' ] && [ "$format" != 'xlunch' ];then
error "Unknown list format '$format'!"
fi
#specifies an app folder(s)
prefix="$2"
timestampfile="${DIRECTORY}/data/preload/timestamps-$(echo "$prefix" | tr -d '/')"
listfile="${DIRECTORY}/data/preload/LIST-$(echo "$prefix" | tr -d '/')"
mkdir -p "${DIRECTORY}/data/preload"
{ #compile the genapplist-yad.c program
if [ ! -f "${DIRECTORY}/etc/genapplist-yad" ] && [ -f "${DIRECTORY}/etc/genapplist-yad.c" ];then
echo "Compiling genapplist-yad program..." 1>&2
command -v gcc >/dev/null || sudo apt install -y gcc 1>&2
gcc "${DIRECTORY}/etc/genapplist-yad.c" -o "${DIRECTORY}/etc/genapplist-yad" 1>&2 || failed=1
#Test the program and make sure it outputs 5 lines
if [ "$(APPS=Arduino DIRECTORY="$DIRECTORY" "${DIRECTORY}/etc/genapplist-yad" | wc -l)" != 5 ];then
failed=1
fi
if [ "$failed" == 1 ];then
rm -f "${DIRECTORY}/etc/genapplist-yad"
echo "The genapplist-yad program failed to compile." 1>&2
else
echo "Success! The genapplist-yad program has been compiled." 1>&2
fi
fi
}
mktimestamps() {
#these directories are checked for changes
checkdirs="${DIRECTORY}/apps
${DIRECTORY}/data/settings
${DIRECTORY}/data/status
${DIRECTORY}/data/update-status
${DIRECTORY}/etc"
timestamps=''
local IFS=$'\n'
for dir in $checkdirs
do
timestamps="$timestamps
dir $dir $(stat -c %Y "${dir}/$(ls -t "$dir" | head -n1)")"
done
#remove first empty newline and check a few other things for changes too
timestamps="prefix: $prefix
format: $format
number of files: $(ls -1q "${DIRECTORY}/apps"/* | wc -l)
preload shasum: $(sha256sum "${DIRECTORY}/preload" | awk '{print $1}')
api shasum: $(sha256sum "${DIRECTORY}/api" | awk '{print $1}')
structure shasum: $(shasum "${DIRECTORY}/data/categories/structure" | awk '{print $1}')
${timestamps:1}"
}
reloadlist=0
if [ -f "$timestampfile" ];then
#get modified timestamps for directories
mktimestamps
if [ "$timestamps" == "$(cat "$timestampfile")" ];then
#if current timestamps and saved timestamps match, then don't reload the list
reloadlist=0
echo "Timestamps match." 1>&2
else
#timestamps don't match, so reload the list
reloadlist=1
echo "Timestamps don't match" 1>&2
echo -e "original file: $(cat "$timestampfile")\nnew timestamp: $timestamps" 1>&2
fi
else
#timestamp file not found
reloadlist=1
fi
if [ ! -f "$listfile" ] || [ -z "$(cat "$listfile")" ];then
echo "list file for $prefix does not exist." 1>&2
reloadlist=1
fi
if [ $reloadlist == 1 ];then
echo "Generating list..." 1>&2
#for app_categories() and app_status() functions
source "${DIRECTORY}/api"
vfiles="$(app_categories | grep . | sort | uniq)" #generate a virtual file system with apps in folders represented as subdirectories
if [ ! -z "$prefix" ];then
echo "Showing apps within $prefix/" 1>&2
vfiles="$(echo "$vfiles" | grep "^$prefix/" | sed "s+$prefix/++g")"
fi
#remove apps within categories - show this layer of stuff only.
vfiles="$(echo "$vfiles" | sed 's+/.*+/+g' | sort | uniq)"
#get list of apps - excluding folders
APPS="$(echo "$vfiles" | grep -v '/')"
#get list of folders - excluding apps - and hide the hidden folder.
DIRS="$(echo "$vfiles" | grep '/' | tr -d '/' | grep -vx "hidden")"
#If updates available, show special Updates category
if "${DIRECTORY}/updater" get-status &>/dev/null;then
DIRS="Updates
$DIRS"
fi
#shuffle the list if enabled
if [ "$(cat "${DIRECTORY}/data/settings/Shuffle App list")" == 'Yes' ];then
APPS="$(echo "$APPS" | shuf)"
DIRS="$(echo "$DIRS" | shuf)"
fi
#remove apps that are not compatible with OS architecture
PREIFS="$IFS"
IFS=$'\n'
for i in $APPS
do
#if install script doesn't exist -------------------- and if os-specific install script doesn't exist, then...
if [ ! -f "${DIRECTORY}/apps/${i}/install" ] && [ ! -f "${DIRECTORY}/apps/${i}/install-${arch}" ];then
#...remove the app from the list
echo "Removing $i from the list because it is not compatible with your ${arch}-bit OS." 1>&2
APPS="$(echo "$APPS" | grep -vx "$i")"
fi
done
IFS="$PREIFS"
if [ "$format" == yad ];then
PREIFS="$IFS"
IFS=$'\n'
LIST=''
for i in $DIRS
do
if [ -f "${DIRECTORY}/icons/categories/${i}.png" ];then
diricon="${DIRECTORY}/icons/categories/${i}.png"
else
diricon="${DIRECTORY}/icons/categories/default.png"
fi
LIST="${LIST}$diricon
${DIRECTORY}/icons/none-24.png
$i
$i/
App folder
"
done #finished preloading categories
#set to false to disable genapplist-yad program - use the original bash version
if true && [ -f "${DIRECTORY}/etc/genapplist-yad" ];then
LIST="$LIST$(DIRECTORY="$DIRECTORY" APPS="$APPS" "${DIRECTORY}/etc/genapplist-yad")
"
else
for i in $APPS
do
status1="$(cat "${DIRECTORY}/data/status/${i}" 2>/dev/null || echo "none")"
status2="$(echo "$status1" | sed 's/none/uninstalled/g')"
LIST="$LIST$(echo "${DIRECTORY}/icons/$status1.png")
${DIRECTORY}/apps/${i}/icon-24.png
$i
$i
"\("$status2"\)" $(head -n1 "${DIRECTORY}/apps/${i}/description" || echo "Description unavailable")
"
done
fi #finished preloading apps
IFS="$PREIFS"
elif [ "$format" == xlunch ];then
#XUNCH list format
PREIFS="$IFS"
IFS=$'\n'
LIST=''
for i in $DIRS
do
if [ -f "${DIRECTORY}/icons/categories/${i}-64.png" ];then
diricon="${DIRECTORY}/icons/categories/${i}-64.png"
else
diricon="${DIRECTORY}/icons/categories/default-64.png"
fi
LIST="$LIST
${i};$diricon;${i}/"
done
for i in $APPS
do
LIST="$LIST
${i} ($(app_status "${i}"));${DIRECTORY}/apps/${i}/icon-64.png;${i}"
done
IFS="$PREIFS"
fi
LIST="$(echo -e "$LIST")"
#save entire list string to file for future use
echo "$LIST" > "$listfile"
#save timestamps to file too
mktimestamps
echo "$timestamps" > "$timestampfile"
else
echo "Reading list file..." 1>&2
LIST="$(cat "$listfile")"
fi
(#put icons in cache
PREIFS="$IFS"
IFS=$'\n'
for icon in $(echo "$LIST" | grep icon-24)
do
cat "$icon" &>/dev/null
#echo "Putting $icon in cache..." 1>&2
done
IFS="$PREIFS" ) &
echo "$LIST"
#preload all categories in background
"${DIRECTORY}/etc/preload-daemon" "$format" &>/dev/null &