Commits

Toby Inkster committed b10d82f

Release updates to WWW-Finger and XRD-Parser.

  • Participants
  • Parent commits ebd3a3a

Comments (0)

Files changed (14)

+############################################################################
+## Changes #################################################################
+############################################################################
+
+WWW-Finger
+==========
+
+Created:      2009-12-08
+Home page:    <http://search.cpan.org/dist/WWW-Finger/>
+Bug tracker:  <http://rt.cpan.org/Dist/Display.html?Queue=WWW-Finger>
+Maintainer:   Toby Inkster <mailto:tobyink@cpan.org>
+
+0.09 [2010-04-26]
+ - (Update) Switch Changes file from Aaron Cope's changefile vocab to my
+   own DOAP Change Sets vocab.
+ - Various cleanups.
+
+0.08 [2010-01-06]
+ - (Bugfix) Documentation improvements.
+
+0.07 [2009-01-06]
+ - (Bugfix) Include BitworkingFingerProtocol.pm in MANIFEST.
+ - (Update) Update copyright noticed to 2010.
+
+0.06 [2009-01-06]
+ - (Update) Improve fingerw's debugging (verbose) messages.
+ - (Addition) Follow rdf:seeAlso and ianalink:describedby links found in
+   Webfinger account profiles.
+ - Refactor some code from WWW::Finger::Webfinger to allow it to be used
+   elsewhere.
+ - (Addition) Support semantics of foaf:account and foaf:holdsAccount.
+ - (Update) Use Turtle for Changes file.
+ - (Addition) Support Joe Gregorio's alternative to current Webfinger
+   protocol.
+ - (Bugfix) Fix duplicated mbox in WWW::Finger::CPAN.
+ - (Addition) Allow fingerw command-line client to load additional modules.
+
+0.05 [2009-12-16]
+ - (Bugfix) Mini bug-fixes.
+ - (Update) use XRD::Parser 0.04.
+
+0.04 [2009-12-16]
+ - (Addition) Bundle a command-line query tool.
+ - (Bugfix) Fingerpoint bugfix in ->graph().
+ - Change default scheme for Webfinger from 'acct://' to 'acct:'.
+ - (Bugfix) Unimplemented methods return empty arrays properly.
+
+0.03 [2009-12-15]
+ - (Bugfix) Fixed package signature.
+ - (Addition) WWW::Finger::Webfinger now provides an ->endpoint method.
+
+0.02 [2009-12-14]
+ - (Bugfix) Fixed problems with build.
+
+0.01 [2009-12-14]
+
 	[
 		a dcs:ChangeSet ;
 		dcs:versus :v_0-08 ;
-		dcs:item [ a dcs:Update ; dcs:checkin "r104"^^xsd:string ; rdfs:label "Switch Changes file from Aaron Cope's changefile vocab to my own DOAP Change Sets vocab."@en ]
+		dcs:item [ a dcs:Update ; dcs:checkin "r104"^^xsd:string ; rdfs:label "Switch Changes file from Aaron Cope's changefile vocab to my own DOAP Change Sets vocab."@en ] ;
+		dcs:item [ rdfs:label "Various cleanups."@en ]
 	] .
 
 
             <rdfs:label xml:lang="en">Switch Changes file from Aaron Cope's changefile vocab to my own DOAP Change Sets vocab.</rdfs:label>
           </dcs:Update>
         </dcs:item>
+        <dcs:item>
+          <rdf:Description>
+            <rdfs:label xml:lang="en">Various cleanups.</rdfs:label>
+          </rdf:Description>
+        </dcs:item>
         <dcs:versus rdf:resource="http://usefulinc.com/ns/doap#v_0-08"/>
       </dcs:ChangeSet>
     </dcs:changeset>
 Changes
+Changes.ttl
 Changes.xml
 Makefile.PL
 MANIFEST
 lib/WWW/Finger/Webfinger.pm
 lib/WWW/Finger/CPAN.pm
 lib/WWW/Finger/BitworkingFingerProtocol.pm
+lib/WWW/Finger/_GenericRDF.pm
 
 t/00sig.t
-t/WWW-Finger.t
+t/01basic.t
 
 script/fingerw
 
 inc/Module/Install/AutoInstall.pm
 inc/Module/Install/Base.pm
 inc/Module/Install/Can.pm
