-
Notifications
You must be signed in to change notification settings - Fork 0
/
nelida.sh
executable file
·266 lines (241 loc) · 6.84 KB
/
nelida.sh
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
#!/bin/bash
HELP="
Usage: $0 [OPTIONS]...
OPTIONS
-h, --help Prints this help message
-l, --lang=code Selects between the available languages:
fr
--unsafe Executes the commands after a confirmation
"
# --ext-term Executes the commands in an external window
# Implies --unsafe, requires gnome-terminal
# (allows to launch interactive commands such as ssh)
# "
unsupported_lg="Language not supported."
if [ "${LANG:0:2}" = "fr" ]
then
HELP="
Utilisation: $0 [OPTIONS]...
OPTIONS
-h, --help Affiche ce message d'aide
-l, --lang=code Sélectionne parmi les langue disponibles :
fr
--unsafe Exécute les commandes après une confirmation
"
# --ext-term Exécute les commandes dans une fenêtre externe
# Implique --unsafe, requiert gnome-terminal
# (permet les commandes interactives telles que ssh)
# "
unsupported_lg="Langue non prise en charge."
fi
safe=true
ext_term=false
lang=fr
######################################################
# Parsing the command line
TEMP=`getopt -o hl: --long help,unsafe,lang: -n "$0" -- "$@"`
if [ $? != 0 ] ; then echo "Abandon" >&2 ; exit 1 ; fi
# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"
while true ; do
case "$1" in
-l|--lang)
if [ "$2" != "fr" ]
then
echo $unsupported_lg
fi
# TODO
shift 2 ;;
--unsafe)
safe=false
shift ;;
--ext-term)
safe=false
ext_term=true
shift ;;
-h|--help)
echo "$HELP"
exit 0 ;;
--) shift ; break ;;
*) echo "Internal error!" ; exit 1 ;;
esac
done
######################################################
rlwrap=$(which rlwrap)
if [ "$rlwrap" = "" ]
then
echo "
Note : Il est recommandé d'installer le paquet rlwrap pour une meilleure
expérience utilisateur. Cela permet la complétion des noms de fichiers
et le rappel de requêtes ou de commandes déjà utilisées.
"
fi
if $ext_term
then
prompt='echo -n $(date "+[%m-%d %H:%M:%S]") $(whoami)@$(hostname):$(pwd)\>" "'
session=$(mktemp -u)
mkfifo $session
gnome-terminal -e "cat $session | ssh localhost"
exec 3> $session
echo "Ce terminal externe est en lecture seule." >&3
echo "Placez-le à côté de votre console Nelida." >&3
eval $prompt >&3
fi
running=true
request_prompt="> "
command_prompt="$ "
ilar_options="-d 1 --time 2" # --source-segmentation characters"
log_path=~/.nelida/log/
db_path=~/.nelida/db/
log_err=$(date "+%y%m%d_%H%M%S_log_err.txt.gz")
log=$(date "+%y%m%d_%H%M%S_log.txt.gz")
pushd $(dirname $0) > /dev/null
path=$(pwd -P)
popd > /dev/null
mkdir -p $log_path $db_path
touch $db_path/incremental.{in,out}.txt
printf "detail db %s %s\n\n" "$(wc < $db_path/incremental.in.txt)" "$(wc < $db_path/incremental.out.txt)" | gzip >> $log_path/$log
echo "
Note : Les commandes que vous utilisez dans ce système sont enregistrées dans
les fichiers de logs qui vous seront demandés à l'issue de l'expérience.
N'utilisez pas de commandes sensibles (qui requièrent des mots de passe
en clair ou autre donnée personnelle ou sensible).
"
echo "Je suis Nelida, que puis-je pour vous ?"
while $running
do
echo
if [ "$rlwrap" != "" ]
then
request=$(rlwrap -C "nelida_request" -S "$request_prompt" -co cat)
else
read -p "$request_prompt" request
fi
if [ "$request" != "" ]
then
tmp=$(mktemp)
tmp_err=$(mktemp)
pushd $path/analogy/ > /dev/null
echo "$request" | ./ilar.sh -p $db_path/incremental $ilar_options 2> $tmp_err > $tmp
gzip < $tmp_err >> $log_path/$log_err
rm -f $tmp_err
gzip < $tmp >> $log_path/$log
if (( $? != 0 ))
then
printf "L'appel à ILAR a échoué, consultez le fichier de log : %s\n" "$log_path/$log" >&2
rm -f $tmp
exit 1
fi
popd > /dev/null
dev=$(grep "^detail deviation" < $tmp | wc -l)
ans=$(grep "^final" < $tmp | cut -b 7-)
rm -f $tmp
mem=false
learn=false
if [ "$ans" = "" ]
then
echo "Je ne sais pas comment faire."
learn=true
else
if (( $dev > 0 ))
then
printf "Je ne suis pas sûr.. Je pense à quelque chose comme ça :\n"
fi
printf "\n$ %s\n\n" "$ans"
read -n1 -p "Est-ce correct ? (o)ui/(n)on/(A)nnuler " validate
echo
if [ "$validate" = "O" ] || [ "$validate" = "o" ]
then
mem=true
else
if [ "$validate" = "N" ] || [ "$validate" = "n" ]
then
printf "status invalid\n\n" | gzip >> $log_path/$log
learn=true
fi
fi
fi
if $learn
then
read -n1 -p "Pouvez-vous/souhaitez-vous m'apprendre ? (O)ui/(n)on " show
echo
if [ "$show" = "O" ] || [ "$show" = "o" ] || [ "$show" = "" ]
then
echo "Entrez la commande correcte : "
if [ "$rlwrap" != "" ]
then
ans=$(rlwrap -C "nelida_command" -S "$command_prompt" -co cat)
else
read -p "$command_prompt" ans
fi
if [ "$ans" != "" ]
then
mem=true
fi
fi
fi
if $mem
then
confirm=true
if ! $safe
then
if ! $ext_term
then
echo "Le contexte actuel est $(whoami)@$(hostname):$(pwd)"
fi
read -n1 -p "Dois-je exécuter la commande dans ce contexte ? (o)ui/(N)on " exe
echo
if [ "$exe" = "o" ] || [ "$exe" = "O" ]
then
if $ext_term
then
echo $ans >&3
eval $ans >&3
if $ext_term
then
eval $prompt >&3
fi
else
echo
eval $ans
echo
printf "Commande exécutée, code de retour : %d\n" "$?"
fi
read -n1 -p "Cela a-t-il fonctionné comme prévu ? (o)ui/(n)on/(A)nnuler " ok
echo
if [ "$ok" != "o" ] && [ "$ok" != "O" ]
then
confirm=false
fi
else
confirm=false
fi
fi
if $confirm
then
if ! $learn
then
printf "status valid\n\n" | gzip >> $log_path/$log
fi
tmp_file=$(mktemp)
printf '%s\t%s\n' "$request" "$ans" > $tmp_file
if (( $(wc -l < $db_path/incremental.in.txt) < $(paste $db_path/incremental.in.txt $db_path/incremental.out.txt | cat - $tmp_file | LANG= sort | uniq | wc -l) ))
then
echo "$request" >> $db_path/incremental.in.txt
echo "$ans" >> $db_path/incremental.out.txt
printf "Bien. Je mémorise l'association. (%d au total)\n" $(wc -l < $db_path/incremental.in.txt)
fi
rm -f $tmp_file
fi
fi
echo "Entrez votre requête. Une ligne vide ou <ctrl>-d pour quitter."
else
running=false
fi
done
if $ext_term
then
exec 3>&-
rm -f $session
fi
echo "Au revoir."