forked from Botspot/pi-apps
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmanage
executable file
·258 lines (226 loc) · 10.7 KB
/
manage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#!/bin/bash
#$1 is an action, like install
#$2 is app name, like Arduino
DIRECTORY="$(readlink -f "$(dirname "$0")")"
function error {
echo -e "\e[91m$1\e[39m"
exit 1
}
if [ -z "$1" ];then
error "You need to specify an operation, and in most cases, which app to operate on."
fi
mkdir -p "${DIRECTORY}/data/status" "${DIRECTORY}/data/update-status"
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
#ensure an install script is not already running
if ps -C install ;then
echo "An install script is already running.
Pi-Apps will wait until that one finishes before installing $2." | 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 install ;do sleep 1; done
fi
#if already installed then ask for confirmation
if [ "$(cat "${DIRECTORY}/data/status/${2}" )" == 'installed' ];then
yad --text="$2 is already installed. Are you sure you want to install it again?" \
--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
#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
lxterminal --title="Installing $2" -e "
cd $HOME
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\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.'
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
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
#ensure an uninstall script is not already running
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 \
--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
if [ "$(cat "${DIRECTORY}/data/status/${2}" )" == 'uninstalled' ];then
yad --text="$2 is already uninstalled. Are you sure you want to uninstall it again?" \
--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
lxterminal --title="Uninstalling $2" -e "
cd $HOME
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\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.'
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
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
#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!"
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}')
newinstallhash=$(sha1sum "${DIRECTORY}/update/pi-apps/apps/${2}/install" | awk '{print $1}')
oldinstallhash=$(sha1sum "${DIRECTORY}/apps/${2}/install" | awk '{print $1}')
#echo -e "newinstallhash: $newinstallhash\noldinstallhash: $oldinstallhash"
#echo -e "newhash: $newhash\noldhash: $oldhash"
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
fi
#move old program to trash
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}"
if [ "$installback" == 'yes' ] && [ "$(cat "${DIRECTORY}/data/settings/Reinstall after update")" != 'No' ];then
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"
elif [ "$1" == 'check-all' ];then
#CHECK-ALL
#for this operation, a program name cannot be specified.
#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
updatable=''
PREIFS="$IFS"
IFS="|"
for app in $applist
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
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}"
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}"
#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}"
#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}"
#in this case, add to updatable list
updatable="${updatable}|${app}"
fi
fi
done
IFS="$PREIFS"
#remove initial '|' character
updatable="${updatable:1}"
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='|'
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"
"${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"\'", "\'"check-all"\'", or "\'"update-all"\'"."
fi