+inc/Module/Install/DOAPChangeSets.pm
 inc/Module/Install/Fetch.pm
 inc/Module/Install/Include.pm
 inc/Module/Install/Makefile.pm
 inc/Module/Install/Win32.pm
 inc/Module/Install/WriteAll.pm
 inc/Test/Signature.pm
-
-

File MANIFEST.SKIP

 ^blibdirs
 \.svn
 ^example.*\.pl$
+^MYMETA.yml

File WWW-Finger-0.09.tar.gz

Binary file added.

File lib/WWW/Finger.pm

 	@Modules = ();
 	eval "use WWW::Finger::Fingerpoint;";
 	carp "Could not load Fingerpoint implementation ($@)" if $@;
-	!eval "use WWW::Finger::Webfinger;";
+	eval "use WWW::Finger::Webfinger;";
 	carp "Could not load Webfinger implementation ($@)" if $@;
 }
 
 {
 	my $class      = shift;
 	my $identifier = shift;
-	
+
 	foreach my $module (@Modules)
 	{
 		my $rv = $module->new($identifier);
 
 1;
 
-# Below is not a proper WWW::Finger implementation, but is rather a
-# framework which real implementations can hook onto by subclassing.
-
-package WWW::Finger::_GenericRDF;
-
-use LWP::UserAgent;
-use RDF::Trine 0.112;
-use RDF::Query;
-use Digest::SHA1 qw(sha1_hex);
-
-our @ISA = qw(WWW::Finger);
-our $VERSION = '0.09';
-
-sub _new_from_response
-{
-	my $class    = shift;
-	my $ident    = shift;
-	my $response = shift;
-	my $self     = bless {}, $class;
-	
-	my $model  = RDF::Trine::Model->new( RDF::Trine::Store->temporary_store );
-	
-	$self->{'ident'} = $ident;
-	$self->{'graph'} = $model;
-	
-	$self->_response_into_model($response);
-	
-	return $self;
-}
-
-sub _response_into_model
-{
-	my $self     = shift;
-	my $response = shift;
-	my $parser;
-	$parser = RDF::Trine::Parser::Turtle->new  if $response->content_type =~ m`(n3|turtle|text/plain)`;
-	$parser = RDF::Trine::Parser::RDFJSON->new if $response->content_type =~ m`(json)`;
-	$parser = RDF::Trine::Parser::RDFXML->new  unless defined $parser;
-	$parser->parse_into_model($response->base, $response->decoded_content, $self->graph);
-}
-
-sub _uri_into_model
-{
-	my $self  = shift;
-	my $uri   = shift;
-	
-	# avoid repetition
-	return if $self->{'_uri_into_model::done'}->{"$uri"};
-	
-	my $ua = LWP::UserAgent->new;
-	$ua->timeout(10);
-	$ua->env_proxy;
-	$ua->default_header('Accept' => 'application/rdf+xml, text/turtle, application/x-rdf+json');
-	
-	my $response = $ua->get($uri);
-	
-	if ($response->is_success)
-	{
-		$self->_response_into_model($response);
-		$self->{'_uri_into_model::done'}->{"$uri"}++;
-	}
-}
-
-sub _simple_sparql
-{
-	my $self = shift;
-	my $where = '';
-	foreach my $p (@_)
-	{
-		$where .= " UNION " if length $where;
-		$where .= sprintf('{ [] foaf:mbox <%s> ; <%s> ?x . } UNION { [] foaf:mbox_sha1sum <%s> ; <%s> ?x . }',
-			(''.$self->{'ident'}),
-			$p,
-			sha1_hex(''.$self->{'ident'}),
-			$p
-			);
-	}
-	
-	my $sparql = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT DISTINCT ?x WHERE { $where }";
-	my $query  = RDF::Query->new($sparql);
-	my $iter   = $query->execute( $self->{'graph'} );
-	my @results;
-	
-	while (my $row = $iter->next)
-	{
-		push @results, $row->{'x'}->literal_value
-			if $row->{'x'}->is_literal;
-		push @results, $row->{'x'}->uri
-			if $row->{'x'}->is_resource;
-	}
-	
-	if (wantarray)
-	{
-		return @results;
-	}
-	
-	if (@results)
-	{
-		return $results[0];
-	}
-	
-	return undef;
-}
-
-sub follow_seeAlso
-{
-	my $self    = shift;
-	my $recurse = shift;
-	
-	my $sparql = "
-	PREFIX dc: <http://purl.org/dc/terms/>
-	PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
-	PREFIX rel: <http://www.iana.org/assignments/relation/>
-	SELECT DISTINCT ?seealso
-	WHERE
-	{
-		{
-			?anything rdfs:seeAlso ?seealso .
-		}
-		UNION
-		{
-			?anything rel:describedby ?seealso .
-			?seealso dc:format <http://www.iana.org/assignments/media-types/application/rdf+xml> .
-		}
-	}
-	";
-
-	my $query  = RDF::Query->new($sparql);
-	my $iter   = $query->execute( $self->graph );
-
-	while (my $row = $iter->next)
-	{
-		$self->_uri_into_model($row->{'seealso'}->uri)
-			if $row->{'seealso'}->is_resource;
-	}
-	
-	$self->follow_seeAlso($recurse - 1)
-		if $recurse >= 1;
-}
-
-sub webid
-{
-	my $self = shift;
-	
-	my $where = sprintf('{ ?person foaf:mbox <%s> . } UNION { ?person foaf:mbox_sha1sum <%s> . } UNION { ?person foaf:account <%s> . } UNION { ?person foaf:holdsAccount <%s> . }',
-		(''.$self->{'ident'}),
-		sha1_hex(''.$self->{'ident'}),
-		(''.$self->{'ident'}),
-		(''.$self->{'ident'}),
-		);
-	
-	my $sparql = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT DISTINCT ?person WHERE { $where }";
-	my $query  = RDF::Query->new($sparql);
-	my $iter   = $query->execute( $self->graph );
-	
-	while (my $row = $iter->next)
-	{
-		return $row->{'person'}->uri
-			if $row->{'person'}->is_resource;
-	}
-	
-	return undef;
-}
-
-sub name
-{
-	my $self = shift;
-	return $self->_simple_sparql(
-		'http://xmlns.com/foaf/0.1/name');
-}
-
-sub nick
-{
-	my $self = shift;
-	return $self->_simple_sparql(
-		'http://xmlns.com/foaf/0.1/nick');
-}
-
-sub homepage
-{
-	my $self = shift;
-	return $self->_simple_sparql(
-		'http://xmlns.com/foaf/0.1/homepage',
-		'http://webfinger.net/rel/profile-page');
-}
-
-sub weblog
-{
-	my $self = shift;
-	return $self->_simple_sparql(
-		'http://xmlns.com/foaf/0.1/weblog');
-}
-
-sub mbox
-{
-	my $self = shift;
-	return $self->_simple_sparql(
-		'http://xmlns.com/foaf/0.1/mbox');
-}
-
-sub image
-{
-	my $self = shift;
-	return $self->_simple_sparql(
-		'http://webfinger.net/rel/avatar',
-		'http://xmlns.com/foaf/0.1/img',
-		'http://xmlns.com/foaf/0.1/depiction');
-}
-
-sub graph
-{
-	my $self = shift;
-	return $self->{'graph'};
-}
-
-sub endpoint
-{
-	my $self = shift;
-	my $ep   = $self->_simple_sparql('http://ontologi.es/sparql#endpoint');
-	return $ep;
-}
-
-
-1;
-
 __END__
 
 =head1 NAME

File lib/WWW/Finger/BitworkingFingerProtocol.pm

 package WWW::Finger::BitworkingFingerProtocol;
 
 use 5.008;
+use base qw(WWW::Finger);
 use strict;
 
 use Carp;
 use URI;
 use URI::Escape;
 
-our @ISA = qw(WWW::Finger);
 our $VERSION = '0.09';
 
 BEGIN

File lib/WWW/Finger/CPAN.pm

 package WWW::Finger::CPAN;
 
 use 5.008;
+use base qw(WWW::Finger);
 use strict;
 
 use Digest::MD5 qw(md5_hex);
 use LWP::Simple;
 use WWW::Finger;
 
-our @ISA = qw(WWW::Finger);
 our $VERSION = '0.09';
 
 BEGIN
 	my ($user, $host) = split /\@/, $self->{'ident'}->to;
 	return undef
 		unless lc $host eq 'cpan.org';
-	
+
 	return $self;
 }
 

File lib/WWW/Finger/Fingerpoint.pm

 package WWW::Finger::Fingerpoint;
 
 use 5.008;
+use base qw(WWW::Finger);
 use strict;
 
 use Carp;
 use WWW::Finger;
 use URI;
 
-our @ISA = qw(WWW::Finger);
 our $VERSION = '0.09';
 
 my $rel_fingerpoint = 'http://ontologi.es/sparql#fingerpoint';
 	}
 
 	return undef
