Index: Slash/Apache/User/User.pm diff -u Slash/Apache/User/User.pm:1.1 Slash/Apache/User/User.pm:1.2 --- Slash/Apache/User/User.pm:1.1 Wed Jan 28 06:53:51 2004 +++ Slash/Apache/User/User.pm Mon Feb 23 01:35:57 2004 @@ -526,6 +526,11 @@ $r->uri('/zoo.pl'); $r->filename($constants->{basedir} . '/zoo.pl'); } + } elsif ($op eq 'friends.rdf') { + $r->args("op=friends&nick=$nick&uid=$uid&content_type=foaf"); + $r->uri('/zoo.pl'); + $r->filename($constants->{basedir} . '/zoo.pl'); + } elsif ($op eq 'fans') { $r->args("op=fans&nick=$nick&uid=$uid"); $r->uri('/zoo.pl'); @@ -541,10 +546,20 @@ $r->uri('/zoo.pl'); $r->filename($constants->{basedir} . '/zoo.pl'); + } elsif ($op eq 'foes.rdf') { + $r->args("op=foes&nick=$nick&uid=$uid&content_type=foaf"); + $r->uri('/zoo.pl'); + $r->filename($constants->{basedir} . '/zoo.pl'); + } elsif ($op eq 'amigos') { $r->args("op=friendview&nick=$nick&uid=$uid"); $r->uri('/journal.pl'); $r->filename($constants->{basedir} . '/journal.pl'); + + } elsif ($op eq 'foaf.rdf') { + $r->args("op=foaf&nick=$nick&uid=$uid"); + $r->uri('/zoo.pl'); + $r->filename($constants->{basedir} . '/zoo.pl'); } else { $r->args("nick=$nick&uid=$uid"); Index: Slash/XML/FOAF/FOAF.pm diff -u /dev/null Slash/XML/FOAF/FOAF.pm:1.1 --- /dev/null Mon Feb 23 01:46:22 2004 +++ Slash/XML/FOAF/FOAF.pm Mon Feb 23 01:35:58 2004 @@ -0,0 +1,190 @@ +# This code is a part of Slash, and is released under the GPL. +# Copyright 1997-2003 by Open Source Development Network. See README +# and COPYING for more information, or see http://slashcode.com/. +# $Id$ + +package Slash::XML::FOAF; + +=head1 NAME + +Slash::XML::FOAF - Perl extension for Slash + + +=head1 SYNOPSIS + + use Slash::XML; + xmlDisplay('foaf', %data); + + +=head1 DESCRIPTION + +Module to output data about a user using the FOAF (Friend of a Friend) +RDF-schema. See http://www.foaf-project.org/ for details about FOAF. + + +=head1 EXPORTED FUNCTIONS + +=cut + +use strict; +use Slash; +use Slash::Utility; + +use base 'Slash::XML'; +use vars qw($VERSION); + +($VERSION) = ' $Revision$ ' =~ /\$Revision:\s+([^\s]+)/; + +my %foaf_elements = ( + maker => "", + Agent => "", + Document => "", + Person => "", + mbox_sha1sum => "", + nick => "", + weblog => "resource", + page => "resource", + homepage => "resource", + knows => "", + holdsAccount => "", + OnlineAccount => "", + accountName => "", + accountServiceHomepage => "resource", +); + +#======================================================================== + +=head2 create(PARAM) + +Creates FOAF. + +=over 4 + +=item Parameters + +=over 4 + +=item PARAM + +Hashref of parameters. Currently supported options are below. + +=over 4 + +=item Document + +Hash containing various info about the generated FOAF document. +Currently supported attributes are title (dc:title, human-readable +Title of the document), date (dc:date, when the document +was created/last-updated) and maker (foaf:maker, string describing the +creator). + +=item Person + +Hash containing various info about the foaf:Person desribed in +the generated FOAF document. Currently supported classes and +properties from FOAF are: mbox_sha1sum, foaf:nick, weblog, page, +homepage, knows, holdsAccount, OnlineAccount,accountName, +accountServiceHomepage and Person. Additionally, seeAlso +can be specified and will be treated as belonging to the +RDF Schema namespace. + + +=back + +=back + +=item Return value + +The complete FOAF data as a string. + +=item NOTE + +The validity in regards to the FOAF schema is NOT checked. +The caller should make sure to abide by the rules. + +=back + +=cut + + +sub create { + my($class, $param) = @_; + my $self = bless {}, $class; + my $ret; + + # create bare foaf document + $ret = "\n"; + $ret .= "\n"; + + # create info about current document + if (defined $param->{Document}){ + my $document = $param->{Document}; + $ret .= "\n"; + if (defined $document->{title}){ + $ret .= " $document->{title}\n"; + } + my $date = defined $document->{date} + ? $document->{date} + : $self->date2iso8601(); + my $maker = defined $document->{maker} + ? $document->{maker} + : "Slashcode FOAF.pm $VERSION"; + + $ret .= " $date\n"; + $ret .= " \n"; + $ret .= " $maker\n"; + $ret .= " \n"; + $ret .= "\n"; + } + + #info about the person to be described + if (defined $param->{Person}){ + $ret .= $self->_processFoaf( "Person", $param->{Person} ); + } + $ret .= "\n"; + + return $ret; +} + +1; + +sub _processFoaf{ + my ($self, $name, $node) = @_; + my $ret; + if (ref($node) eq "HASH" ){ + $ret .= "\n"; + foreach (keys %$node){ + $ret .= $self->_processFoaf( $_, $node->{$_} ); + } + $ret .= "\n"; + }elsif (ref($node) eq "ARRAY"){ + foreach (@$node){ + $ret .= $self->_processFoaf( $name, $_ ); + } + }else{ + if ($foaf_elements{$name} eq "resource"){ + $ret .= "\n"; + }elsif ($name eq "seeAlso"){ + $ret .= "\n"; + }else{ + $ret .= "$node\n"; + } + } + + return $ret; +} + +__END__ + + +=head1 SEE ALSO + +Slash(3), Slash::XML(3). + +=head1 VERSION + +$Id$ Index: Slash/XML/FOAF/MANIFEST diff -u /dev/null Slash/XML/FOAF/MANIFEST:1.1 --- /dev/null Mon Feb 23 01:46:22 2004 +++ Slash/XML/FOAF/MANIFEST Mon Feb 23 01:35:58 2004 @@ -0,0 +1,4 @@ +MANIFEST +Makefile.PL +FOAF.pm +test.pl Index: Slash/XML/FOAF/Makefile.PL diff -u /dev/null Slash/XML/FOAF/Makefile.PL:1.1 --- /dev/null Mon Feb 23 01:46:22 2004 +++ Slash/XML/FOAF/Makefile.PL Mon Feb 23 01:35:58 2004 @@ -0,0 +1,7 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + 'NAME' => 'Slash::XML::FOAF', + 'VERSION_FROM' => 'FOAF.pm', # finds $VERSION +); Index: Slash/XML/FOAF/test.pl diff -u /dev/null Slash/XML/FOAF/test.pl:1.1 --- /dev/null Mon Feb 23 01:46:22 2004 +++ Slash/XML/FOAF/test.pl Mon Feb 23 01:35:58 2004 @@ -0,0 +1,20 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### We start with some black magic to print on failure. + +# Change 1..1 below to 1..last_test_to_print . +# (It may become useful if the test is moved to ./t subdirectory.) + +BEGIN { $| = 1; print "1..1\n"; } +END {print "not ok 1\n" unless $loaded;} +use Slash::XML::FOAF; +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. + +# Insert your test code below (better if it prints "ok 13" +# (correspondingly "not ok 13") depending on the success of chunk 13 +# of the test code): + Index: plugins/Zoo/zoo.pl diff -u plugins/Zoo/zoo.pl:1.1 plugins/Zoo/zoo.pl:1.2 --- plugins/Zoo/zoo.pl:1.1 Wed Jan 28 06:55:12 2004 +++ plugins/Zoo/zoo.pl Mon Feb 23 01:35:58 2004 @@ -11,6 +11,7 @@ use Slash::Utility; use Slash::Zoo; use Slash::XML; +use Digest::SHA1; use vars qw($VERSION); ($VERSION) = ' $Revision$ ' =~ /\$Revision:\s+([^\s]+)/; @@ -87,6 +88,10 @@ check => 1, function => \&all }, + foaf => { + check => 1, + function => \&foaf + }, default => { check => 0, function => \&list @@ -128,7 +133,7 @@ if ($r = Apache->request) { return if $r->header_only; } - footer() unless $form->{content_type} eq 'rss'; + footer() unless $form->{content_type} eq 'rss' or $form->{content_type} eq 'foaf' or $op eq 'foaf'; } sub list { @@ -166,6 +171,8 @@ if ($form->{content_type} eq 'rss') { _rss($friends, $nick, 'friends'); + } elsif ($form->{content_type} eq 'foaf') { + _foaf( $friends, $uid, 'friends' ); } else { my $implied; if ($editable) { @@ -371,6 +378,8 @@ if ($form->{content_type} eq 'rss') { _rss($foes, $nick, 'foes'); + } elsif ($form->{content_type} eq 'foaf') { + _foaf($foes, $uid, "foes" ); } else { my $implied; if ($editable) { @@ -538,6 +547,26 @@ return 1; } +sub foaf { + my($zoo, $constants, $user, $form, $slashdb) = @_; + + my ($uid, $nick); + if ($form->{uid} || $form->{nick}) { + $uid = $form->{uid} ? $form->{uid} : $slashdb->getUserUID($form->{nick}); + $nick = $form->{nick} ? $form->{nick} : $slashdb->getUser($uid, 'nickname'); + } else { + $uid = $user->{uid}; + $nick = $user->{nick}; + } + + my $known = $zoo->getRelationships($uid, FRIEND); + my $foes = $zoo->getRelationships($uid, FOE); + push( @$known, @$foes ); + + _foaf($known, $uid, "foaf" ); + +} + sub all { my($zoo, $constants, $user, $form, $slashdb) = @_; @@ -787,6 +816,56 @@ }, image => 1, items => \@items + }); +} + +sub _foaf { + my( $entries, $uid, $type) = @_; + my $constants = getCurrentStatic(); + my $form = getCurrentForm(); + my $reader = getObject('Slash::DB', { db_type => 'reader' }); + my $user = $reader->getUser($uid, ['nickname', 'realemail','homepage', 'journal_last_entry_date']); + my $nickname = $user->{nickname}; + my $userpage = "$constants->{rootdir}/~" . fixparam($nickname) . "/"; + + + # basic foaf:Person + my $person = { + nick => $nickname, + holdsAccount => { + OnlineAccount => { + accountName => $nickname, + page => $userpage, + accountServiceHomepage => $constants->{rootdir}, + }, + } + }; + # add various field is defined + $person->{mbox_sha1sum} = Digest::SHA1::sha1_hex('mailto:' . $user->{realemail}) if $user->{realemail}; + $person->{homepage} = $user->{homepage} if $user->{homepage}; + $person->{weblog} = $userpage . "journal/" if $user->{journal_last_entry_date}; + + # add person's relationship + my @knows; + for my $entry (@$entries) { + my $p = $reader->getUser( $entry->[0] , ['nickname','realemail'] ); + push @knows, { Person => { + nick => $p->{nickname}, + mbox_sha1sum => Digest::SHA1::sha1_hex("mailto:" . $p->{realemail}), + seeAlso => "$constants->{rootdir}/~" . fixparam($p->{nickname}) . "/$type.rdf", + }}; + } + $person->{knows} = \@knows; + + # output RDF + $type = $type eq "foaf" ? "Friends and Foes" : $type; + xmlDisplay("foaf" ,{ + Document => { + title => "FOAF File for $nickname, with $type", + maker => "Slashcode zoo.pl $VERSION", + }, + Person => $person, + }); }