|
|
|
#!/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
|
|
|
|
}
|
|
|
|
|
|
|
|
#determine if host system is 64 bit arm64 or 32 bit armhf
|
|
|
|
if [ ! -z "$(file "$(readlink -f "/sbin/init")" | grep 64)" ];then
|
|
|
|
arch=64
|
|
|
|
elif [ ! -z "$(file "$(readlink -f "/sbin/init")" | grep 32)" ];then
|
|
|
|
arch=32
|
|
|
|
else
|
|
|
|
error "Failed to detect OS CPU architecture! Something is very wrong."
|
|
|
|
fi
|
|
|
|
|
|
|
|
#yad or xlunch format
|
|
|
|
format="$1"
|
|
|
|
|
|
|
|
if [ -z "$format" ];then
|
|
|
|
format=yad
|
|
|
|
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"
|
|
|
|
|
|
|
|
mktimestamps() {
|
|
|
|
#these directories are checked for changes
|
|
|
|
checkdirs="${DIRECTORY}/apps
|
|
|
|
${DIRECTORY}/data/settings
|
|
|
|
${DIRECTORY}/data/status
|
|
|
|
${DIRECTORY}/data/categories
|
|
|
|
${DIRECTORY}/etc"
|
|
|
|
|
|
|
|
timestamps=''
|
|
|
|
PREIFS="$IFS"
|
|
|
|
IFS=$'\n'
|
|
|
|
for dir in $checkdirs
|
|
|
|
do
|
|
|
|
timestamps="$timestamps
|
|
|
|
${dir}/$(ls -t "$dir" | head -n1)
|
|
|
|
$(stat -c %Y "${dir}/$(ls -t "$dir" | head -n1)")"
|
|
|
|
done
|
|
|
|
IFS="$PREIFS"
|
|
|
|
#remove first empty newline and check a few other things for changes too
|
|
|
|
timestamps="$prefix
|
|
|
|
$format
|
|
|
|
$(ls -1q "${DIRECTORY}/apps"/* | wc -l)
|
|
|
|
$(sha256sum "${DIRECTORY}/preload" | 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
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
#timestamp file not found
|
|
|
|
reloadlist=1
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -f "$listfile" ] || [ -z "$(cat "$listfile")" ];then
|
|
|
|
echo "list file does not exist." 1>&2
|
|
|
|
reloadlist=1
|
|
|
|
fi
|
|
|
|
|
|
|
|
#this ensures that all apps & categories stay preloaded.
|
|
|
|
(sleep 5;"${DIRECTORY}/etc/preload-daemon" "$format") 1>&2 &
|
|
|
|
|
|
|
|
if [ $reloadlist == 1 ];then
|
|
|
|
echo "Generating list..." 1>&2
|
|
|
|
|
|
|
|
APPS="$(ls "${DIRECTORY}/apps")"
|
|
|
|
structure="$(cat "${DIRECTORY}/data/categories/structure")"
|
|
|
|
|
|
|
|
#generate a virtual file system with apps in folders represented as subdirectories
|
|
|
|
vfiles=''
|
|
|
|
PREIFS="$IFS"
|
|
|
|
IFS=$'\n'
|
|
|
|
for app in $APPS
|
|
|
|
do
|
|
|
|
line="$(echo "$structure" | grep "$app"'|' | awk -F'|' '{print $2 "/" $1}')"
|
|
|
|
|
|
|
|
if [ -z "$line" ];then
|
|
|
|
echo "WARNING: $app app not found in $(echo "${DIRECTORY}/data/categories/structure" | sed 's+/home/pi+~+g') file." 1>&2
|
|
|
|
if [ -z "$onlinestructurefile" ];then
|
|
|
|
onlinestructurefile="$(wget -qO- 'https://raw.githubusercontent.com/Botspot/pi-apps/master/data/categories/structure')"
|
|
|
|
fi
|
|
|
|
onlinematch="$(echo "$onlinestructurefile" | grep "$app"'|')"
|
|
|
|
if [ ! -z "$onlinematch" ];then
|
|
|
|
echo -e "Located the default category for the $app app from github.\nIt is: ${onlinematch}EOO" 1>&2
|
|
|
|
echo "$onlinematch" >> "${DIRECTORY}/data/categories/structure"
|
|
|
|
else
|
|
|
|
echo -e "Could not find the default category for the $app app." 1>&2
|
|
|
|
echo "${app}|" >> "${DIRECTORY}/data/categories/structure"
|
|
|
|
fi
|
|
|
|
#refresh structure file
|
|
|
|
structure="$(cat "${DIRECTORY}/data/categories/structure")"
|
|
|
|
line="$(echo "$structure" | grep "$app"'|' | awk -F'|' '{print $2 "/" $1}')"
|
|
|
|
fi
|
|
|
|
|
|
|
|
vfiles="$vfiles
|
|
|
|
$line"
|
|
|
|
done
|
|
|
|
IFS="$PREIFS"
|
|
|
|
|
|
|
|
#create special directory containing installed apps
|
|
|
|
PREIFS="$IFS"
|
|
|
|
IFS=$'\n'
|
|
|
|
for app in $APPS
|
|
|
|
do
|
|
|
|
line="$(echo "$structure" | grep "$app"'|' | awk -F'|' '{print $2 "/" $1}')"
|
|
|
|
|
|
|
|
if [ -f "${DIRECTORY}/data/status/$app" ] && [ "$(cat "${DIRECTORY}/data/status/$app")" == 'installed' ];then
|
|
|
|
#if installed, add to list
|
|
|
|
vfiles="$vfiles
|
|
|
|
Installed/$app"
|
|
|
|
fi
|
|
|
|
|
|
|
|
done
|
|
|
|
IFS="$PREIFS"
|
|
|
|
|
|
|
|
vfiles="$(echo "$vfiles" | grep . | sed 's+^/++g' | sort | uniq)"
|
|
|
|
#echo "$vfiles"
|
|
|
|
|
|
|
|
if [ ! -z "$prefix" ];then
|
|
|
|
echo "Showing apps within $prefix/" 1>&2
|
|
|
|
|
|
|
|
vfiles="$(echo "$vfiles" | grep "$prefix" | sed "s+$prefix/++g")"
|
|
|
|
fi
|
|
|
|
|
|
|
|
vfiles="$(echo "$vfiles" | sed 's+/.*+/+g' | sort | uniq)"
|
|
|
|
# only root file name replace \ with / move first / to end of line remove duplicate entries
|
|
|
|
#vfiles="$(echo "$vfiles" | awk -F '/' '{print $1}' | sed 's+\\+/+g' | sed 's+^/\(.*\)+\1/+' | sort | uniq)"
|
|
|
|
|
|
|
|
#echo "$vfiles" 1>&2
|
|
|
|
|
|
|
|
#get list of apps --------------- and exclude apps mentioned in hidelist file ---------------- remove lines containing '/'
|
|
|
|
APPS="$(echo "$vfiles" | grep -v '/')"
|
|
|
|
|
|
|
|
#get list of "directories"
|
|
|
|
DIRS="$(echo "$vfiles" | grep '/' | tr -d '/' | grep -vx "hidden")"
|
|
|
|
#APPS="$(ls "${DIRECTORY}/apps")"
|
|
|
|
|
|
|
|
#echo -e "Apps: $APPS\nDirs: $DIRS" 1>&2
|
|
|
|
|
|
|
|
#exit 0
|
|
|
|
#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"
|
|
|
|
|
|
|
|
#shuffle the list if enabled
|
|
|
|
if [ "$(cat "${DIRECTORY}/data/settings/Shuffle App list")" == 'Yes' ];then
|
|
|
|
APPS="$(echo "$APPS" | shuf)"
|
|
|
|
DIRS="$(echo "$DIRS" | shuf)"
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "$format" == yad ];then
|
|
|
|
PREIFS="$IFS"
|
|
|
|
IFS=$'\n'
|
|
|
|
LIST=''
|
|
|
|
for i in $DIRS
|
|
|
|
do
|
|
|
|
if [ "$i" == 'Installed' ];then
|
|
|
|
diricon="${DIRECTORY}/icons/folder-installed.png"
|
|
|
|
else
|
|
|
|
diricon="${DIRECTORY}/icons/folder.png"
|
|
|
|
fi
|
|
|
|
|
|
|
|
LIST="${LIST}$diricon
|
|
|
|
${DIRECTORY}/icons/none-24.png
|
|
|
|
$i
|
|
|
|
$i/
|
|
|
|
App folder
|
|
|
|
"
|
|
|
|
done
|
|
|
|
|
|
|
|
for i in $APPS
|
|
|
|
do
|
|
|
|
LIST="$LIST$(echo "${DIRECTORY}/icons/$(cat "${DIRECTORY}/data/status/${i}" 2>/dev/null || echo "none").png")
|
|
|
|
${DIRECTORY}/apps/${i}/icon-24.png
|
|
|
|
$i
|
|
|
|
$i
|
|
|
|
"\("$(cat "${DIRECTORY}/data/status/${i}" 2>/dev/null || echo "uninstalled")"\)" $(echo "$(cat "${DIRECTORY}/apps/${i}/description" || echo "Description unavailable")" | head -n1)
|
|
|
|
"
|
|
|
|
done
|
|
|
|
IFS="$PREIFS"
|
|
|
|
|
|
|
|
elif [ "$format" == xlunch ];then
|
|
|
|
#XUNCH list format
|
|
|
|
|
|
|
|
PREIFS="$IFS"
|
|
|
|
IFS=$'\n'
|
|
|
|
LIST=''
|
|
|
|
for i in $DIRS
|
|
|
|
do
|
|
|
|
if [ "$i" == 'Installed' ];then
|
|
|
|
diricon="${DIRECTORY}/icons/folder-installed-64.png"
|
|
|
|
else
|
|
|
|
diricon="${DIRECTORY}/icons/folder-64.png"
|
|
|
|
fi
|
|
|
|
|
|
|
|
LIST="$LIST
|
|
|
|
${i};$diricon;${i}/"
|
|
|
|
done
|
|
|
|
|
|
|
|
for i in $APPS
|
|
|
|
do
|
|
|
|
LIST="$LIST
|
|
|
|
${i} "\("$(cat "${DIRECTORY}/data/status/${i}" 2>/dev/null || echo "uninstalled")"\)";${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" 1>/dev/null
|
|
|
|
#echo "Putting $icon in cache..." 1>&2
|
|
|
|
done
|
|
|
|
IFS="$PREIFS" ) &
|
|
|
|
|
|
|
|
echo "$LIST"
|