One FOAF fits all

A few years ago, I created my FOAF profile with FOAF-O-Matic. But actually, I almost never updated it and its foaf:knows list.

So, now, I’ll let external websites manage those informations.
I have exports in RDF of my flickr, twitter and facebook accounts, as well as this weblog (in progress), and in most of them, I define those relationships to the people I know. Since all those files define a URI for myself, I can use my main (I mean hosted by my own) FOAF file as a reference profile that will link myself to my other URIs using owl:sameAs, and also add rdfs:seeAlso links to the related files (as described here), eg:

<owl:sameAs
  rdf:resource="http://apassant.net/home/2007/12/flickrdf/people/33669349@N00"
  rdfs:seeAlso="http://apassant.net/home/2007/12/flickrdf/data/people/33669349@N00"/>

<owl:sameAs
  rdf:resource="http://twitter.com/terraces"
  rdfs:seeAlso="http://tools.opiumfield.com/twitter/terraces/rdf"/>

And I’ll get a decentralized foaf:knows network, as shown on this graph:

onefoaf.png

Then, I can grab all these profiles in a local RDF store, or even better, use a dedicated Semantic Web “social graph manager” as Knowee or Beatnik to get all my contacts locally, get their e-mail, query profiles, or as David said, integrates in other desktop apps and sync with my iphone (ok, I don’t have one yet :) ) …

And if services as linked-in or bibliography repositories export FOAF URIs for anyone, as the FOAF/DBLP service already offers, I could even link to people I worked with. In case all those services exports data with only foaf:knows and I want to be more precice, I can refine relationships in my profile using the RELATIONSHIP vocabulary, or maybe even include rules in my profile that could then be taken into consideration by agents that will query it ? Something like:

