Memories
box

Boîte
à souvenirs

A propos de ce site

A l'image de Michel Rolland et de, certainement, beaucoup d'autres, je me suis posé des questions sur la survie de Flick'r au moment de l'offre de rachat de Yahoo ! par Microsoft. Même si ces dernières n'ont pas abouti, mes interrogations ne m'ont pas quitté, d'autant plus que Flick'r ne semble pas une priorité de Yahoo !. Or, je préfèrerais récupérer mes données, avant d'être dans la situation que décrit Karl dans ce billet.

Mes besoins

Récupérer les métadonnées de Flick'r

Ce ne sont pas tant les photos qui m'inquiètent, car j'en possède bien évidemment une sauvegarde, mais les métadonnées que j'ai patiemment ajoutées à chacune d'elles. Or, qui dit métadonnées, dit.... RDF.

Comme je l'avais signalé à Michel Rolland, plusieurs scripts proposent des exports selon le modèle RDF depuis Flick'r, mais ils me semblaient un poil complexe à exploiter. La solution est venue d'un service mis au point par Masaka qui permet de récupérer les métadonnées associées à une photo sous la forme d'un flux RDF/XML, en précisant simplement l'URL de la page Flickr correspondant à la photo.

Valoriser les photos et les métadonnées

La question de la récupération résolue, il fallait passer à la suivante : « Comment mettre en valeur les photos et leurs métadonnées ? Â».

Deux directions m'ont guidé pour y répondre.

D'une part, je souhaitais rassembler les différentes photos sous la forme d'albums correspondant à un événement : visites, voyages, conférences... Mais, à la différence des sets dans Flick'r, je souhaitais, d'autre part, associer un certain nombre d'informations sur le lieu de la visite (géo-localisation, présentation du lieu...).

Or, toutes ces données sont déjà mises à disposition sous une forme normalisée (RDF) dans le Web de données, par l'intermédiaire de Dbpedia, Geonames ou Freebase entre autres. Il me suffisait donc de les récupérer afin d'intégrer ces données brutes au sein de mon application.

C'est bien tout l'intérêt du Web de données : proposer des données brutes indépendantes des usages, disponibles sous une forme normalisée et accessibles avec un protocole normalisé et bien connu (HTTP) afin que tout un chacun puisse les réutiliser à sa guise.

CQFD...

Faire évoluer l'application sans faire évoluer les données

Je n'avais pas d'a priori sur les différentes fonctionnalités et les modalités de navigation au sein des photos et des albums. Je ne voulais pas limiter les possibilités actuelles et futures de l'application en créant une base de données relationnelles figée ou du moins dans laquelle j'aurais perdu la très grande majorité des données que j'avais récupérées en RDF, en les limitant aux besoins que j'avais identifiés aujourd'hui.

Par conséquent, il me semblait plus constructif et plus souple d'indexer non seulement les données récupérées de Flick'r et du Web de données, mais aussi la description d'un événement dans un triple store RDF.

Afin de faciliter les développements, je me suis tourné vers le framework mis au point par Benjamin Nowack, ARC qui indexe les triplets RDF dans MySQL et offre une API en PHP pour y accéder.

La mise en Å“uvre

Décrire l'événement

Chaque événement est décrit en RDF (pour la sérialisation, ma préférence va à XML, désolé pour les puristes...) grâce à l'ontologie spécifique mise au point par Yves Raymond et Samer Abdallah. Cette dernière permet pour chaque événement d'associer les participants, le lieu, la date et le résultat de l'événement, dans mon cas, des photos.

Par ailleurs, grâce au vocabulaire RDF « review Â» mis au point pour les besoins du site revyu, il m'est possible d'ajouter un ou plusieurs avis sur chaque événement, en précisant une notation subjective.

Finalement, la description d'un événement ressemble au fichier RDF/XML suivant :

