mardi 14 mai 2013

Trouve-moi un Vélo'v et autres développements autour des données ouvertes à Lyon

Avec plusieurs personnes d'OpenData69, je travaille autour des données publiques ou ouvertes dans le Rhône, et plus particulièrement à Lyon. Dans nos réalisations techniques, nous proposons — entre autre — différents démonstrateurs utilisant plusieurs jeux de données, dont ceux du Grand Lyon et des Vélo'v lyonnais de JCDecaux.

Ainsi, Emmanuel Scotto a réalisé un démonstrateur utilisant les données ouvertes du Grand Lyon ; sources.

Personnellement, je m'intéresse surtout aux vélos en libre service (en attendant les données des TCL…) avec un démonstrateur utilisant les données des Vélo'v de JCDecaux[1] ; sources.

Accueil démonstrateur vélov

Résultat démonstrateur vélov

Pour la suite, nous avons en tête différents outils pour permettre aux lyonnais de mieux utiliser leurs vélo'v :

  • des statistiques d'utilisations des stations : quelles sont les stations les moins/plus utilisées, à quelles périodes, etc. ;
  • des études sur les déplacements urbains : variation de l'utilisation des vélos selon la date (weekend, jour férié, vacances), la météo, les événements (rencontres sportives, concerts, etc.) ;
  • des prédictions de disponibilité/remplissage des stations : détection de motifs d'usages, et projections.

Ces travaux dépendent naturellement des API sur lesquelles nous pouvons nous appuyer, et donc de la volonté d'ouverture des administrations, des collectivités territoriales, et des entreprises.

Note

[1] sur IPv6, naturellement :)

dimanche 24 avril 2011

TraceFS, grep, et plus si affinités

Concept

L'idée est de présenter une trace modélisée sous forme d'arborescence de fichiers, via FUSE. Les accès se font par une combinaison d'utilisateur, de modèle, de trace, et d'observé. On peut alors avoir des choses comme /utilisateur/utilisateur4/modèles/modèle5/trace/trace3/observé/observé6.

L'intérêt est ensuite d'extraire les données avec des outils standards POSIX, pour consulter et éventuellement modifier les traces. Le format des fichiers peut être de différente sorte, selon l'option de montage du système de fichier (flat, json, n3, etc)

Exemple

Pour l'utilisateur « Damien », dans la trace « Exercice2 » de « WeeChat », savoir combien d'observés sont de type frappeClavier. On constate que la trace accédée directement par son nom via le sujet de la trace : le modèle est passé sous silence car ces informations suffisent à discriminer la trace dans la base de traces.

$ grep -irc "type=frappeClavier" /utilisateur/Damien/trace/Exercice2/ | wc -l
3151

[1]

L'avantage est de pouvoir directement interroger le SGBT avec des outils standards. Pour l'utilisateur, cela signifie :

  • une grande simplicité : pas besoin de concevoir de scripts python, d'apprendre des API ou de déployer du code sur le SGBT. Toutes les opérations se font avec des outils standards UNIX, voir POSIX, ce qui signifie une prise en main immédiate.
  • un important gain de temps : accéder au contenu d'un observé est immédiat, et ne nécessite que la lecture d'un fichier

Durant la phase de travail sur la conception d'un modèle de trace, ou l'instrumentation d'un outil, je vois un intérêt à ce genre d'approche.

Note

[1] les geeks auront repéré la blague dans la commande :)

mercredi 8 septembre 2010

Conception d'un service pour Mac OS : raccourcisseur d'URL

Le service web : bit.ly / j.mp

Bit.ly (qui existe aussi sous le nom J.mp[1]) est un outil web pour raccourcir les URL. Comme beaucoup d'autres outils web similaires, il propose une API qui permet d'interagir avec lui de façon automatisée.

