[open-ils-commits] r9950 - in trunk/Open-ILS: src/extras src/perlmods/OpenILS/WWW src/perlmods/OpenILS/WWW/SuperCat xsl

svn at svn.open-ils.org svn at svn.open-ils.org
Sun Jun 29 03:07:06 EDT 2008


Author: dbs
Date: 2008-06-29 03:07:00 -0400 (Sun, 29 Jun 2008)
New Revision: 9950

Modified:
   trunk/Open-ILS/src/extras/Makefile.install
   trunk/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat.pm
   trunk/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat/Feed.pm
   trunk/Open-ILS/xsl/MARC21slim2ATOM.xsl
   trunk/Open-ILS/xsl/MARC21slim2RSS2.xsl
Log:
Address a few RSS and Atom feed validation problems:
  * Make OPAC URLs absolute (needs refinement to respect locale/skin)
  * Push datetime creation down to the feed and item level
  * Atom:
    * Merge summary fields into a single element
  * RSS2:
    * Generate a channel/description field
    * Merge item/description fields into a single element
    * Use RFC-822 dates (adds DateTime::Format::Mail as a prerequisite)
    * Set guid isPermaLink attribute false as we're using tag: URIs
    * Place alternate link elements in the xhtml namespace
    * Generate a link element with no attributes



Modified: trunk/Open-ILS/src/extras/Makefile.install
===================================================================
--- trunk/Open-ILS/src/extras/Makefile.install	2008-06-27 14:28:53 UTC (rev 9949)
+++ trunk/Open-ILS/src/extras/Makefile.install	2008-06-29 07:07:00 UTC (rev 9950)
@@ -101,6 +101,7 @@
     libclass-dbi-abstractsearch-perl\
     libtemplate-perl\
     libtext-aspell-perl\
+    libdatetime-format-mail-perl\
     libdatetime-timezone-perl\
     libdatetime-perl\
     libunix-syslog-perl\

Modified: trunk/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat/Feed.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat/Feed.pm	2008-06-27 14:28:53 UTC (rev 9949)
+++ trunk/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat/Feed.pm	2008-06-29 07:07:00 UTC (rev 9950)
@@ -6,7 +6,10 @@
 use XML::LibXSLT;
 use OpenSRF::Utils::SettingsClient;
 use CGI;
+use DateTime;
+use DateTime::Format::Mail;
 
