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 :
- les données des profils FOAF s'ils sont indiqués
- les données RDF associées à la ressource du lieu dans Dbpedia
- les données associées à la ressource de Dbpedia par le prédicat owl:sameAs
- 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
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
Warning: Invalid argument supplied for foreach() in /home/lespetitA/www/souvenirs/facettes.php on line 12