Commits

Toby Inkster  committed 07ef189

Beginnings of XML::Atom::Microformats.

  • Participants

Comments (0)

Files changed (8)

+#############################################################
+
+@prefix :        <http://usefulinc.com/ns/doap#> .
+@prefix dcs:     <http://ontologi.es/doap-changeset#> .
+@prefix dc:      <http://purl.org/dc/terms/> .
+@prefix foaf:    <http://xmlns.com/foaf/0.1/> .
+@prefix my:      <http://purl.org/NET/cpan-uri/dist/XML-Atom-Microformats/> .
+@prefix rdfs:    <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix toby:    <http://tobyinkster.co.uk/#> .
+@prefix xsd:     <http://www.w3.org/2001/XMLSchema#> .
+
+#############################################################
+
+<>
+
+	dc:title         "Changes" ;
+	dc:description   "Revision history for Perl extension Example::Example."@en ;
+	dc:subject       my:project ;
+	dc:creator       toby:i .
+
+#############################################################
+
+my:v_0-01
+
+	a               :Version ;
+	dc:issued       "2000-01-01"^^xsd:date ;
+	:revision       "0.01"^^xsd:string ;
+	:file-release   <http://backpan.cpan.org/authors/id/T/TO/TOBYINK/Example-Example-0.01.tar.gz> ;
+	rdfs:comment    "Original version"@en .
+
+#############################################################
+
+my:project
+
+	a               :Project ;
+	:name           "Example-Example" ;
+	:shortdesc      "Example Project"@en ;
+	:programming-language  "Perl" ;
+	:homepage       <http://search.cpan.org/dist/Example-Example/> ;
+	:download-page  <http://search.cpan.org/dist/Example-Example/> ;
+	:bug-database   <http://rt.cpan.org/Dist/Display.html?Queue=Example-Example> ;
+	:repository     [ a :SVNRepository ; :browse <http://goddamn.co.uk/viewvc/perlmods/Example-Example/> ] ;
+	:maintainer     toby:i ;
+	:developer      toby:i ;
+	:documenter     toby:i ;
+	:tester         toby:i ;
+	:created        "2000-01-01"^^xsd:date ;
+	:license        <http://dev.perl.org/licenses/> ;
+	:release        my:v_0-01 .
+
+#############################################################
+
+toby:i
+
+	a               foaf:Person ;
+	foaf:name       "Toby Inkster" ;
+	foaf:homepage   <http://tobyinkster.co.uk/> ;
+	foaf:page       <http://search.cpan.org/~tobyink/> ;
+	foaf:mbox       <mailto:tobyink@cpan.org> .
+
+#############################################################
+Changes
+Changes.ttl
+Changes.xml
+Makefile.PL
+MANIFEST
+MANIFEST.SKIP
+README
+META.yml
+SIGNATURE
+
+lib/XML/Atom/Microformats.pm
+lib/XML/Atom/Microformats/_context.pm
+
+t/00sig.t
+t/01basic.t

File MANIFEST.SKIP

+^Makefile$
+^blib/
+^pm_to_blib
+^blibdirs
+\.svn
+^example.*\.pl$
+^[^/]+\.(tar\.gz|tar\.bz2|tgz|tbz2|tbz|zip|tar)$
+^MYMETA..yml
+use strict;
+use warnings;
+
+use inc::Module::Install;
+
+my $dist = 'XML-Atom-Microformats';
+my $fn   = "lib/$dist.pm"; $fn =~ s#-#/#g;
+
+name                $dist;
+perl_version_from   $fn;
+version_from        $fn;
+abstract_from       $fn;
+readme_from         $fn;
+author              'Toby Inkster <tobyink@cpan.org>';
+license             'perl';
+
+test_requires       'Test::More' => '0.61';
+
+requires            'Carp'               => '1.00';
+requires            'HTML::Microformats' => 0;
+requires            'HTML::HTML5::Parser'=> 0;
+requires            'RDF::Trine'         => '0.112';
+requires            'URI'                => '1.30';
+requires            'XML::Atom::OWL'     => 0;
+requires            'XML::LibXML'        => '1.60';
+
+recommends          'RDF::RDFa::Parser'  => '1.00';
+
+resources(
+	'homepage'   => "http://search.cpan.org/dist/$dist/",
+	'repository' => "http://goddamn.co.uk/viewvc/perlmods/$dist/",
+	'bugtracker' => "http://rt.cpan.org/Dist/Display.html?Queue=$dist",
+	);
+	
+write_doap_changes;
+write_doap_changes_xml;
+
+include 'Test::Signature';
+auto_install;
+WriteAll(
+	'meta' => 1,
+	'sign' => 1,
+	);
+use lib "lib";
+use lib "../XML-Atom-OWL/lib";
+use lib "../HTML-Microformats/lib";
+use Data::Dumper;
+use JSON;
+use XML::Atom::Microformats;
+
+my $xml = <<XML;
+<feed xmlns="http://www.w3.org/2005/Atom">
+	<entry>
+		<id>http://example.com/id/1</id>
+		<content type="text/html">
+			&lt;p class="vcard">&lt;span class="fn">Alice&lt;/span>&lt;/p>
+		</content>
+		<link rel="self" href="http://example.com/article/1" />
+		<link rel="profile" href="http://ufs.cc/x/hcard" />
+	</entry>
+	<entry>
+		<id>http://example.com/id/2</id>
+		<content type="text/html">
+			&lt;p class="vcard">&lt;span class="fn">Bob&lt;/span>&lt;/p>
+		</content>
+		<link rel="self" href="http://example.com/article/2" />
+	</entry>
+</feed>
+XML
+
+my $xamf = XML::Atom::Microformats->new($xml, "http://example.net/");
+
+print $xamf->json(pretty=>1,canonical=>1);

File lib/XML/Atom/Microformats.pm

+package XML::Atom::Microformats;
+
+use HTML::Microformats;
+use JSON;
+use RDF::Query;
+use XML::Atom::OWL;
+
+sub new
+{
+	my ($class, $xml, $base_uri) = @_;
+	my $awol = XML::Atom::OWL->new($xml, $base_uri, undef, RDF::Trine::Store::Memory->temporary_store)->consume;
+	my $self = bless { 'AWOL' => $awol }, $class;
+	
+	return $self->_find_contexts->_prepare_contexts;	
+}
+
+sub _find_contexts
+{
+	my ($self) = @_;
+	
+	my $sparql = <<SPARQL;
+PREFIX awol: <http://bblfish.net/work/atom-owl/2006-06-06/#>
+PREFIX iana: <http://www.iana.org/assignments/relation/>
+SELECT ?entry ?entryid ?entrylink ?contenttype ?contentbody ?profile
+WHERE
+{
+	?entry a awol:Entry ;
+		awol:content ?content ;
+		awol:id ?entryid .
+	?content a awol:Content ;
+		awol:type ?contenttype ;
+		awol:body ?contentbody .
+	OPTIONAL { ?entry iana:self ?entrylink . }
+	OPTIONAL
+	{
+		{ ?feed awol:entry ?entry ; iana:profile ?profile . }
+		UNION { ?entry iana:profile ?profile . }
+	}
+}
+SPARQL
+
+	my $query  = RDF::Query->new($sparql);
+	my $result = $query->execute($self->{'AWOL'}->graph);
+	my $data = {};
+	while (my $row = $result->next)
+	{
+		my $e = $row->{'entry'}->as_ntriples;
+		
+		$data->{$e}->{'entryid'}     ||= $row->{'entryid'}->literal_value;
+		$data->{$e}->{'contentbody'} ||= $row->{'contentbody'}->literal_value;
+		$data->{$e}->{'contenttype'} ||= $row->{'contenttype'}->literal_value;
+		$data->{$e}->{'entrylink'}   ||= (defined $row->{'entrylink'} ? $row->{'entrylink'}->uri : undef);
+		
+		if (defined $row->{'profile'})
+		{
+			push @{ $data->{$e}->{'profiles'} }, $row->{'profile'}->uri;
+		}
+	}
+	$self->{'contexts'} = [values %$data];
+	
+	return $self;
+}
+
+sub _prepare_contexts
+{
+	my ($self) = @_;
+	
+	foreach my $context (@{$self->{'contexts'}})
+	{
+		next unless $context->{'contenttype'} eq 'text/html'
+			|| $context->{'contenttype'} eq 'application/xhtml+xml';
+		
+		my $dom;
+		my $html = sprintf("<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title></title></head><body><div>%s</div></body></html>",
+			$context->{'contentbody'});
+		
+		my $hmf = HTML::Microformats->new_document(
+			$html,
+			($context->{'entrylink'} || $context->{'entryid'}),
+			type => $context->{'contenttype'});
+		
+		if ($@ || !defined $hmf)
+		{
+			warn sprintf("ENTRY <%s>: %s",
+				$context->{'entryid'},
+				($@ || "Could not process entry."));
+			next;
+		}
+		
+		$hmf->add_profile( @{$context->{'profiles'}} );
+		
+		$context->{'HMF'} = $hmf;
+	}
+	
+	return $self;
+}
+
+sub parse_microformats
+{
+	my $self = shift;
+	return $self if $self->{'parsed'};
+	
+	foreach my $context (@{$self->{'contexts'}})
+	{
+		next unless $context->{'HMF'};
+		$context->{'objects'} = $context->{'HMF'}->objects;
+	}
+	
+	$self->{'parsed'} = 1;
+	return $self;
+}
+
+sub clear_microformats
+{
+	my $self = shift;
+	
+	foreach my $context (@{$self->{'contexts'}})
+	{
+		$context->{'objects'} = undef;
+		next unless $context->{'HMF'};
+		$context->{'HMF'}->clear_microformats;
+	}
+	
+	$self->{'parsed'} = 0;
+	return $self;
+}
+
+sub objects
+{
+	my ($self, $format, $entry) = @_;
+	$self->parse_microformats;
+	
+	my @rv;
+	
+	foreach my $context (@{$self->{'contexts'}})
+	{
+		next unless $context->{'HMF'};
+		
+		if ($entry eq $context->{'entryid'} || !defined $entry)
+		{
+			my @these = $context->{'HMF'}->objects($format);
+			push @rv, @these;
+		}
+	}
+	
+	return @rv if (wantarray);
+	return \@rv;
+}
+
+sub all_objects
+{
+	my ($self, $entry) = @_;
+	my $rv = {};
+	
+	foreach my $format (@HTML::Microformats::Formats)
+	{
+		$rv->{$format} = $self->objects($format, $entry);
+	}
+	
+	return $rv;
+}
+
+sub TO_JSON
+{
+	return $_[0]->all_objects;
+}
+
+sub json
+{
+	my ($self, %opts) = @_;
+	
+	$opts{'convert_blessed'} = 1
+		unless defined $opts{'convert_blessed'};
+	
+	$opts{'utf8'} = 1
+		unless defined $opts{'utf8'};
+
+	return to_json($self->all_objects, \%opts);
+}
+
+1;
+use lib 'inc';
+use Test::More tests => 1;
+use Test::Signature;
+signature_ok();
+use Test::More tests => 1;
+BEGIN { use_ok('Example::Example') };
+