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