About bit.ly
bit.ly allows users to shorten, share, and track links (URLs). Reducing the URL length makes sharing easier. bit.ly can be accessed through our website, bookmarklets and a robust and open API. bit.ly is also integrated into several popular third-party tools such as Tweetdeck. A more full list of third party tools can be found on the bit.ly blog. Unique user-level and aggregate links are created, allowing users to view complete, real-time traffic and referrer data, as well as location and metadata. Tracking stats are available after users shorten their long links with bit.ly by clicking on the “Info+” link on bit.ly, or just adding a “+” sign to the end of any bit.ly link (for example, http://bit.ly/n0og+).
[2]

J'utilise j.mp[3] au quotidien car il propose des outils intéressants pour le suivi et l'archivage des raccourcis créés. Il est tout à fait possible d'utiliser un autre outil à la place.

Code

Pour créer le service, nous allons utiliser l'IDE Automator d'Apple. Automator permet de combiner des « briques » élémentaires logicielles pour construire un workflow basic. Il s'agit donc d'un outil pour concevoir aisément des tâches automatisées.

Service web Mac OS - j.mp - création de projet

Les services sont des processus contextuels disponibles dans Mac OS X. Ils acceptent du texte ou des fichiers de l’application actuelle ou du Finder. Les services apparaissent dans le menu Services.

Service web Mac OS - j.mp - code

Le code en lui-même est très court : alimenté par le sélecteur automatique d'URL, on effectue une requête http sur l'API du service web pour récupérer l'adresse raccourcie; on la place alors dans le presse-papier du système. Cela signifie combiner deux briques d'Automator : exécution d'un script UNIX, et placer un élément dans le presse-papier.

Le script est une simple requête CURL utilisant en entrée les données fournies par le sélecteur : /usr/bin/curl "http://api.bit.ly/v3/shorten?login=IDENTIFIANT&apiKey=CLÉAPI&format=txt&domain=j.mp&longUrl=$1".

Avertissement : cette méthode implique de mettre en dur dans le code l'identifiant et la clé de l'API. Cela ne pose pas un problème en soit dans le cadre d'une utilisation personnelle, car le service que nous créons (J.mp) est stocké dans le profil de l'utilisateur : ~/Library/Services/J.mp.workflow. Toutefois, en cas de partage il faudra songer à changer les identifiants de connexion au service web; cela peut se faire directement avec un éditeur de texte dans le fichier Contents/document.wflow. Pour un déploiement plus large (plusieurs machines, mise à disposition globale à tous les utilisateurs de la machine, etc), un mécanisme de paramétrage sera à mettre en place (on peut songer à un fichier de préférences dans ~/.config/).

Un fois le code source enregistré dans Automator, le service est immédiatement opérationnel. En effet, MacOS stock directement le service dans ~/Library/Services/ sans demander à l'utilisateur où placer le projet. Pratique, mais inhabituel.

Références

Notes

[1] pour les personnes qui desperately need those two additional free characters in order to make your point, comme l'annonce le blog

[2] source

[3] prononcer jump

mardi 13 octobre 2009

Jouer avec un SGBT, c'est possible !

Il m'aura fallu un peu de temps, mais voici enfin deux scripts simples qui permettent de tester le KTBS de PA :

  • lancer_le_ktbs : démarre le KTBS en local
  • initialiser_le_ktbs : alimente le KTBS avec :
    • 1 utilisateur : alice
    • 1 modèle de trace : weechat
    • 1 trace : t01
    • 4 observés :
      1. joindre un canal
      2. envoyer un message
      3. recevoir un message
      4. quitter le canal

Avec ces scripts, il est possible de faire tourner un SGBT contenant des données afin d'interagir avec lui : demande d'observé, transformation, etc

Comment utiliser les scripts ? Facile.

-1) mettez en place un support IPv6 sur votre machine. Une adresse en fe80:* suffit

0) faites un checkout du KTBS : $ svn co https://svn.liris.cnrs.fr/sbt-dev/ktbs-rest-impl/trunk

1) ouvrez un terminal, et lancez le script lancer_le_ktbs avec comme argument le chemin vers bin/ktbs que vous venez de récupérer

Par exemple :

$ ./lancer_le_ktbs ../bin/ktbs 
=== Using IPV6
KTBS example at http://ip6-localhost:8001/

2) ouvrez un terminal, et lancez le script initialiser_le_ktbs. Admirez la sortie standard qui vous donne les valeurs de retour du KTBS (sauf celle de l'étape 2 qui est filtrée). Admirez également la sortie standard du KTBS qui vous indique les données reçues.

ip6-localhost - - [13/Oct/2009 16:26:51] "POST / HTTP/1.1" 201 0
ip6-localhost - - [13/Oct/2009 16:26:51] "POST /alice/ HTTP/1.1" 201 0
ip6-localhost - - [13/Oct/2009 16:26:52] "PUT /alice/weechat/ HTTP/1.1" 200 386
ip6-localhost - - [13/Oct/2009 16:26:52] "POST /alice/ HTTP/1.1" 201 0
ip6-localhost - - [13/Oct/2009 16:26:52] "POST /alice/t01/ HTTP/1.1" 201 0
ip6-localhost - - [13/Oct/2009 16:26:52] "POST /alice/t01/ HTTP/1.1" 201 0
ip6-localhost - - [13/Oct/2009 16:26:52] "POST /alice/t01/ HTTP/1.1" 201 0
ip6-localhost - - [13/Oct/2009 16:26:52] "POST /alice/t01/ HTTP/1.1" 201 0

Pointez maintenant votre navigateur préféré sur l'interface web du KTBS (http://ip6-localhost:8001/alice/t01/@obsels) et admirez votre trace (ou plus exactement celle d'Alice) de WeeChat conforme au modèle spécifié.



Vous pouvez maintenant travailler avec le KTBS.