+
 sub exists {
 	my $class = shift;
 	my $type = shift;
@@ -225,6 +228,7 @@
 
 package OpenILS::WWW::SuperCat::Feed::atom;
 use base 'OpenILS::WWW::SuperCat::Feed';
+use OpenSRF::Utils qw/:datetime/;
 
 sub new {
 	my $class = shift;
@@ -244,7 +248,8 @@
 
 sub update_ts {
 	my $self = shift;
-	my $text = shift;
+	# ATOM demands RFC-3339 compliant datetime formats
+	my $text = shift || gmtime_ISO8601();
 	$self->_create_node($self->{item_xpath},'http://www.w3.org/2005/Atom','updated', $text);
 }
 
@@ -317,11 +322,15 @@
 	my $self = shift;
 	my $text = shift;
 	$self->_create_node('/rss/channel',undef,'title', $text);
+	# RSS2 demands a /channel/description element; just dupe title until we give
+	# users the ability to provide a description for their bookbags
+	$self->_create_node('/rss/channel',undef,'description', $text);
 }
 
 sub update_ts {
 	my $self = shift;
-	my $text = shift;
+	# RSS2 demands RFC-822 compliant datetime formats
+	my $text = shift || DateTime::Format::Mail->format_datetime(DateTime->now());
 	$self->_create_node($self->{item_xpath},undef,'lastBuildDate', $text);
 }
 
@@ -337,17 +346,27 @@
 	my $id = shift;
 	my $mime = shift || "application/x-$type+xml";
 
-	$type = 'self' if ($type eq 'rss2');
-
-	$self->_create_node(
-		$self->{item_xpath},
-		undef,
-		'link',
-		$id,
-		{ rel => $type,
-		  type => $mime,
-		}
-	);
+	if ($type eq 'rss2' or $type eq 'alternate') {
+		# Just link to ourself using standard RSS2 link element
+		$self->_create_node(
+			$self->{item_xpath},
+			undef,
+			'link',
+			$id,
+			undef
+		);
+	} else {
+		# Alternate link: use XHTML link element
+		$self->_create_node(
+			$self->{item_xpath},
+			'http://www.w3.org/1999/xhtml',
+			'xhtml:link',
+			$id,
+			{ rel => $type,
+			  type => $mime,
+			}
+		);
+	}
 }
 
 sub id {
@@ -372,11 +391,33 @@
 
 sub update_ts {
 	my $self = shift;
+	# RSS2 demands RFC-822 compliant datetime formats
 	my $text = shift;
+	if (!$text) {
+		# No date passed in, default to now
+		$text = DateTime::Format::Mail->format_datetime(DateTime->now());
+	} elsif ($text =~ m/^\s*(\d{4})\.?\s*$/o) {
+		# Publication date is just a year, convert accordingly
+		my $year = DateTime->new(year=>$1);
+		$text = DateTime::Format::Mail->format_datetime($year);
+	}
 	$self->_create_node($self->{item_xpath},undef,'pubDate', $text);
 }
 
+sub id {
+	my $self = shift;
+	my $id = shift;
 
+	$self->_create_node(
+		$self->{item_xpath},
+		undef,
+		'guid',
+		$id,
+		{
+			isPermaLink=>"false"
+		}
+	);
+}
 
 #----------------------------------------------------------
 

Modified: trunk/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat.pm	2008-06-27 14:28:53 UTC (rev 9949)
+++ trunk/Open-ILS/src/perlmods/OpenILS/WWW/SuperCat.pm	2008-06-29 07:07:00 UTC (rev 9950)
@@ -412,7 +412,7 @@
 
 		$feed->root($root);
 		$feed->creator($host);
-		$feed->update_ts(gmtime_ISO8601());
+		$feed->update_ts();
 		$feed->link( unapi => $base) if ($flesh_feed);
 
 		print "Content-type: ". $feed->type ."; charset=utf-8\n\n";
@@ -656,7 +656,9 @@
 
 		$feed->root($root);
 		$feed->creator($host);
-		$feed->update_ts(gmtime_ISO8601());
+
+		$feed->update_ts();
+
 		$feed->link( unapi => $base) if ($flesh_feed);
 
 		print "Content-type: ". $feed->type ."; charset=utf-8\n\n";
@@ -745,7 +747,7 @@
 
 	$feed->title("Items in Book Bag [".$bucket->name."]");
 	$feed->creator($host);
-	$feed->update_ts(gmtime_ISO8601());
+	$feed->update_ts();
 
 	$feed->link(alternate => $base . "/rss2-full/$id" => 'application/rss+xml');
 	$feed->link(atom => $base . "/atom-full/$id" => 'application/atom+xml');
@@ -754,7 +756,7 @@
 
 	$feed->link(
 		OPAC =>
-		'/opac/en-US/skin/default/xml/rresult.xml?rt=list&' .
+		$host . '/opac/en-US/skin/default/xml/rresult.xml?rt=list&' .
 			join('&', map { 'rl=' . $_->target_biblio_record_entry } @{$bucket->items} ),
 		'text/html'
 	);
@@ -814,7 +816,7 @@
 	}
 
 	$feed->creator($host);
-	$feed->update_ts(gmtime_ISO8601());
+	$feed->update_ts();
 
 	$feed->link(alternate => $base . "/rss2-full/$rtype/$axis/$limit/$date" => 'application/rss+xml');
 	$feed->link(atom => $base . "/atom-full/$rtype/$axis/$limit/$date" => 'application/atom+xml');
@@ -823,7 +825,7 @@
 
 	$feed->link(
 		OPAC =>
-		'/opac/en-US/skin/default/xml/rresult.xml?rt=list&' .
+		$host . '/opac/en-US/skin/default/xml/rresult.xml?rt=list&' .
 			join('&', map { 'rl=' . $_} @$list ),
 		'text/html'
 	);
