Faire des qcm simplement - retour accueil
git clone git://bebou.netlib.re/qcm
Log | Files | Refs | README |
qcm.sh (6128B)
1 #! /bin/sh 2 3 usage() { 4 <<-. cat 5 Faire des sondages simples en parsant les logs d'un serveur web 6 7 Usage : qcm [-h] [-e] [-u url] [-l logs] [-g] [-i identifiant] [-d dossier] 8 9 url par défaut : http://bebou.netlib.re (modifiable dans le code) 10 log par défaut : /var/log/nginx/access.log (modifiable dans le code) 11 dossier avec html des rés : /var/www/bebou.netlib.re (modifiable dans le code) 12 nombre d'options par défaut : 4 (ABCD) 13 identifiant par défaut : match la regex [a-zA-Z0-9]{3} 14 15 Exemples : 16 17 qcm # écrire le questionnaire sur le moment avec tous les défauts 18 qcm -u http://monsite.com # modifier l'affichage de l'url 19 qcm -l /var/log/httpd/logs # changer le chemin du log parcouru 20 qcm -e # masquer les réponses quand elles arrivent, mode "examen" 21 qcm -i fraise # lancer un questionnaire avec l'identifiant fraise 22 qcm -d /var/www/monsite # changer le dossier par défaut dans lequel afficher les résultats 23 cat mon-questionnaire.qcm | qcm # lancer le questionnaire .qcm 24 cat mon-questionnaire.qcm | ssh compte@serveur qcm # le lancer à distance mais ne fonctionne pas encore ! 25 26 Pour une explication plus détaillée voir le README ou 27 http://arthur.bebou.netlib.re/qcm 28 . 29 } 30 31 show() { 32 <<-. tee "$webdir/index.html" | grep -Ev "(<pre>|</pre>)" | cat 33 <pre> 34 exemple de réponse : $url/$id/A 35 url des résultats (à rafraichir manuellement) : $url/$id 36 37 $question 38 39 $context 40 41 $groupedanswers 42 43 total : $tot 44 </pre> 45 . 46 } 47 48 gplot() { 49 gnuplot -e " 50 set term dumb 75,13; 51 set border 1+2; 52 set ytics scale 0 nomirror autofreq 1; 53 set xtics nomirror; 54 set yrange [0:*]; 55 plot '-' u 1:xtic(2) w histo not; 56 " | sed 's/-/━/g; s/|/┃/g; s/ \* / ┃ /g; s/ \*\*/ ┏━/g; s/━+/━━/g; s/+━/┗━/g; 57 s/\([0-9]\) +/\1 ┃/g; s/\(┃ \+\)+/\1 /g; s/\*\* /━┓ /g; s/\*\*\*/━━━/g; 58 s/\*\*/━━/g;s/━\*━/━━━/g' 59 } 60 61 62 calcandshow() { 63 plotcmd="$1";hide="$2" 64 if [ -z "$uniqueanswers" ];then tot=0 65 else 66 if [ -n "$hide" ];then 67 groupedanswers= 68 else 69 if [ "$type" = "qcm" ];then 70 sortanswers='while read line;do echo "$line" | grep -o . | sort -u | tr -d "\n";printf "\n";done' 71 elif [ "$type" = "vote" ];then 72 sortanswers='grep -o .' 73 else 74 sortanswers='cat' 75 fi 76 groupedanswers=$(echo "$uniqueanswers" | 77 grep -Eo "/$id/[^ ]+ " | cut -d'/' -f3- | # PARSAGE DE LOG 78 eval $sortanswers | 79 sed 's,%\([0-9A-F][0-9A-F]\),\\\\\x\1,g' | xargs printf "%b\n" | 80 grep -v "^$" | 81 sort | uniq -c | sort -rn | $qplotcmd ) 82 fi 83 tot=$(echo "$uniqueanswers" | wc -l) 84 fi 85 86 context=$(case "$type" in 87 ( "ouverte" ) : ;; 88 ( "regex" ) printf "format autorisé : %s" "$options" ;; 89 ( * ) 90 [ "$choix" = "+" ] \ 91 && printf "%s\n" "plusieurs choix possibles" \ 92 || printf "%s\n" "un seul choix possible" 93 [ -n "$options" ] \ 94 && printf "%s" "$(echo "$options" | tr '~' '\n' | paste "$tmpd/o" -)" \ 95 || printf "options : %s" "$(< "$tmpd/o" paste -d '\0' -s -)" 96 ;; 97 esac) 98 99 clear 100 show 101 } 102 103 demander() { 104 case "$type" in 105 ( "ouverte" ) pattern=; qplotcmd="cat";; 106 ( "regex" ) pattern="${options:-[ABCD] } "; qplotcmd="cat";; 107 ( * ) 108 possibleanswers="ABCDEFGHIJKLMNOPQRSTUVWXYZ" 109 [ -n "$options" ] && nbq=$(( $(echo "$options" | grep -o '~' | wc -l) + 1 )) 110 echo "$possibleanswers" | grep -o '.' | head -n"$nbq" > "$tmpd/o" 111 answers=$(< "$tmpd/o" tr -d '\n') 112 pattern="[$answers]$choix " 113 qplotcmd="$plotcmd";; 114 esac 115 pattern="GET /$id/$pattern" 116 117 [ -p "$tmpd/notif" ] || mkfifo "$tmpd/notif" 118 tail -fn0 "$logs" | grep --line-buffered -E "$pattern" >> "$tmpd/in" & # PARSAGE DE LOG 119 tail1pid=$! 120 tail -fn0 "$logs" | grep --line-buffered -E "$pattern" > "$tmpd/notif" & # PARSAGE DE LOG 121 tail2pid=$! 122 123 calcandshow "$qplotcmd" "$hide" 124 cat "$tmpd/notif" | while read newanswer ;do 125 uniqueanswers=$(< "$tmpd/in" sort $uopt -k1,1) 126 [ "$olduniqueanswers" != "$uniqueanswers" ] && calcandshow "$qplotcmd" "$hide" 127 olduniqueanswers="$uniqueanswers" 128 done & 129 disppid=$! 130 131 read _ < /dev/tty 132 kill "$disppid" "$tail1pid" "$tail2pid" 133 134 if [ -n "$hide" ];then 135 uniqueanswers=$(< "$tmpd/in" sort $uopt -k1,1) 136 calcandshow "$qplotcmd" 137 read _ < /dev/tty 138 uniqueanswers=;groupedanswers=;tot=0 139 fi 140 141 rm "$tmpd/in" 142 } 143 144 nbq=4 145 uopt="-u" 146 plotcmd="cat" 147 148 while getopts "hegl:u:i:d:" opt; do 149 case $opt in 150 ( l | u | i | d ) [ -n "$OPTARG" ] && eval "$opt='$OPTARG'" ;; 151 ( g ) command -v gnuplot > /dev/null && plotcmd="gplot" ;; 152 ( h ) usage; exit ;; 153 ( e ) hide="yes";; 154 ( * ) echo "Option inconnue, voir l'aide en lançant qcm -h";exit 1;; 155 esac 156 done 157 158 url="${u:-http://bebou.netlib.re}" 159 logs="${l:-/var/log/nginx/access.log}" 160 161 162 [ ! -e "$logs" ] && { echo "fichier de log '$logs' n'existe pas" >&2;exit 1; } 163 164 tmpd=$(mktemp -d "${TMPDIR:-/tmp}/qcm.XXXXXX") 165 if [ -n "$i" ];then 166 existingids=$(ps -A -l -f | grep "[ /]qcm " | 167 grep -o -- '-i [^ ]\+' | 168 cut -d' ' -f2 | sort | uniq -c) 169 while echo "$existingids" | grep -q " \+[3-9] \+$i";do 170 if [ ! -t 0 ];then echo "id existe déjà"; exit 1; 171 else printf "id existe déjà, nouvel id : "; read i < /dev/tty 172 fi 173 done 174 id="$i" 175 else 176 id=$(basename "$tmpd" | cut -d'.' -f2) 177 fi 178 179 webdir="${d:-/var/www/bebou.netlib.re}"/$id 180 mkdir "$webdir" || { echo "Impossible de créer le dossier '$webdir'" >&2;exit 1; } 181 182 alias question:=question; question() { question="$*"; } 183 alias type:=type; type() { type="$*"; } 184 alias options:=options; options() { options="$*"; } 185 alias choix:=choix; choix() { [ "$*" = "multiple" ] && choix="+" || choix=; } 186 alias unique:=unique; unique() { [ "$*" = "non" ] && uopt= || uopt="-u"; } 187 188 trap 'rm -rf "$tmpd" "$webdir";exit' INT TERM QUIT 189 trap 'kill 0' EXIT 190 191 if [ -t 0 ];then 192 <<-. cat 193 Ecrivez le questionnaire puis ctrl+d sur une ligne vide pour le soumettre 194 syntaxe du questionnaire : 195 http://arthur.bebou.netlib.re/qcm/#le-format-du-fichier-de-questionnaire 196 . 197 fi 198 199 cat > "$tmpd/questions" 200 file="$tmpd/questions" 201 . "$file"