mercredi 23 septembre 2009

Interconnexion application flash ↔ KTBS

Bonne nouvelle, les interconnexions sont en train de se mettre en place entre le KTBS et différents prototypes. Par contre, il reste du boulot.

Enfin bon, ça commence à tourner, c'est le principal. Voici un extrait de code en ActionScript montrant comment faire un aller-retour entre une application Flash et le KTBS. Notez la création simple de la liaison pour le service web via le HTTPService(). En revanche, ne me demandez pas (encore) comment on fait si la connexion timeout, saute, se bouche ou autre. Il est également possible d'utiliser directement des sockets, ce qui est pratique pour affiner les choses à la main.

Sérieusement, ce langage est immonde. Ça a la lourdeur du javascript, et la grammaire a été conçue par un polonais shooté à la vodka : ça ressemble presque à un langage normal, sauf quand ils se sont amusé à permuter l'ordre des éléments sans aucune raison valable (genre variable:type ← franchement, faut être malade pour inventer ça...). C'est supposé être un langage de haut niveau, userfriendly et tout, mais on se tape les contraintes héritées des années 70 (marqueur de fin de ligne, typage fort, etc). Et surtout ils ont tout pété entre les versions 2 et 3 du langage. Sans compter que le compilateur (en java) a le dynamisme d'une vache salers explosée au Lexomil.

Dernier détail : sur le papier, l'eventListener fonctionne, mais en pratique il ne me donne rien; je soupçonne fortement un tripatouillage interne des données, genre « bouge pas, je vais te mettre ça en forme et nettoyer ce qui ne sert pas ». Ben tiens...

// l'objet décrivant le SGBT
private var _sgbt :HTTPService;


/*
 * constructeur de KTBS
 */
public function SGBT() :void {
// création d'un service web sur le KTBS de PA
	_sgbt = new HTTPService();
	_sgbt.url = "http://ip6-localhost:8001/";
	_sgbt.method = "GET";
	_sgbt.contentType = "application/rdf+xml";
// reniflage de la réponse du KTBS, avec appel à reponse() en lui passant les données retournées
	_sgbt.addEventListener(ResultEvent.RESULT, reponse);
	_sgbt.send();
}


/*
 * traite les données reçues du KTBS
 * retourne : rien
 * mesData est l'événement provenant du listener sur requête du KTBS
*/
public function reponse(mesData :ResultEvent) :void {
	_sgbt.removeEventListener(ResultEvent.RESULT, reponse);
// trace() est une primitive de déboguage écrivant sur la sortie standard
	trace(mesData.result.toString());
}

mercredi 10 juin 2009

Appel à commentaires sur les modèles de trace

Avant propos

Il y a deux abréviations à connaitre.

i18n (internationalization) internationalisation

Les adaptations à faire sur les formats de données, selon les pays. Par exemple, comment on exprime une date (JJ/MM/AA, MM/DD/AA, etc), une monnaie ($123, 123€), un nombre (123.456 ou 123,456), etc. C'est un travail technique qui demande à faire abstraction du contenu pour en décrire sa structure.

CF l18n

l10n (localization) régionalisation

Il s'agit de la traduction à proprement parler.

WP :

La régionalisation de logiciel concerne le processus de traduction de l'interface utilisateur d'un logiciel d'une langue vers une autre et en l'adaptant à la culture locale. On utilise parfois le terme localisation, qui est une transposition du mot anglais localization (faux ami). On écrit parfois l10n car le mot localization est composé de dix lettres encadrées par un l et un n.

Avant qu'un logiciel ne soit régionalisé, il faut au préalable qu'il ait été internationalisé, c’est-à-dire qu'il ait été écrit pour pouvoir être traduit dans différentes langues et cultures.

CF l10n

Discussion sur les modèles

Pour construire l'interface de l'outil générique de visualisation interactive de trace (OGVIT), il faut que chaque attribut ait un nom compréhensible pour l'utilisateur. Ce qui veut dire qu'au couple attribut+valeur (par exemple, ktbs:hasTime et 1244638257), il faut ajouter un 3e élément qui est le « nom humain » (mercredi 10 juin 2009, 14:50:57)

De plus , ce nom humain doit pouvoir être internationalisé (et localisé), car tout le monde n'utilise pas la même langue. Ce qui veut dire qu'un observé, au final, doit autant être compréhensible par la machine que par l'humain. Si l'humain sait vaguement s'adapter, la machine elle a besoin d'un formalisme explicite.

Il existe plusieurs endroits où ajouter ces élément de i18n et de l10n :

Dans l'observé lui-même

  • avantage : l'information est immédiatement présente, on peut la traiter directement
  • inconvénients :
    • ça prend de la place, on répète l'information autant de fois qu'on a d'observés.
    • pour gérer plusieurs langues, il faudra ajouter autant d'éléments de traduction; c'est du gaspillage.

