After playing with del.icio.us and zool's RDF port of their API I wondered what other services I could link to from my FOAF.
Having spent a happy hour or so in Waterstones at the weekend purchasing some extra goodies to top up my already bulging bookshelves it dawned on me: AllConsuming.net has a REST interface so it should be a snap to create an RDF version of Erik's API using some XSLT.
Here's some notes on my first attempt at transforming the current reading list.
Here's the URL to fetch my current reading list from AllConsuming:
http://allconsuming.net/rest.cgi?action=GetCurrentlyReadingList&username=ldodds
You'll notice that it has a username parameter which is my AllConsuming username. Substitute your username in the URL to fetch your own list.
We can then take a stylesheet allconsuming2foaf.xsl and use the W3C XSLT service to apply it to my data.
The URL is pretty unfriendly, but you can use the form on the XSLT service page to plug in your URL and the URL of my stylesheet.
There are a couple of things worth noting in the output. Firstly I'm using the Wordnet namespace to indicate that each item is a Book. The Dublin Core title, and identifier elements are used to record the book title and ISBN. I wanted to use off-the-shelf vocabularies where possible.
Secondly, AllConsuming allows you to record some brief comments about a book. To capture that data I've used Danny's Review Vocabulary to indicate that a given book has a review, as well as indicating who the reviewer is. The generated RDF includes some details about me: my homepage as well as the fact that I have an OnlineAccount with AllConsuming.
To make the personal description slightly richer, I adapted the stylesheet to take two parameters: seeAlso which should be the URL of your FOAF description, and mbox_sha1sum which should be your encrypted email address. You can see these demonstrated in this version of my data.
Lastly the AllConsuming REST interface include the URLs of both the AllConsuming and Amazon pages for each book. To capture this data I used the foaf:page property to state "here's a page about this book". I scouted about for a couple of book price comparison sites that could be linked to via ISBN and added links to those pages also.
To link to this data from your FOAF description, simply add the following rdfs:seeAlso property:
<rdfs:seeAlso>
<foaf:Document rdf:about="...transformed data url...">
<dc:title>Current Reading List</dc:title>
</foaf:Document>
</rdfs:seeAlso>
Simply substitute the URL to your transformed AllConsuming data in the appropriate place. To save load on the XSLT service and AllConsuming you may just want to download the file and store it locally, updating it whenever you update your reading list.
Next steps are to tweak the stylesheet to cope with some of the other actions in the AllConsuming REST interface: there are some minor inconsistencies in the response formats which I'm not cleanly dealing with yet.
In response to a thread on rdfweb-dev earlier this week I created a wiki page for capturing FOAF Application Ideas. The idea being to capture various application suggestions, no matter how detailed, in a central place so that the creativity doesn't get lost in the mailing list or buried in the #foaf chat logs.
It was also a prompt for myself to write up a few of the ideas that I've chatted about on IRC or had circulating around my head over the last few months.
One of these is something I've been calling "FOAF Secretary". It's an application that borrows some ideas from Edd's work (foafbot, FOAF Dashboard integration) but adds a few twists.
The important one being the incorporation of speech synthesis and recognition, something which seems relatively straight-forward to do using the Java Speech API.
The general goal is that rather than having an IRC based conversational interface, one would actually converse with the agent. The agent would also provide the facility to give a precis of someone or a group based on the available FOAF data: hence the "secretary" bit in the title (better naming ideas welcomed).
A little digging has uncovered the FreeTTS and Festival Speech Synthesis System for handling the speech generation, and there's been some work on generating dialogue responses from RDF/XML which ought to prove useful as a starting point.
After digging out the APIs earlier today I quickly hacked up a simple "hello world" test that will take a FOAF file (e.g. HelloWorld.rdf and generate speech from it, in the form: "X knows the following people..."). The code isn't worth posting but here's some output you can listen to: ldodds.wav.
The voice isn't great quality but there are means to import other voices into FreeTTS, and I've yet to try out Festival. But it's a start.
Funny how terms just seem to emerge out of no-where isn't it? I came across the the term Semantic Integration the other day, via this posting from Dare Obasanjo: Semantic Integration and XML. Since then I keep tripping over it.
Basically semantic integration seems to involve using RDF/OWL to define mappings between XML vocabularies.
Recently I've been involved in co-ordinating a number of large scale data migrations to help integrate several systems. This inevitably involved exploring the business models in the affected applications to define a mapping layer to allow the data to be cleanly migrated. Also inevitably this mapping ends up being expressed as a bunch of (hairy!) procedural code. It would have been nice to have been able to express that mapping in a more declarative way, if no other reason than it's easier to understand and debug possible problems. An example of not being able to see the wood for the trees.
I found that details such as syntactic variations in field formats (e.g. different date formats) were actually the most trivial aspect. And with appropriate data typing definitions in a semantic mapping layer, the need for these conversions could also be captured.
Approaching integration in this way involves stepping back from the surface syntax and looking at the business model it's capturing. It doesn't really matter whether the "syntax" is angle-brackets or a bunch of database DDL. XSLT isn't the right way to capture these relationships it's just a transform, a means to apply the mapping. And XSLT isn't necessarily the best approach anyway, transforms can get big and ugly really quickly.
Perhaps a better comparison would be semantic integration and architectural forms. The idea behind architectural forms is that one can define an architectural schema (i.e. the business entities) and mappings to this schema from other syntaxes. In the different flavours of RSS there are many elements that mean the same thing but have different names, etc. Using architectural forms you could define a "super-schema" that normalises this data into a suitable form for your application to build upon. The idea is that you don't write your application to use a specific syntax, you write it against the architectural form. I've got more notes on this in my wiki.
It's possible to implement architectural forms in many ways including simple SAX filters or XSLT. AF proponents will be quick to point out though that architectural forms is not a general purpose transformation tool, it's more than that.
I need to do more reading on semantic integration (pointers to examples would be interesting) to be able to compare it's approach with architectural forms more closely. However my gut feeling is that AFs are still "too close" to the syntax which limits what you can express. For more complex mappings you need more control than simply renaming elements and attributes, hiding sub-trees, etc. And in this area RDF/OWL provides a great deal more flexibility, and the technique is not limited to XML.
Lots of interesting FOAF activity lately, seemingly spurred on by the ETech presentations. Danny has already blogged pointers to the Guardian coverage and the videos of the presentations.
Elsewhere I see that flickr now supports FOAF through it's profile service. I've not looked at the site since I signed up and played a few days ago, probably time to dive back in again. There are some interesting services springing up.
The Trust and Reputation in Web-based Social Networks project deserves your support. Part of Jennifer Golbeck's dissertation the intention is to capture trust metrics from people's FOAF files to generate some views of the trust relationships. There are examples of how to hand-code the trust statements in your FOAF description. Or you could use the Trust-O-Matic.
While you're editing your FOAF description you might want to read through Christopher Allen's Hand-crafting my FOAF article which includes some good pointers on generating your FOAF description. It's worth dusting off your self-description to make sure you're using the latest terms, do it now to avoid being pestered!
I've been meaning to take a look at del.icio.us for a while now as my bookmarks have (once again) become unwieldy and have been increasingly frustrated about having stuff bookmarked "to read" at work but not at home.
Prompted by zool's del.icio.us in RDF posting I decided to sign-up and have a play. My first impressions are that it's really cool, and I've quickly decided to switch to using it as my main bookmark manager. You can see the few that I've added already.
I really like the fact that I can subscribe to particular topics and people using the RSS feeds provided. And any service that doesn't appropriate my data, allowing me to export it in various ways gets a big thumbs up from me.
Incidentally if you want to point to your del.icio.us RSS feed from your FOAF description, then you can do so like this, being sure to amend the details where appropriate:
<foaf:Person rdf:nodeID="me">
<foaf:name>Leigh Dodds</foaf:name>
<rdfs:seeAlso>
<rss:channel rdfs:about="http://del.icio.us/rss/ldodds">
<foaf:maker rdf:nodeID="me"/>
</rss:channel>
</rdfs:seeAlso>
</foaf:Person>
I'm currently debating building a local RDF store containing my bookmark related data, probably via zool's RDF version of the API to pick up any additional context it exposes. In fact I can feel another mini-project looming already...
If you've not used del.icio.us yet then take a look. It's tasty!
Been to any good gigs lately? Why not record this additional information in your FOAF description?
Continuing the Get Your FOAF On series I'll show you how to describe your attendance at an event, with some specific notes on conference attendance.
Describing events isn't a goal for FOAF, but it is a goal of the RDF Calendar group who are developing an RDF schema for capturing calendar information. The RDF Calendar Taskforce, is an article I wrote for XML.com some time ago now, but provides some useful background on that groups activities and goals. They're obviously much further along now and you can now found some detailed, and growing, documentation of their current calendaring vocabulary in the ESW Wiki: RDF Calendar Documentation.
One obvious way to tie together your FOAF description and your calendar, already expressed in RDF iCal, is to simply add an rdfs:seeAlso property to your description to point at your calendar:
<foaf:Person xmlns:ical="http://www.w3.org/2002/12/cal/ical#">
<foaf:name>Pope Gregory XIII</foaf:name>
<rdfs:seeAlso>
<ical:Vcalendar rdf:about="http://pope.gregory.name/calendar.rdf"/>
</rdfs:seeAlso>
</foaf:Person>
In the above snippet we are indicating the type of the resource involved in the the rdfs:seeAlso relationship to indicate to a Scutter that it can expect to find calendar data at the target URL.
But how does one go about creating an RDF iCal description? There are several different ways. Firstly many applications, including Mozilla and iCal will generate a calendar in the original iCalendar ("ics") format. From there you can easily convert it into the RDF version using Masahide Kanzaki's online RDF iCalendar convertor.
The convertor allows you to convert data by pasting it into the provided text box (if you've got in stashed on your hard drive) or by passing it a URL (if you've shared it online). If you're a .mac user you can simply grab the "Download" link from you're online calendar and pass it to the convertor in the box provided. Be sure to uncheck the "use XSLT for rendering" checkbox on the RDFiCal convertor so that you get the raw RDF rather than an HTML view of your calendar.
Another pain-free way to get yourself an RDF iCalendar is to use eventSherpa which will perform all the heavy-lifting for you, including automatic conversion to RDF. I've not used
these service personally, so would be interested in hearing other peoples opinions.
Let's assume for a moment though that, like me, you're not organized enough to actually maintain a calendar. What if you want to just list your attendance at an event, e.g. a gig, directly in your FOAF description?
You can do this by adding RDF iCal statements directly into your FOAF description. Here's an example that you can use as a template. Assume for the sake of the example that the ical namespace (http://www.w3.org/2002/12/cal/ical#) has already been declared:
<foaf:Person rdf:nodeID="me">
<foaf:name>Leigh Dodds</foaf:name>
</foaf:Person>
<ical:Vevent>
<ical:attendee rdf:nodeID="me"/>
<ical:summary>Big Chill Festival 2003</ical:summary>
<ical:dtstart rdf:parseType='Resource'>
<ical:date>2003-08-01</ical:date>
</ical:dtstart>
<ical:dtend rdf:parseType='Resource'>
<ical:date>2003-08-03</ical:date>
</ical:dtend>
</ical:Vevent>
Which says that I attended the Big Chill Festival between 1-3 August 2003. The event is described with a simple summary, as well at the start and end dates. The ical:attendee property is used to tie me (the attendee) to the event. Check the RDF Calendar Documentation for more details on other useful properties of events.
Rather than hand-code multiple events why not try out the RDFiCal-a-Matic another handy tool from Masahide Kanzaki. Just like the FOAF-a-Matic this is a simple Javascript application that lets you fill out some form fields to generate your RDF data.
There's an outstanding problem with describing events that's worth summarising before we move on: there's no unique identifier for the event, and hence no easy way to merge event descriptions together. In FOAF this is typically solved by defining an Inverse Functional Property that can be used to identify and merge resources. However there are no such properties currently defined for events. One possible workaround is to use foaf:homepage property, assuming the event your describing has a distinct homepage, which unfortunately isn't always the case. As an end user though this shouldn't dissuade you from marking up the data; I'll update this tutorial with additional information as it becomes available.
Libby Miller has some good discussion of this and related issues on her weblog.
In the next installment of this series I'll look at bit closer at some distinct types of events: Conferences, Births, Deaths and Marriages.
social software: automatic relationship clustering is a very interesting article over on d2r. It discusses using graph clustering techniques to identify groups within a social network. Diego suggests that adapting this to use FOAF ought to be straight-forward.
As I noted in my critique of XFN plain old foaf:knows is a fairly limited relationship. It's be more interesting to discover other kinds of relationships based on event attendance, collaboration, common interests, etc. This technique ought to be applicable to that kind of exploration as it deals only with nodes and edges; it's just a matter of presenting the right nodes and edges to the algorithm.
This is the second article in the "Get Your FOAF On" series which provides some short overview of how to use various FOAF features. In this edition we'll look at the FOAF vocabulary elements for describing project as well as stating your involvement.
Let's jump straight in with an example:
<foaf:Project>
<dc:title>My Pet Project</dc:title>
<dc:description>A project involving pets in some fashion. Probably cats</dc:description>
<foaf:homepage rdf:resource="http://www.example.com/projects/pet-project"/>
</foaf:Project>
This example mixes two vocabularies: FOAF and Dublin Core. The FOAF vocabulary furnishes us with a class for describing projects (foaf:Project) and the foaf:homepage property for identifying the homepage of some "thing". We can use this property to amalgamate descriptions of projects taken from multiple sources, whilst still allowing us to talk about the homepage document separately from the project itself. The Dublin Core vocabulary gives us the ever useful description and title properties.
Now this is your pet project, so how do you say that you're it's creator? One way would be to use the dc:creator property from Dublin Core. However there are some issues with using Dublin Core creator, so we'll instead use foaf:maker which is more clearly defined:
<foaf:Project>
<dc:title>My Pet Project</dc:title>
<dc:description>A project involving pets in some fashion. Probably cats</dc:description>
<foaf:homepage rdf:resource="http://www.example.com/projects/pet-project"/>
<foaf:maker>
<foaf:Person>
<foaf:name>Dr. Doolittle</foaf:name>
</foaf:Person>
</foaf:maker>
</foaf:Project>
Or alternatively:
<foaf:Person rdf:nodeID="me">
<foaf:name>Dr. Doolittle</foaf:name>
</foaf:Person>
<foaf:Project>
<dc:title>My Pet Project</dc:title>
<dc:description>A project involving pets in some fashion. Probably cats</dc:description>
<foaf:homepage rdf:resource="http://www.example.com/projects/pet-project"/>
<foaf:maker rdf:nodeID="me"/>
</foaf:Project>
So you're a bit further down the line with your project and you've picked up some help along the way. How do you indicate that other people have contributed to the project? Simple just add additional foaf:maker properties, not forgetting to reference the other persons FOAF file using rdfs:seeAlso:
<foaf:Project>
<dc:title>My Pet Project</dc:title>
<dc:description>A project involving pets in some fashion. Probably cats</dc:description>
<foaf:homepage rdf:resource="http://www.example.com/projects/pet-project"/>
<foaf:maker rdf:nodeID="dr"/>
<foaf:maker>
<foaf:Person>
<foaf:name>Eliza Doolittle</foaf:name>
<rdfs:seeAlso rdf:resource="..."/>
</foaf:Person>
</foaf:maker>
</foaf:Project>
Instead of using additional foaf:maker properties you could also use the dc:contributor property, although this suffers from the same problems as dc:creator. However it does allow one to distinguish between the orginal author of a project and the role of contributor.
All of the above examples have used foaf:maker. The inverse of foaf:maker is foaf:made. You can use this to point to things you've made; the above examples showing a thing pointing to it's maker.
FOAF also provides two other properties for linking you to your projects: foaf:currentProject and foaf:pastProject. The meanings of these should be pretty obvious. How they're used is a little counter-intuitive though as the properties are commonly used to refer to a document describing a project, e.g. it's homepage, rather than the project itself:
<foaf:Person>
<foaf:name>Dr Doolittle</foaf:name>
<foaf:currentProject rdf:resource="http://www.example.com/projects/pet-project"/>
<foaf:pastProject rdf:resource="http://www.example.com/projects/talking-to-animals"/>
</foaf:Person>
The FOAF specification notes the ambiguity here and suggests that some further work is required. However I think the above usage -- pointing to a project home page -- is relatively safe as there's a general trend in FOAF to describe things indirectly, using smushing to aggregate descriptions. Also note that there's no restriction on the number of time you can use these properties, so you can have as many current and past projects as you want. And if you're anything like me you're accumulating projects faster than you can shake them off!
To round off this mini-tutorial I want to point to some example data for people interested in building applications around project descriptions. Freshmeat provide a regular export of their project descriptions, and I recently announced a quick XSLT conversion that generates data from this export.
One thing that this highlights is that there are other interesting facets of software projects that could be usefully captured. Edd Dumbill has done a preliminary survey of what we might need from a DOAP (Description of a Project). Max Voekel has also published some notes on DOASP (Description of a Software Project).
This is the first in a series of short articles showcasing some of the capabilities of the FOAF and related vocabularies.
The intention is to provide enough detail to show the expressive power of the existing properties and how they can be usefully mixed with other vocabularies. However I want to keep these examples simple enough that people can use them as a template for hand-crafting their own FOAF files.
I'm assuming that you already have a basic FOAF document describing yourself and your friends. To meet this criteria you can just use the online FOAF-a-Matic which is available in ten languages.
I've also recently published an Introduction to FOAF tutorial on XML.com which you might also find interesting. It covers the basic FOAF properties and introducing concepts such as "smushing" and "Inverse Functional Properties" which I'll refer to occasionally in this series.
From that starting point I'm going to cover the usage of the following topics, starting with some areas which I personally don't think have had enough of an airing. This means that in some places we'll bump up against open issues and areas that need further clarification. I consider this a good thing.
Here's the current list of topics:
If you've got suggestions for other topics worth covering then let me know.
Along with my co-author, Brian Kelly, I've had a paper accepted for the IADIS 2004 - Web Based Communities conference. The paper discusses the role of FOAF and the Semantic Web in supporting community building, particularly at conferences. The HTML version of the paper is now online.
We're intending to generate as much data as possible that describes conferences, their speakers and particularly their attendees. Coupled with applications to visualise and explore the data, we're hoping that it will further showcase the role of FOAF in supporting community building and social networking.
Along with the paper, I've also announced the Conference Metadata Wiki. This is itself an experiment, this time exploring metadata generation from a Wiki as well as distributed authoring. As John Bosak has noted, there's no free metadata, but amortizing the costs across a community can make it very cheap indeed. So if you've chaired, spoken at, or attended a conference, why not stop by the Wiki and add some data?
I'm interested in feedback on both the paper and the Wiki. I've documented how the Wiki works and there is a lengthy example and some real data which should also provide useful references.
I'm also hoping that application authors will explore how they can add conference attendance data to their applications. For example it'd be interested to see this in Plink; pivoting the data on the conference could expose other people who have attended. I'm sure there are some interesting extensions to Dashboard that could work in a similar vein. I've already had some brief discussions with Jim Ley about getting foafnaut to support this data, and I'm going to be putting together some demonstrations in that vein as my next iteration of this project.
I should also acknowledge that there's been some other interesting work in using FOAF at conferences, including FOAF finger and, more recently, BlueFOAF. The latter allows you to spot your friends who may be in the neighbourhood based on their Bluetooth devices. It might be interesting to be able to record "I want to talk to this person" based on your knowledge that they'll be attending a conference. You could then be alerted to their presence when you're actually
there on the day; see also my previous comments on ice breaking
To sum up, I'm hoping this is going to be an interesting experiment and that people will help by adding data to the Wiki. Tell your friends...and friends-of-friends, of course!
p.s. should have known Danny would have blogged this before I got chance to write it up!