commit 639842c7c88eaaf1c26a4378a5fea5083cc61bb5 Author: Glenn Y. Rolland Date: Thu Apr 12 16:00:52 2018 +0200 Examples diff --git a/README.md b/README.md new file mode 100644 index 0000000..39f98d0 --- /dev/null +++ b/README.md @@ -0,0 +1,146 @@ + +# Kateryna - Mini-Projet d'introduction à ruby + +## Officience Make-It-Count (offimic) + +Les bureaux parisiens d'Officience accueillent un co-working à norme sociale et des évènements. Dans cet espace la possibilité d'occuper une place libre dans des conditions de travail optimales est très variables. + +L'objectif de ce projet est de produire un ensemble d'outils permettant de mesurer, d'analyser et d'anticiper le nombre de personnes présentes et l'occupation de l'espace. + + +---- + +## Phase I - Collecter les données + +Écrire un script `offimic-api` : + +- Ce script doit implémenter un serveur HTTP avec une API REST. +- Son API doit permettre de collecter et restituer les données collectées. + + +### Technologies + +- Le serveur HTTP sera codé en Ruby . +- Il utilisera la bibliothèque Sinatra. + + +### Fonctionnement + +Le serveur devra être capable de répondre aux requêtes suivantes : + +#### GET /history__ + +- Retourne l'historique des mesures collectées, au format CSV + +#### GET /count/:value + +- Enregistre la valeur `:value` pour la date/heure correspondant à celle de la requête +- Retourne `"OK"` ou `"ERROR"`, selon que l'enregistrement est réussi ou non. + + +---- + +## Phase II - Mesurer l'occupation + +Ecrire un script `offimic-measure`. Il doit permettre de + +- faire une mesure du nombre de personnes présentes sur le réseau ; +- d'envoyer le résultat de la mesure à l'API `offimic-api`.. + +Le script sera ensuite lancé toutes les 10 minutes. + + +### Technologies + +- Le serveur HTTP sera codé en Ruby +- Il utilisera la bibliothèque Thor pour gérer la ligne de commande. +- Le script sera ensuite ajouté à une cron task. +- Il faut installer le package `arp-scan` sur le systeme (`apt-get install ...`) + +### Fonctionnement + +- Utiliser IO.popen et la commande suivante pour obtenir la liste des addresses mac actuellement sur le réseau (depuis la table ARP) + +~~~~ +arp-scan --interface=wlan0 --localnet --timeout 1500 --retry 4 --ignoredups --quiet \ + | sed -n -r '/([0-9a-f]{2}:){5}/p' \ + | wc -l +~~~~ + +### Références + +- http://ruby-doc.org/core-2.3.0/IO.html#popen-method + +---- + +## Phase III - Fichiers de configurations en JSON + +Modifier `offimic-api` et `offimic-measure` de telle sorte qu'ils lisent un fichier de configuration au démarrage et utilisent les paramètres qui y sont présents. + +Leur fichiers de configuration respectifs sont : + +- `~/.config/offimic/api.json` pour l'API +- `~/.config/offimic/measure.json` pour l'outil de mesure + +### Fonctionnement + +Ces fichiers seront de la forme suivante : + +~~~~ +{ + "schema": "https", + "host": "api.example.com", + "path": "/" + "port": "5000", +} +~~~~ + + +---- + +## Phase IV - API en JSON + +Modifier `offimic-api` de telle sorte que l'API produise du JSON. + +### Fonctionnement + +Les routes restent les mêmes, mais les réponses changent (voir exemples ci-dessous) : + +__GET /history__ + +~~~~ +{ + status: "ok", + body: [ + { scan_time: "2018-04-01 22:10:25 UTC+3", count: 3 }, + { scan_time: "2018-04-01 22:40:13 UTC+3", count: 4 }, + { scan_time: "2018-04-01 23:10:17 UTC+3", count: 4 }, + ] +} +~~~~ + +__GET /count/:value__ + +~~~~ +{ + status: "ok", + body: { scan_time: "2018-04-01 23:10:17 UTC+3", count: 4 }, +} +~~~~ + + +---- + +## Phase V - Stocker le hash pour chaque adresses MAC + +Modifier `offimic-measure` et faire en sorte d'enregistrer les adresses MAC des différentes machines présentes. + +Dans un second temps, on anonymisera les entrées pour stockes des hash MD5 qui correspondent à chaque adresse MAC plutot que les adresses MAC elle-mêmes. + +---- + +## TODO (futur / pas rédigé) + +- Permettre de blacklister certaines macadress qui ne sont pas ratachées à des individus (miniserveur, imprimante, freebox, etc.) => ils seront pas mentionnés dnas l'historique + +- Distinguer les personnes régulierement présentes des visiteurs occasionnels (= évenements) sur de courtes périodes. diff --git a/ruby/officount.rb b/ruby/officount.rb new file mode 100755 index 0000000..a74ac5b --- /dev/null +++ b/ruby/officount.rb @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +require 'sinatra' +require 'date' + +get '/history' do + File.open('history.csv', 'r') do |fh| + fh.read + end +end + +get '/count/:value' do + value = params[:value] + dt = DateTime.now + File.open('history.csv', 'a') do |fh| + fh.puts "#{dt.rfc3339}, #{value}" + end +end diff --git a/shell/officount.sh b/shell/officount.sh new file mode 100755 index 0000000..3702801 --- /dev/null +++ b/shell/officount.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +oc_handle_get() { + # on attrape le parametre de la fonction + line="$1" + + # le verble http (= le premier mot de la requete) + route="$(echo "$line" |sed -e 's/^GET *//')" + + echo "Route: $route" + + # table de routage + case "$route" in + /history) # faire des trucs pour history + cat history.csv >> input + # TODO: rediriger ça vers le client + ;; + + /count/*) # faire des trucs pour count + value="$(echo "$route" |sed -e 's|/count/||')" + timestamp="$(date --rfc-3339=seconds)" + + echo "$timestamp, $value" >> history.csv + ;; + esac +} + +oc_handle_post() { + >&2 echo "Warning: NOT YET IMPLEMENTED" +} + +oc_handle_request() { + # on attrape le parametre de la fonction + read line + # le verble http (= le premier mot de la requete) + verb="$(echo "$line" |awk '{print $1;}')" + + echo "Cat pid = $pid" + echo "Verb: $verb" + case "$verb" in + GET) + oc_handle_get "$line" + ;; + POST) + oc_handle_post "$line" + ;; + esac + echo "Closing pipe..." + exec 3>&- + > input +} + +# écouter sur le port 80 +# prendre une requete +# lire la requete 'GET ... ' + +# GET /history +# => oc_history +# GET /count/:value +# => oc_count +oc_server() { + port="$1" + + while true ; do + exec 3<> input + + >&3 cat input & + pid="$!" + + echo "Ready for next client !" + nc -l -q 1 -p "$port" <&3 -c "oc_handle_request" + #"$pid" + done +} + +oc_server "$1" +