[snip]
<event:Event rdf:about="http://www.lespetitescases/souvenirs/
   20060925-mycenes">
   <rdfs:label>Visite de Mycènes</rdfs:label>
   <event:sub_event 
   rdf:resource="http://www.lespetitescases/souvenirs/
   2006-voyagegrece"/>
   <event:agent 
   rdf:resource="http://www.lespetitescases.net/foaf_got.rdf#GP"/>
   <event:place rdf:resource="http://dbpedia.org/resource/Mycenae"/>
   <event:time>
      <time:TemporalEntity>
            <time:hasBeginning>
               <time:Instant>
                  <time:inDateTime>
                        <time:DateTimeDescription>
                           <time:year>2006</time:year>
                           <time:month>09</time:month>
                           <time:day>25</time:day>
                        </time:DateTimeDescription>
                  </time:inDateTime>
               </time:Instant>
            </time:hasBeginning>
      </time:TemporalEntity>
   </event:time>
   <event:product 
   rdf:resource="http://static.flickr.com/117/
   256750086_3b3c3ba710.jpg"/>
   <rev:hasReview>
      <rev:Review>
            <rev:rating>5</rev:rating>
            <rev:reviewer 
	    rdf:resource="http://www.lespetitescases.net/
	    foaf_got.rdf#GP"/>
            <rev:text>
               Mycènes, [snip]
            </rev:text>
      </rev:Review>
   </rev:hasReview>
</event:Event>
[snip]

Récupérer et indexer des données

Un script permet d'indexer ce fichier RDF dans le triple store et va guider la récupération et l'indexation des autres données, si nécessaire :

  1. les données des profils FOAF s'ils sont indiqués 
  2. les données RDF associées à la ressource du lieu dans Dbpedia 
  3. les données associées à la ressource de Dbpedia par le prédicat owl:sameAs 
  4. les données de Flick'r transformées automatiquement par le service de Masaka 

Bref, pour résumer, une fois le fichier RDF écrit et chargé, le script s'occupe de rapatrier toutes les données qui lui sont liées, sans intervention supplémentaire.

Interroger les données

L'indexation des données en RDF implique l'utilisation de SPARQL, le langage de requêtes normalisé par le W3C de RDF. Voici quelques exemples :

Récupération des données de base d'un événement (titre, l'URI de la première photo, date et éventuellement URI et titre de l'événement dont il dépend):

SELECT ?label ?photo ?yearbegin 
?monthbegin ?daybegin ?eventparent ?eventparentlabel
WHERE {
<http://www.lespetitescases/souvenirs/20070813-lagarde> rdfs:label ?label;
event:product ?photo;
event:time ?temporalentity.
?temporalentity time:hasBeginning ?instant.
?instant time:inDateTime ?datetime.
OPTIONAL {
<http://www.lespetitescases/souvenirs/20070813-lagarde> event:sub_event 
?eventparent.
?eventparent rdfs:label ?eventparentlabel.}.
OPTIONAL { ?datetime time:year ?yearbegin.}.
OPTIONAL { ?datetime time:month ?monthbegin.}.
OPTIONAL {?datetime time:day ?daybegin.}.
}
LIMIT 1

Récupération de tous les mots-clés associés aux photos contenues dans ma base :

SELECT DISTINCT ?topic WHERE {
?s <http://purl.org/NET/c4dm/event.owl#product> ?photo .
?photo <http://xmlns.com/foaf/0.1/topic> ?topic
}

Récupération de la longitude, de la latitude et éventuellement du nom normalisé dans Geonames du lieu d'un événement précis :

SELECT ?name ?long ?lat WHERE {
<http://www.lespetitescases/souvenirs/20070813-lagarde> event:place ?place.
?place geo:long ?long;
geo:lat ?lat;
owl:sameAs ?sameas.
OPTIONAL { ?sameas a geonames:Feature;
geonames:name ?name.}}

Récupération du titre, de l'URL de la page Web dans Flick'r, du nom du créateur d'une photo précise et de l'URI et du titre de l'événement auquelle elle est reliée :

SELECT ?title ?page ?name ?event ?label WHERE {
<http://static.flickr.com/1436/1296393091_c38d1bb515.jpg> dc:title ?title;
foaf:page ?page;
dc:creator ?creator.
?creator foaf:name ?name.
?event event:product <'.$this->uri.'>;
rdfs:label ?label.
}

Cerise sur le gâteau, grâce à SPARQL et ARC, j'ai mis en place en un rien de temps un point d'accès SPARQL, protocole sous la forme de Web service normalisé par le W3C, qui permet à tout un chacun d'interroger à sa guise mes données.

Et pour la touche finale : un joli petit graphisme

Afin de rendre plus agréable la consultation du site, il était nécessaire de ne pas se contenter d'un graphisme basique comme on le fait trop souvent quand nous faisons des expérimentations technologiques. En effet, cette attitude a tendance à faire croire que l'utilisation des technologies du Web sémantique est incompatible avec la possibilité de disposer d'un site Web digne de ce nom. Or, il s'agit de deux choses différentes.

