-
Notifications
You must be signed in to change notification settings - Fork 32
/
watchface
executable file
·430 lines (405 loc) · 12.1 KB
/
watchface
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
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
#! /bin/bash
VERSION="1.1"
function showVersion {
echo "watchface v${VERSION}"
}
function showHelp {
showVersion
cat << EOF
watchface [option] [command...]
Utility functions for AsteroidOS watchfaces. By default, uses "Developer Mode"
over ssh, but can also use "ADB Mode" using ADB.
Available options:
-h or --help print this help screen and quit
-a or --adb use ADB command to communicate with watch
-b or --boot reboot watch after deploying multiple watchfaces
-e or --every select every watchface (deploy only)
-g or --gui use the GTK+ gui
-p or --port specify an IP port to use for ssh and scp commands
-r or --remote specify the remote (watch) name or address for ssh and scp commands
-q or --qemu communicate with QEMU emulated watch (same as -r localhost -p 2222 )
-w or --wall WP set the wallpaper for deploy or test to the named file
Available commands:
update use git to update your local copy of the unoffical-watchfaces repository
version display the version of this program and exit
deploy WF push the named watchface to the watch and activate it
deployall deploy all watchfaces
clone WF NEWWF clone the named watchface WF to new watchface NEWWF
test WF test the named watchface on the computer using qmlscene
EOF
}
function runWatchCommand {
local user="$1"
local cmd=$2
case ${user} in
root)
if [ "$ADB" = "true" ] ; then
adb shell "${cmd}"
else
ssh -p "${WATCHPORT}" -t root@"${WATCHADDR}" ${cmd}
fi
;;
ceres)
if [ "$ADB" = "true" ] ; then
printf -v cmd %q "${cmd}"
adb shell "su -l -c ${cmd} ceres"
else
ssh -p "${WATCHPORT}" -t ceres@"${WATCHADDR}" ${cmd}
fi
;;
*)
echo "Error: unknown watch user ${user}"
;;
esac
}
function setDconf {
local dconfsetting="$1"
local filename="$2"
runWatchCommand "ceres" "dconf write ${dconfsetting} '\"file://${filename}\"'"
}
function pushFiles {
local user="$1"
local sourcedir="$2"
local destdir="$3"
if [ "$ADB" = "true" ] ; then
adb push ${sourcedir} "${destdir}"
else
scp -P"${WATCHPORT}" -r ${sourcedir} "${user}@${WATCHADDR}:${destdir}"
fi
}
function pushWatchface {
pushFiles "root" "${1}"'/usr/share/*' "/usr/share/"
}
function pushWallpaper {
local source="$1"
local wallpaper
wallpaper="$(basename "$1")"
local destination="/usr/share/asteroid-launcher/wallpapers/full/${wallpaper}"
pushFiles "root" "${source}" "${destination}"
setDconf "/desktop/asteroid/background-filename" "${destination}"
}
function restartCeres {
runWatchCommand "root" "systemctl restart user@1000"
}
function rebootWatch {
runWatchCommand "ceres" "reboot"
}
function activateWatchface {
setDconf "/desktop/asteroid/watchface" "/usr/share/asteroid-launcher/watchfaces/${1}.qml"
}
function watchfaceClone {
local files
mapfile -t files <<<"$(find . -path './'"$1"'/*' -type f | awk '{ dst=$0 ; gsub(/'"$1"'/,"'"$2"'",dst); print $0 "|" dst }')"
for filepair in "${files[@]}" ; do
IFS="|" read -r -a srcDstPaths <<< "${filepair}"
#echo "Copying from ${srcDstPaths[0]} to ${srcDstPaths[1]}"
destdir="${srcDstPaths[1]%/*}"
extension="${srcDstPaths[1]##*.}"
mkdir -p "${destdir}"
cp "${srcDstPaths[0]}" "${srcDstPaths[1]}"
if [ "${extension}" = "qml" ] ; then
sed -i "s/$1/$2/g" "${srcDstPaths[1]}"
fi
done
}
function sanitizeSourceWatchface {
# trim trailing / if present
local face="${1%/*}"
if [[ ! -d "${face}/usr/share/asteroid-launcher/watchfaces/" ]] ; then
echo "Error: ${face} does not appear to be a watchface" >&2
exit 1
fi
echo "${face}"
}
function deployface {
local sourcewatchface
local activate="$2"
if ! sourcewatchface=$(sanitizeSourceWatchface "$1") ; then
exit 1
fi
echo "Deploying ${sourcewatchface}"
pushWatchface "${sourcewatchface}"
if [ "${activate}" = "true" ] ; then
activateWatchface "${sourcewatchface}"
if [ -n "${WALLPAPER}" ] ; then
pushWallpaper "${WALLPAPER}"
fi
fi
}
function testface {
local sourcewatchface
if ! sourcewatchface=$(sanitizeSourceWatchface "$1") ; then
exit 1
fi
echo "Testing ${sourcewatchface}"
if [ -n "${WALLPAPER}" ] ; then
qmlscene "${sourcewatchface}" "${WALLPAPER}" "${sourcewatchface}/usr/share/asteroid-launcher/watchfaces/" loader.qml
else
qmlscene "${sourcewatchface}" "background.jpg" "${sourcewatchface}/usr/share/asteroid-launcher/watchfaces/" loader.qml
fi
}
function cloneface {
local sourcewatchface
local destwatchface="$2"
if ! sourcewatchface=$(sanitizeSourceWatchface "$1") ; then
exit 1
fi
echo "Cloning ${sourcewatchface} into ${destwatchface}"
if [ -e "${destwatchface}" ] ; then
echo "Error: ${destwatchface} already exists, exiting program"
exit
fi
watchfaceClone "${sourcewatchface}" "${destwatchface}"
}
function guiMenu {
local watchface
local action
local default
if ! action=$(zenity --title="Select action" --list --radiolist \
--column="selected" --column="action" \
TRUE deploy \
FALSE clone \
FALSE test); then
exit
fi
if [ "${DEFAULTOPTION}" == "ON" ] ; then
default=TRUE
else
default=FALSE
fi
case $action in
deploy)
declare -a args=('--title="Choose watchfaces"' "--list" "--checklist" '--column="Selected"' '--column="Name"')
for wf in "${WATCHFACES[@]}" ; do
args+=("${default}" "${wf}")
done
if ! watchface=$(zenity "${args[@]}"); then
exit
fi
;;
clone|test)
if ! watchface=$(zenity --title="Choose a watchface" --list --column="Name" "${WATCHFACES[@]}"); then
exit
fi
;;
esac
# convert | chars to spaces
watchface=${watchface//|/ }
if zenity --question --title="Confirming" --text="${action} ${watchface}" ; then
echo "OK!"
if [ "${action}" = "clone" ] ; then
if newface=$(zenity --entry --title="Cloning ${watchface}" \
--text="Enter name of new watchface:" \
--entry-text "newface")
then cloneface "${watchface}" "${newface}"
else echo "No name entered"
fi
elif [ "${action}" = "deploy" ] ; then
local first=true
for wf in ${watchface}; do
deployface "${wf}" "${first}"
first=false
done
restartCeres
if [ "${REBOOT}" = "true" ] ; then
rebootWatch
fi
else
testface "${watchface}"
fi
else
echo "Canceled"
fi
}
function textMenu {
local args
local watchface
local newface
if ! action=$(${MENUPROGRAM} --title "Select action" --clear --radiolist \
"Select action" 0 0 3 \
"deploy" "Deploy watchface to watch" ON \
"clone" "Clone watchface to new name" OFF \
"test" "Test watchface on computer" OFF \
3>&1 1>&2 2>&3); then
exit
fi
case $action in
deploy)
declare -a args=("--title" "Watchfaces" "--clear" "--checklist" "Choose watchfaces:" 25 78 15 "--" )
for wf in "${WATCHFACES[@]}" ; do
args+=("${wf}" "" "${DEFAULTOPTION}")
done
if ! watchface=$(${MENUPROGRAM} "${args[@]}" 3>&1 1>&2 2>&3); then
exit
fi
;;
clone|test)
declare -a args=("--title" "Watchfaces" "--clear" "--menu" "Choose a watchface:" 25 78 15 "--" )
for wf in "${WATCHFACES[@]}" ; do
args+=("${wf}" "")
done
if ! watchface=$(${MENUPROGRAM} "${args[@]}" 3>&1 1>&2 2>&3); then
exit
fi
;;
esac
if (${MENUPROGRAM} --clear --title "Confirming" --yesno "${action} ${watchface}" 0 0); then
echo "OK!"
if [ "${action}" = "clone" ] ; then
if newface=$(${MENUPROGRAM} \
--title "Cloning ${watchface}" --clear \
--inputbox "Enter name of new watchface:" \
8 50 "newface" \
3>&1 1>&2 2>&3)
then
cloneface "${watchface}" "${newface}"
else
echo "No name entered"
fi
elif [ "${action}" = "deploy" ] ; then
local first=true
for wf in ${watchface}; do
deployface "${wf}" "${first}"
first=false
done
if [ "${REBOOT}" = "true" ] ; then
rebootWatch
fi
else
testface "${watchface}"
fi
else
echo "Canceled"
fi
}
function deployall {
for wf in "${WATCHFACES[@]}" ; do
deployface "${wf}" false
done
}
# These are the defaults for SSH access
WATCHPORT=22
WATCHADDR=192.168.2.15
# These are the defaults for local QEMU target
QEMUPORT=2222
QEMUADDR=localhost
# Assume no ADB unless told otherwise
ADB=false
# Assume no GUI unless told otherwise
GUI=false
# Only show interactive prompt if the user hasn't
# already specified a command on the command line
SKIP_INTERACTIVE_PROMPT=false
# No wallpaper unless asked
WALLPAPER=""
# Default to all watchfaces unselected for deploy
DEFAULTOPTION=OFF
# Default to not deploying all watchfaces
DEPLOY_ALL=false
# Assume Dialog unless unavailable
if hash dialog 2>/dev/null; then
MENUPROGRAM="dialog"
elif hash whiptail 2>/dev/null; then
MENUPROGRAM="whiptail --separate-output"
fi
while [[ $# -gt 0 ]] ; do
case $1 in
-a|--adb)
ADB=true
shift
;;
-b|--boot)
REBOOT=true
shift
;;
-e|--every)
DEFAULTOPTION=ON
shift
;;
-g|--gui)
GUI=true
shift
;;
-q|--qemu)
WATCHPORT=${QEMUPORT}
WATCHADDR=${QEMUADDR}
shift
;;
-p|--port)
WATCHPORT="$2"
shift
shift
;;
-r|--remote)
WATCHADDR="$2"
shift
shift
;;
-h|--help)
showHelp
exit 1
;;
-w|--wall)
WALLPAPER="$2"
shift
shift
;;
clone)
cloneface "$2" "$3"
shift
shift
shift
SKIP_INTERACTIVE_PROMPT=true
;;
deployall)
DEPLOY_ALL=true
shift
SKIP_INTERACTIVE_PROMPT=true
;;
deploy)
deployface "$2" true
restartCeres
shift
shift
SKIP_INTERACTIVE_PROMPT=true
;;
test)
testface "$2"
shift
shift
SKIP_INTERACTIVE_PROMPT=true
;;
update)
git pull
shift
SKIP_INTERACTIVE_PROMPT=true
;;
version)
showVersion
shift
SKIP_INTERACTIVE_PROMPT=true
;;
*)
echo "Ignoring unknown option $1"
shift
;;
esac
done
mapfile -t WATCHFACES < <(find . -maxdepth 3 -type d -path "*/usr/share" -printf "%h\n" | sort | awk -F '/' '{print $2}' )
if [ "${SKIP_INTERACTIVE_PROMPT}" != "true" ] ; then
if [ "${GUI}" = "true" ] ; then
if hash zenity 2>/dev/null; then
echo "Error: install 'zenity' to use gui menus."
else
guiMenu
fi
else
if [ -z "${MENUPROGRAM}" ] ; then
echo "Error: install either 'dialog' or 'whiptail' to use text menus."
else
textMenu
fi
fi
elif [ "${DEPLOY_ALL}" == "true" ] ; then
deployall
fi