-		unless length $sparql;
+		unless defined $sparql && length $sparql;
 	
 	$self->{'endpoint'} = $sparql;
 	

File lib/WWW/Finger/Webfinger.pm

 package WWW::Finger::Webfinger;
 
 use 5.008;
+use base qw(WWW::Finger::_GenericRDF);
 use strict;
 
 use Carp;
 use URI::Escape;
 use XRD::Parser 0.04;
 
-our @ISA = qw(WWW::Finger::_GenericRDF);
 our $VERSION = '0.09';
 
 BEGIN
 		unless $ident->scheme =~ /^(mailto|acct|xmpp)$/;
 
 	$self->{'ident'} = $ident;
-	my ($user, $host) = split /\@/, $ident->authority;
+	my ($user, $host) = split /\@/, $ident->authority
+		if defined $ident && defined $ident->authority;
 	if ("$ident" =~ /^(acct|mailto)\:([^\s\@]+)\@([a-z0-9\-\.]+)$/i)
 	{
 		$user = $2;
 		$host = $3;
 	}
-	
+
 	eval {
 		my $xrd_parser = XRD::Parser->hostmeta($host);
 		$xrd_parser->consume;
 		$self->{'hostmeta'} = $xrd_parser->graph;
 	};
+
 	return undef unless defined $self->{'hostmeta'};
 	
 	my @descriptors;