Manue m'a donc concocté un petit graphisme que je trouve pour ma part très joli et qui met bien en valeur les photos et les modalités de navigation. Merci beaucoup.

En guise de conclusion

Si le Web 2.0 a permis le développement sur le Web d'une certaine forme d'intelligence collective avec des initiatives tels que Wikipedia, il a aussi dans de nombreux cas induit une captation des données par des sociétés commerciales. En offrant des mécanismes standardisés de structuration, de mise à disposition, d'échanges et d'interrogation des données à l'échelle du Web, les technologies du Web sémantique que certains assimilent au Web 3.0 permettent non seulement de mieux exploiter toutes les données créées et mises à disposition sur le Web et offrent aux utilisateurs un moyen de reprendre le contrôle de leurs données et leur rendent leur capacité de choix.

Il y a quelques années, les utilisateurs du Web se le sont réappropriés au fur et à mesure grâce à une utilisation plus stricte des standards CSS et HTML, entre autres, causant en partie la remise en cause de la stratégie de Microsoft sur le Web (même si c'est pas encore complètement gagné). Gageons que l'appropriation et l'utilisation des standards du Web sémantique amèneront les Google, Facebook et consorts à remettre en question leur stratégie de main mise sur les données des utilisateurs.

Bref, les technologies du Web sémantique et le Web de données (le Web 3.0 ??) seront-t-il les sauveurs des idéaux du Web 2.0 ? Personnellement, je ne me pose plus la question, j'en suis convaincu.


Warning: mysql_connect() [function.mysql-connect]: Unknown MySQL server host 'mysql5-32' (1) in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 55

Visiter par carte

carte

Visiter par nuage


Warning: mysql_connect() [function.mysql-connect]: Unknown MySQL server host 'mysql5-32' (1) in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 55

Warning: mysql_real_escape_string() expects parameter 2 to be resource, boolean given in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 415

Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 416

Warning: mysql_connect() [function.mysql-connect]: Unknown MySQL server host 'mysql5-32' (1) in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 55

Warning: mysql_real_escape_string() expects parameter 2 to be resource, boolean given in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 415

Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 416

Warning: mysql_connect() [function.mysql-connect]: Unknown MySQL server host 'mysql5-32' (1) in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 55

Warning: mysql_real_escape_string() expects parameter 2 to be resource, boolean given in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 415

Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 416

Warning: mysql_connect() [function.mysql-connect]: Unknown MySQL server host 'mysql5-32' (1) in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 55

Warning: mysql_real_escape_string() expects parameter 2 to be resource, boolean given in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 415

Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 416

Warning: mysql_connect() [function.mysql-connect]: Unknown MySQL server host 'mysql5-32' (1) in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 55

Warning: mysql_real_escape_string() expects parameter 2 to be resource, boolean given in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 415

Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 416

Warning: mysql_connect() [function.mysql-connect]: Unknown MySQL server host 'mysql5-32' (1) in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 55

Warning: mysql_get_server_info(): supplied argument is not a valid MySQL-Link resource in /home/lespetitA/www/souvenirs/arc/store/ARC2_Store.php on line 87

Warning: mysql_query(): supplied argument is not a valid MySQL-Link resource in /home/lespetitA/www/souvenirs/arc/store/ARC2_StoreSelectQueryHandler.php on line 96

Warning: mysql_error(): supplied argument is not a valid MySQL-Link resource in /home/lespetitA/www/souvenirs/arc/store/ARC2_StoreSelectQueryHandler.php on line 97

Warning: Invalid argument supplied for foreach() in /home/lespetitA/www/souvenirs/memories-class.php on line 186

Warning: array_values() [function.array-values]: The argument should be an array in /home/lespetitA/www/souvenirs/memories-class.php on line 194

Warning: Wrong parameter count for min() in /home/lespetitA/www/souvenirs/memories-class.php on line 194

Warning: array_values() [function.array-values]: The argument should be an array in /home/lespetitA/www/souvenirs/memories-class.php on line 195

Warning: Wrong parameter count for max() in /home/lespetitA/www/souvenirs/memories-class.php on line 195

Warning: Invalid argument supplied for foreach() in /home/lespetitA/www/souvenirs/memories-class.php on line 197

Visiter par label