Dans le modèle de trace

  • avantage : c'est définit une fois pour toute; on économise de la place et du temps
  • inconvénients :
    • on se retrouve à trimbaler dans le modèles des informations dont on n'a pas besoin. Par exemple, moi je n'ai pas besoin de pouvoir exprimer mes dates en japonais.
    • ajouter une langue revient à reprendre le modèle, ce qui n'est pas toujours évident à faire car celui-ci n'est pas forcément modifiable. Par exemple, il peut être intégré dans une application dont on n'a pas les sources.

Dans un document à côté du modèle

  • avantages :
    • on peut modifier et compléter les traductions et formats sans toucher au modèle.
    • le modèle ne contient que la définition de la trace, le reste étant dans un document associé.
  • inconvénients :
    • quand on veut manipuler un modèle, il faut alors manipuler deux fichiers pour avoir les littéraux. Pas pratique.
    • ça complique le schmilblick.

Reste à décider. Vos avis sur la question ?

Exemple concret

Je souhaite visualiser la trace de ma (« Damien_traces ») frappe clavier dans weechat, mon client IRC tracé. La trace correspondant à l'envoi du message « bonjour » sur le canal #LIRIS de Freenode est la suivante :

@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix ktbs: <http://liris.cnrs.fr/~ithaca/ns/ktbs/0.1/> .
@prefix : <http://example.com/trace-model/> .

[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*b";
:zoneDeSaisieAvantCaractère "";
:zoneDeSaisieAprèsCaractère "b";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "b";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie " ";
:positionDuCurseurDansLaZoneDeSaisie "1";
ktbs:hasBegin "1244635383";
ktbs:hasEnd "1244635383";
ktbs:hasTrace <> ;
].

[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*o";
:zoneDeSaisieAvantCaractère "b";
:zoneDeSaisieAprèsCaractère "bo";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bo";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie "  ";
:positionDuCurseurDansLaZoneDeSaisie "2";
ktbs:hasBegin "1244635383";
ktbs:hasEnd "1244635383";
ktbs:hasTrace <> ;
].

[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*n";
:zoneDeSaisieAvantCaractère "bo";
:zoneDeSaisieAprèsCaractère "bon";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bon";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie "   ";
:positionDuCurseurDansLaZoneDeSaisie "3";
ktbs:hasBegin "1244635383";
ktbs:hasEnd "1244635383";
ktbs:hasTrace <> ;
].

[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*j";
:zoneDeSaisieAvantCaractère "bon";
:zoneDeSaisieAprèsCaractère "bonj";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bonj";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie "    ";
:positionDuCurseurDansLaZoneDeSaisie "4";
ktbs:hasBegin "1244635384";
ktbs:hasEnd "1244635384";
ktbs:hasTrace <> ;
].

[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*o";
:zoneDeSaisieAvantCaractère "bonj";
:zoneDeSaisieAprèsCaractère "bonjo";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bonjo";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie "     ";
:positionDuCurseurDansLaZoneDeSaisie "5";
ktbs:hasBegin "1244635384";
ktbs:hasEnd "1244635384";
ktbs:hasTrace <> ;
].

[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*u";
:zoneDeSaisieAvantCaractère "bonjo";
:zoneDeSaisieAprèsCaractère "bonjou";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bonjou";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie "      ";
:positionDuCurseurDansLaZoneDeSaisie "6";
ktbs:hasBegin "1244635385";
ktbs:hasEnd "1244635385";
ktbs:hasTrace <> ;
].

[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*r";
:zoneDeSaisieAvantCaractère "bonjou";
:zoneDeSaisieAprèsCaractère "bonjour";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bonjour";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie "       ";
:positionDuCurseurDansLaZoneDeSaisie "7";
ktbs:hasBegin "1244635385";
ktbs:hasEnd "1244635385";
ktbs:hasTrace <> ;
].

[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "return";
:zoneDeSaisieAvantCaractère "bonjour";
:zoneDeSaisieAprèsCaractère "";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie "";
:positionDuCurseurDansLaZoneDeSaisie "0";
ktbs:hasBegin "1244635386";
ktbs:hasEnd "1244635386";
ktbs:hasTrace <> ;
].

L'OGVIT est supposé construire automatiquement, à partir du modèle de la trace, la visualisation suivante.

Interface pour la visualisation de la trace des frappes clavier de weechat

On constate plusieurs choses :

  • c'est vide : ben oui, car je n'ai pas le modèle de cette trace, et d'une façon plus générale le format d'un modèle
  • il manque des informations pour construire la représentation de la trace : les noms (humains) des colonnes doivent provenir du modèle, ou du fichier de l10n associé.

Comme quoi, c'est vraiment là un problème technique et non pas scientifique. Il faut qu'on se force à prendre des décisions pour avancer.