@@ -1069,7 +1071,7 @@
 	$feed->title("Search results for [$terms] at ".$org_unit->[0]->name);
 
 	$feed->creator($host);
-	$feed->update_ts(gmtime_ISO8601());
+	$feed->update_ts();
 
 	$feed->_create_node(
 		$feed->{item_xpath},

Modified: trunk/Open-ILS/xsl/MARC21slim2ATOM.xsl
===================================================================
--- trunk/Open-ILS/xsl/MARC21slim2ATOM.xsl	2008-06-27 14:28:53 UTC (rev 9949)
+++ trunk/Open-ILS/xsl/MARC21slim2ATOM.xsl	2008-06-29 07:07:00 UTC (rev 9950)
@@ -24,6 +24,7 @@
 				</id>
 			</xsl:for-each>
 
+			<!-- Spec wants RFC 3339 format - fix it outside of XSL? -->
 			<xsl:for-each select="marc:controlfield[@tag=005]">
 				<updated>
 					<xsl:value-of select="."/>
@@ -77,17 +78,23 @@
 				</rights>
 			</xsl:for-each>
 
+			<!-- Spec wants RFC 3339 format - fix it outside of XSL? -->
 			<xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='c']">
 				<published>
 					<xsl:value-of select="."/>
 				</published>				
 			</xsl:for-each>
 
-			<xsl:for-each select="marc:datafield[500&lt;@tag][@tag&lt;=599][not(@tag=506 or @tag=530 or @tag=540 or @tag=546)]">
-				<summary>
-					<xsl:value-of select="marc:subfield[@code='a']"/>
-				</summary>
-			</xsl:for-each>
+			<!--
+			Spec wants zero or one summary elements per item; best option
+			would be to test for one of these elements and only create
+			if one exists, but for now we simply merge all candidates
+			-->
+			<summary>
+				<xsl:for-each select="marc:datafield[500&lt;@tag][@tag&lt;=599][not(@tag=506 or @tag=530 or @tag=540 or @tag=546)]">
+						<xsl:value-of select="marc:subfield[@code='a']"/>
+				</xsl:for-each>
+			</summary>
 
 			<xsl:for-each select="marc:datafield[@tag=600 or @tag=610 or @tag=611 or @tag=630 or @tag=650 or @tag=653]">
 				<category>

Modified: trunk/Open-ILS/xsl/MARC21slim2RSS2.xsl
===================================================================
--- trunk/Open-ILS/xsl/MARC21slim2RSS2.xsl	2008-06-27 14:28:53 UTC (rev 9949)
+++ trunk/Open-ILS/xsl/MARC21slim2RSS2.xsl	2008-06-29 07:07:00 UTC (rev 9950)
@@ -78,6 +78,7 @@
 				</dc:publisher>
 			</xsl:for-each>
 
+			<!-- this is supposed to be RFC-822 compliant -->
 			<xsl:for-each select="marc:datafield[@tag=260]/marc:subfield[@code='c']">
 				<pubDate>
 					<xsl:value-of select="."/>
@@ -94,11 +95,12 @@
 				</dc:format>
 			</xsl:for-each>
 
-			<xsl:for-each select="marc:datafield[500&lt;@tag][@tag&lt;=599][not(@tag=506 or @tag=530 or @tag=540 or @tag=546)]">
-				<description>
-					<xsl:value-of select="marc:subfield[@code='a']"/>
-				</description>
-			</xsl:for-each>
+			<!-- specification only allows one description element per item -->
+			<description>
+				<xsl:for-each select="marc:datafield[500&lt;@tag][@tag&lt;=599][not(@tag=506 or @tag=530 or @tag=540 or @tag=546)]">
+						<xsl:value-of select="marc:subfield[@code='a']"/>
+				</xsl:for-each>
+			</description>
 
 			<xsl:for-each select="marc:datafield[@tag=600]">
 				<dc:subject>



More information about the open-ils-commits mailing list