File lib/WWW/Finger/_GenericRDF.pm

+package WWW::Finger::_GenericRDF;
+
+# Below is not a proper WWW::Finger implementation, but is rather a
+# framework which real implementations can hook onto by subclassing.
+
+use LWP::UserAgent;
+use RDF::Trine 0.112;
+use RDF::Query;
+use Digest::SHA1 qw(sha1_hex);
+
+our @ISA = qw(WWW::Finger);
+our $VERSION = '0.09';
+
+sub _new_from_response
+{
+	my $class    = shift;
+	my $ident    = shift;
+	my $response = shift;
+	my $self     = bless {}, $class;
+	
+	my $model  = RDF::Trine::Model->new( RDF::Trine::Store->temporary_store );
+	
+	$self->{'ident'} = $ident;
+	$self->{'graph'} = $model;
+	
+	$self->_response_into_model($response);
+	
+	return $self;
+}
+
+sub _response_into_model
+{
+	my $self     = shift;
+	my $response = shift;
+	my $parser;
+	$parser = RDF::Trine::Parser::Turtle->new  if $response->content_type =~ m`(n3|turtle|text/plain)`;
+	$parser = RDF::Trine::Parser::RDFJSON->new if $response->content_type =~ m`(json)`;
+	$parser = RDF::Trine::Parser::RDFXML->new  unless defined $parser;
+	$parser->parse_into_model($response->base, $response->decoded_content, $self->graph);
+}
+
+sub _uri_into_model
+{
+	my $self  = shift;
+	my $uri   = shift;
+	
+	# avoid repetition
+	return if $self->{'_uri_into_model::done'}->{"$uri"};
+	
+	my $ua = LWP::UserAgent->new;
+	$ua->timeout(10);
+	$ua->env_proxy;
+	$ua->default_header('Accept' => 'application/rdf+xml, text/turtle, application/x-rdf+json');
+	
+	my $response = $ua->get($uri);
+	
+	if ($response->is_success)
+	{
+		$self->_response_into_model($response);
+		$self->{'_uri_into_model::done'}->{"$uri"}++;
+	}
+}
+
+sub _simple_sparql
+{
+	my $self = shift;
+	my $where = '';
+	foreach my $p (@_)
+	{
+		$where .= " UNION " if length $where;
+		$where .= sprintf('{ [] foaf:mbox <%s> ; <%s> ?x . } UNION { [] foaf:mbox_sha1sum <%s> ; <%s> ?x . }',
+			(''.$self->{'ident'}),
+			$p,
+			sha1_hex(''.$self->{'ident'}),
+			$p
+			);
+	}
+	
+	my $sparql = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT DISTINCT ?x WHERE { $where }";
+	my $query  = RDF::Query->new($sparql);
+	my $iter   = $query->execute( $self->{'graph'} );
+	my @results;
+	
+	while (my $row = $iter->next)
+	{
+		push @results, $row->{'x'}->literal_value
+			if $row->{'x'}->is_literal;
+		push @results, $row->{'x'}->uri
+			if $row->{'x'}->is_resource;
+	}
+	
+	if (wantarray)
+	{
+		return @results;
+	}
+	
+	if (@results)
+	{
+		return $results[0];
+	}
+	
+	return undef;
+}
+
+sub follow_seeAlso
+{
+	my $self    = shift;
+	my $recurse = shift;
+	
+	my $sparql = "
+	PREFIX dc: <http://purl.org/dc/terms/>
+	PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+	PREFIX rel: <http://www.iana.org/assignments/relation/>
+	SELECT DISTINCT ?seealso
+	WHERE
+	{
+		{
+			?anything rdfs:seeAlso ?seealso .
+		}
+		UNION
+		{
+			?anything rel:describedby ?seealso .
+			?seealso dc:format <http://www.iana.org/assignments/media-types/application/rdf+xml> .
+		}
+	}
+	";
+
+	my $query  = RDF::Query->new($sparql);
+	my $iter   = $query->execute( $self->graph );
+
+	while (my $row = $iter->next)
+	{
+		$self->_uri_into_model($row->{'seealso'}->uri)
+			if $row->{'seealso'}->is_resource;
+	}
+	
+	$self->follow_seeAlso($recurse - 1)
+		if $recurse >= 1;
+}
+
+sub webid
+{
+	my $self = shift;
+	
+	my $where = sprintf('{ ?person foaf:mbox <%s> . } UNION { ?person foaf:mbox_sha1sum <%s> . } UNION { ?person foaf:account <%s> . } UNION { ?person foaf:holdsAccount <%s> . }',
+		(''.$self->{'ident'}),
+		sha1_hex(''.$self->{'ident'}),
+		(''.$self->{'ident'}),
+		(''.$self->{'ident'}),
+		);
+	
+	my $sparql = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT DISTINCT ?person WHERE { $where }";
+	my $query  = RDF::Query->new($sparql);
+	my $iter   = $query->execute( $self->graph );
+	
+	while (my $row = $iter->next)
+	{
+		return $row->{'person'}->uri
+			if $row->{'person'}->is_resource;
+	}
+	
+	return undef;
+}
+
+sub name
+{
+	my $self = shift;
+	return $self->_simple_sparql(
+		'http://xmlns.com/foaf/0.1/name');
+}
+
+sub nick
+{
+	my $self = shift;
+	return $self->_simple_sparql(
+		'http://xmlns.com/foaf/0.1/nick');
+}
+
+sub homepage
+{
+	my $self = shift;
+	return $self->_simple_sparql(
+		'http://xmlns.com/foaf/0.1/homepage',
+		'http://webfinger.net/rel/profile-page');
+}
+
+sub weblog
+{
+	my $self = shift;
+	return $self->_simple_sparql(
+		'http://xmlns.com/foaf/0.1/weblog');
+}
+
+sub mbox
+{
+	my $self = shift;
+	return $self->_simple_sparql(
+		'http://xmlns.com/foaf/0.1/mbox');
+}
+
+sub image
+{
+	my $self = shift;
+	return $self->_simple_sparql(
+		'http://webfinger.net/rel/avatar',
+		'http://xmlns.com/foaf/0.1/img',
+		'http://xmlns.com/foaf/0.1/depiction');
+}
+
+sub graph
+{
+	my $self = shift;
+	return $self->{'graph'};
+}
+
+sub endpoint
+{
+	my $self = shift;
+	my $ep   = $self->_simple_sparql('http://ontologi.es/sparql#endpoint');
+	return $ep;
+}
+
+1;
+use Test::More tests => 3;
+BEGIN { use_ok('WWW::Finger') };
+
+WWW::Finger->import('+CPAN');
+
+my $finger = WWW::Finger->new('tobyink@cpan.org');
+ok(defined $finger, "CPAN finger worked");
+is($finger->name, "Toby Inkster", "CPAN finger returned correct name");

File t/WWW-Finger.t

-use Test::More tests => 3;
-BEGIN { use_ok('WWW::Finger') };
-
-WWW::Finger->import('+CPAN');
-
-my $finger = WWW::Finger->new('tobyink@cpan.org');
-ok(defined $finger, "CPAN finger worked");
-is($finger->name, "Toby Inkster", "CPAN finger returned correct name");