( GRAPH <http://linkedin/foafexport/mygraph> { #me foaf:knows ?x } )
=>
( #me rel:collaboratesWith ?x )

that will be in my profile itself.

Finally, since I can create a link to this FOAF profile from my OpenID, I can reuse this graph in many applications. And when login to a new service, ask him “is there anyone here that I know from flickr ?”.

More than social network, I can also link from the same profile (or, actually, from the profiles that have been linked to the reference one) to various things I wrote or done on the Web, as data from last-fm, revyu or flickr, thanks to SIOC, as explained here.

So: One reference profile. Lots of distributed information. One Giant Global Graph.

NB: Also check some of Dan Brickley’s experiments about related topics.

NB2: I did not take trust issues in consideration in that post, i.e. how can we be sure that the owl:sameAs relationship is linked to an URI which is really *me*. I think one solution would be to authenticate on those websites using OpenID so that it can find my FOAF file, then my URI, and add an owl:sameAs link in the other direction. Both files should also be signed, and I think that will be ok (?).

DOAP and the Linked Data Web

From the LOD mailing-list, I discovered and browsed doapspace.org, that aims to build a DOAP repository. Contrary to doap:store that fetches RDF files from the Web thanks to PTSW, one of the nice feature of doapspace is that it creates DOAP files from services that do not offer such meta-data for their projects, such as SourceForge or FreshMeat.

Rob already scrapped about 45000 DOAP files ! And should be able in a few days to ping PTSW to inform it about new files, that can the be crawled into doap:store, browsed… and SPARQLed - let’s hope my box can support such amount of data and queries…

As discussed on the mailing-list, this service could be a great way to make DOAP enter one step further into the Linked Data Web. What’s currently missing is URIs, for projects and people. I noticed when creating doap:store that many projects don’t have an URI (and are just blank nodes), which makes impossible to link to them from external files, as FOAF profiles.

Now, imagine that doapspace scrapper creates URI for all people and projects, based on the service name and user / project id on the original service. Using owl:sameAs and rdfs:seeAlso, anyone could add something like this in its FOAF profile:

<foaf:Person rdf:about="#me">
  <owl:sameAs
    rdf:resource="http://doapspace.org/user/sf/terraces"
    rdf:seeAlso="http://doapspace.org/user/sf/terraces/rdfview"/>
  <owl:sameAs
    rdf:resource="http://doapspace.org/user/fm/terraces"
    rdf:seeAlso="http://doapspace.org/user/fm/terraces/rdfview"/>
</foaf:Person>

Then, by reading my FOAF profile with Tabulator or any Linked Data Browser I can easilly browse my profiles on doapspace, that would ideally list all projects (with their URIs) I’m into and that I can browse again, thanks again to seeAlso links.

Another advantage is that I don’t have to mention the projects I maintain in my FOAF file, but let doapspace do the job for me, since using owl:sameAs will tell that these different URIs identify the same person (= me). Then using a single SPARQL query on these files with an engine that supports owl:sameAs, I can easilly find all projects I’m into, whereas it comes from:

select ?project
where {
  ?project doap:maintainer <my_foaf_URI>
}

The final step would be to query only my FOAF profile, and let the engine discover / identify doapspace URIs and retrieve profiles to add them in its files to query, as the Semantic Web Client library does, but I don’t know if it currently supports owl:sameAs or not.

Using Protégé through an authenticated proxy

I recently struggled with Protégé in order to make it work through an authenticated enterprise proxy, since I wanted to import / extend ontologies from the Web.

When running a Java application, you can pass it the URL of a proxy, but it seems the only way to setup authentication parameters is to modify original source code. I agree a plugin is certainly better, but I don’t have time to invest it, so here’s a simple hack to make Protégé-OWL work with such a proxy.

 mkdir protege-owl
cd protege-owl
svn checkout http://smi-protege.stanford.edu/repos/protege/owl/trunk  . 

You’ll also need to get the protege.jar file, that can be downloaded here, and move it to the /libs folder.

Add the following import:

 import java.util.Properties; 

In getInputStream method, replace

 conn.addRequestProperty("Accept", "*/*");
return conn.getInputStream(); 

By

 conn.addRequestProperty("Accept", "*/*");
// Set proxy settings only if the file is outside our domain
if(url.getHost().indexOf("company.host.tld")==-1) {
  Properties systemSettings = System.getProperties();
  systemSettings.put("http.proxyHost","proxy_URL");
  systemSettings.put("http.proxyPort", "proxy_Port");
  sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
  String encodedUserPwd = encoder.encode("proxy_User:proxy_Pass".getBytes());
  conn.setRequestProperty("Proxy-Authorization", "Basic " + encodedUserPwd);
}
return conn.getInputStream(); 

Add the following imports:

 import java.util.Properties;
import java.io.InputStream;
import java.net.URLConnection; 

In isPossibleToImport() method, replace:

 OntologyNameExtractor extractor = new OntologyNameExtractor(url.openConnection().getInputStream(), url);
URI uri = extractor.getOntologyName(); 

By:

 OntologyNameExtractor extractor;
// Set proxy settings only if the file is outside our domain
if(url.getHost().indexOf("edf.fr")==-1) {
  URLConnection conn = url.openConnection();
  conn.setRequestProperty("Accept", "application/rdf+xml");
  conn.addRequestProperty("Accept", "text/xml");
  conn.addRequestProperty("Accept", "*/*");
  Properties systemSettings = System.getProperties();
  systemSettings.put("http.proxyHost","proxy_URL");
  systemSettings.put("http.proxyPort", "proxy_Port");
  sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
  String encodedUserPwd = encoder.encode("proxy_User:proxy_Pass".getBytes());
  conn.setRequestProperty("Proxy-Authorization", "Basic " + encodedUserPwd);
  InputStream stream = conn.getInputStream();
  extractor = new OntologyNameExtractor(stream, url);
} else {
  extractor = new OntologyNameExtractor(url.openConnection().getInputStream(), url);
}
URI uri = extractor.getOntologyName(); 

Notes ISWC2005: Swoogle

Présentation ce matin de Swoogle, moteur de recherche d’ontologies et de métadonnées qui compte pour le moment 700K documents indexés.

Swoogle permet une recherche par mots clés sur les ontologies ou les concepts, offrant des détails pour chaque ontologie trouvée, par ex:

http://www.isi.edu/~pan/damltime/time-entry.owl Suffix: owl  Encoding: RX  Last modified: 2004-10-19 15:36:56 Classes defined: 17  Properties defined: 48  Instances defined: 7 Triples: 308  Namespaces used: 6  Ontology Ratio: 0.677083

Possibilité également de voir plus de détails sur l’ontologie (namespaces utilisées …), de rechercher les ontologies contenant tel ou tel concept puis de détailler leur utilisation. l’objectif étant d’avoir un outil pour découvrir des ontologies mais également pour évaluer l’utilisation d’une ontologie donnée.

Swoogle offre également un shopping cart pour pouvoir ensuite faire des requêtes sur l’ensemble du panier.

Le classement des résultats se base sur un algorithme proche du PageRank, à la différence que chaque lien a ici un poids défini en fonction du type puisque contrairement à des pages Web classiques, les relations entre documents peuvent avoir différentes sémantiques et non plus être de simples liens hypertextes.

Les slides de la présentation sont disponibles ici.

Introduction au Web Sémantique

Un article d’introduction au Web Sémantique, The future of the Web is Semantic, présentant les notions d’URI et les différents langages de représentation de resources sur le Web (RDF, RDFS et OWL).

IBM developerWorks propose par ailleurs de nombreux fils RSS de ces articles.