Examples
This commit is contained in:
commit
639842c7c8
3 changed files with 241 additions and 0 deletions
146
README.md
Normal file
146
README.md
Normal file
|
@ -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.
|
18
ruby/officount.rb
Executable file
18
ruby/officount.rb
Executable file
|
@ -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
|
77
shell/officount.sh
Executable file
77
shell/officount.sh
Executable file
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue