<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Terry's Worklog &#187; CONTENTdm</title>
	<atom:link href="http://people.oregonstate.edu/~reeset/blog/groups/digital-libraries/contentdm/feed" rel="self" type="application/rss+xml" />
	<link>http://people.oregonstate.edu/~reeset/blog</link>
	<description>On my work (programming, digital libraries, cataloging) and other stuff that perks my interest (family, cycling, etc)</description>
	<lastBuildDate>Sat, 21 Nov 2009 10:07:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CONTENTdm and OpenSearch</title>
		<link>http://people.oregonstate.edu/~reeset/blog/archives/397</link>
		<comments>http://people.oregonstate.edu/~reeset/blog/archives/397#comments</comments>
		<pubDate>Sun, 31 Dec 2006 10:59:49 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[CONTENTdm]]></category>
		<category><![CDATA[Digital Libraries]]></category>

		<guid isPermaLink="false">http://oregonstate.edu/~reeset/blog/archives/397</guid>
		<description><![CDATA[I love OpenSearch.&#160; It&#8217;s been one of those things that I&#8217;ve been wanting to spend more time looking at &#8212; maybe incorporate into Dspace or some of our other services like LibraryFind (which actually is now on the todo list).&#160; Anyway, folks may not know it, but Kyle Banerjee and I are writing a book.&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>I love OpenSearch.&nbsp; It&#8217;s been one of those things that I&#8217;ve been wanting to spend more time looking at &#8212; maybe incorporate into Dspace or some of our other services like LibraryFind (which actually is now on the todo list).&nbsp; Anyway, folks may not know it, but Kyle Banerjee and I are writing a book.&nbsp; A how to of sorts, for folks doing digital repositories.&nbsp; I&#8217;ve been lights out for most of December cranking out 4 finished and 1 1/2 nearly completed chapters.&nbsp; So far so good.&nbsp; Well, one of the parts that of the book deals with exposing resources to larger audiences and a discussion of OpenSearch falls into that section.&nbsp; As&nbsp; I was looking through the specification this afternoon, I thought, wow, this would be easy to implement just about everywhere.&nbsp;&nbsp; So I took a 1/2 hour, and quickly whipped up some code that integrated OpenSearch into CONTENTdm.&nbsp; I&#8217;ll post the code shortly.&nbsp; However, what I thought cool was the number of resources that have embraced OpenSearch as a query method.&nbsp; IE7 for example, utilizes OpenSearch as the method for querying search providers.&nbsp; This means that by adding an OpenSearch server to my Contentdm instance, I instantly am able to add this resource as a search target in IE 7.</p>
<p>&nbsp;</p>
<p><a href="http://oregonstate.edu/~reeset/blog/wp-content/mslive_images/CONTENTdmandOpenSearch_2872/ie7_integration3.jpg"><img height="400" src="http://oregonstate.edu/~reeset/blog/wp-content/mslive_images/CONTENTdmandOpenSearch_2872/ie7_integration_thumb1.jpg" width="640" border="0"></a></p>
<p>&nbsp;</p>
<p>As&nbsp;I mentioned,&nbsp;writing the code&nbsp;took about 30 minutes and&nbsp;was much easier than I&#8217;d anticipated.&nbsp;&nbsp;Given the speed at which OpenSearch has caught on outside the library community (I was surprised at how many applications and services support it) and&nbsp;how simple it is to implement &#8212; I&#8217;m thinking that its almost crazy not&nbsp;to spend the&nbsp;time&nbsp;and integrate the&nbsp;protocol into&nbsp;our organization&#8217;s&nbsp;services if only to give&nbsp;developers outside the library community an&nbsp;straighter line for service integration.</p>
<p>&nbsp;</p>
<p>&#8211;TR&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://people.oregonstate.edu/~reeset/blog/archives/397/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Adding user comments and tagging to CONTENTdm</title>
		<link>http://people.oregonstate.edu/~reeset/blog/archives/356</link>
		<comments>http://people.oregonstate.edu/~reeset/blog/archives/356#comments</comments>
		<pubDate>Fri, 29 Sep 2006 18:16:21 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[CONTENTdm]]></category>

		<guid isPermaLink="false">http://oregonstate.edu/~reeset/blog/archives/356</guid>
		<description><![CDATA[At OSU, we&#8217;ve played with this on and off and finally decided to just take this live.&#160; For those that use CONTENTdm, I&#8217;ve created a small document that discusses how this works and what it looks like.&#160; As I said, simple implementation at this point, but if use takes off, I&#8217;ll look to add things [...]]]></description>
			<content:encoded><![CDATA[<p>At OSU, we&#8217;ve played with this on and off and finally decided to just take this live.&nbsp; For those that use CONTENTdm, I&#8217;ve created a small document that discusses how this works and what it looks like.&nbsp; As I said, simple implementation at this point, but if use takes off, I&#8217;ll look to add things like tag clouds, integrated search results, etc.&nbsp; This won&#8217;t be interesting to anyone but folks using CONTENTdm.&nbsp; Sorry.</p>
<p>Here&#8217;s a link to the document: <a href="http://oregonstate.edu/~reeset/contentdm/downloads/CONTENTdm_Tagging.doc">CONTENTdm_Tagging.doc</a></p>
<p>&nbsp;</p>
<p>&#8211;TR</p>
]]></content:encoded>
			<wfw:commentRss>http://people.oregonstate.edu/~reeset/blog/archives/356/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Native RSS Support in CONTENTdm (kindof) :)</title>
		<link>http://people.oregonstate.edu/~reeset/blog/archives/342</link>
		<comments>http://people.oregonstate.edu/~reeset/blog/archives/342#comments</comments>
		<pubDate>Wed, 30 Aug 2006 22:58:33 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[CONTENTdm]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://oregonstate.edu/~reeset/blog/archives/342</guid>
		<description><![CDATA[Updated: Fixed a couple of typos below
Updated two: Thanks to Josh Kline for pointing out that the PubDate wasn&#8217;t RFC 822 complient.  This has been updated.
About a year ago, I created an RSS generator for CONTENTdm.&#160; At the time, CONTENTdm really didn&#8217;t have an API that could be worked with, so in building the [...]]]></description>
			<content:encoded><![CDATA[<p><i>Updated: Fixed a couple of typos below</i></p>
<p><i>Updated two: Thanks to Josh Kline for pointing out that the PubDate wasn&#8217;t RFC 822 complient.  This has been updated.</i></p>
<p>About a year ago, I created an RSS generator for <a href="http://www.contentdm.com">CONTENTdm</a>.&nbsp; At the time, CONTENTdm really didn&#8217;t have an API that could be worked with, so in building the generator, I created a perl script that would simply ping the server periodically and report back changes.&nbsp; This has been working fine, even with the newer 4.0 interfaces &#8212; but a few things had broken&#8230;just who has the time to fix everything.&nbsp; <img src='http://people.oregonstate.edu/~reeset/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &nbsp; </p>
<p>Anyway, over the past month, I have been updating all my older tools, documenting new ones and getting thing posted onto my CONTENTdm projects website (<a href="http://oregonstate.edu/~reeset/contentdm">http://oregonstate.edu/~reeset/contentdm</a>).&nbsp; A number of the new tools that I&#8217;ve been creating are relating to social software.&nbsp; I.e., I&#8217;ve created a commenting and tagging plugin for CONTENTdm (which I&#8217;ll likely post about once I finish documenting), updated this RSS feed and then have finally added LDAP authentication support to our CDM interface (though I wish DiMeMia allowed more customizability to the administration interfaces so I could integrate this better [and again, I'll post a code snippet once the docs are completed]).&nbsp; </p>
<p>The new RSS plugin is written entirely in PHP (to match the rest of the CONTENTdm files) and can generate feeds for the entire server or individual collections.&nbsp; The plugin makes use of the OAI server to extract information and then reformat for delivery in an RSS 2.0 wrapper.&nbsp; Here is an example of what this looks like:</p>
<p><a href="http://oregonstate.edu/~reeset/blog/wp-content/mslive_images/NativeRSSSupportinCONTENTdmkindof_93F4/rss_cdm2.png"><img height="385" src="http://oregonstate.edu/~reeset/blog/wp-content/mslive_images/NativeRSSSupportinCONTENTdmkindof_93F4/rss_cdm_thumb.png" width="640" border="0"></a> </p>
<p>For the most part, the plugin requires no changes to current CONTENTdm interfaces other than the presences of a link to the feed.&nbsp; We&#8217;ve done the following at our main collection page: <a href="http://digitalcollections.library.oregonstate.edu/">http://digitalcollections.library.oregonstate.edu/</a></p>
<p>Now the code &#8212; drop dead easy.&nbsp; </p>
<p><u><em>Code</em>:</u></p>
<pre>
&lt;?
  /*
   * Terry Reese
   * Modified: August 30, 2006
   *
   * Changes:
   *    Updated PubDate to correct date format.  Thanks to Josh Kline for pointing this out
   */
  define("CONTENTdmPath", "/usr/local/Content/docs/");
  define("DMSCRIPTS", "dmscripts/");
  define("BaseURL", "http://" . $_SERVER['SERVER_NAME'] . "/");
  define("OAIURL", BaseURL . "cgi-bin/oai.exe?verb=ListRecords&amp;metadataPrefix=oai_dc{set}&amp;from={start}&amp;until={end}");
  define("DEF_TITLE", "OSU CONTENTdm Image Collection");
  include(CONTENTdmPath . DMSCRIPTS . "DMSystem.php");

  if (isset($_GET['set'])) { $set = $_GET['set']; } else { $set = "";}

  class RSS {
     function header ($title,$link) {
        $string = '&lt;?xml version="1.0" encoding="UTF-8"?&gt;' .  "\n" .
		  '&lt;rss version="2.0"' . "\n" .
		  'xmlns:content="http://purl.org/rss/1.0/modules/content/"' . "\n" .
	 	  'xmlns:wfw="http://wellformedweb.org/CommentAPI/"' . "\n" .
		  'xmlns:dc="http://purl.org/dc/elements/1.1/"&gt;' . "\n" .
	          '&lt;channel&gt;' . "\n" .
		  '&lt;title&gt;'.$title.'&lt;/title&gt;' . "\n" .
		  '&lt;link&gt;'.$link.'&lt;/link&gt;' . "\n" .
		  '&lt;description&gt;&lt;/description&gt;' . "\n" .
		  '&lt;pubDate&gt;Mon, 28 Aug 2006 15:48:41 +0000&lt;/pubDate&gt;' . "\n" .
		  '&lt;language&gt;en&lt;/language&gt;' . "\n";
	 return $string;
     }

     function footer () {
	$string = "&lt;/channel&gt;\n";
    	$string .= "&lt;/rss&gt;";
	return $string;
     }

     function buildItem($DCValues) {
  	$string = "&lt;item&gt;\n" .
		  "&lt;title&gt;".$DCValues["title"]."&lt;/title&gt;\n" .
		  "&lt;link&gt;".$DCValues["identifier"]."&lt;/link&gt;\n" .
		  "&lt;pubDate&gt;". date("D, d M Y",  strtotime($DCValues["datestamp"])) . " 00:00:00 +0000&lt;/pubDate&gt;\n" .
		  "&lt;dc:creator&gt;".$DCValues["creator"]."&lt;/dc:creator&gt;\n";
	if (strlen($DCValues["description"])&gt;255) {
		$string .= "&lt;description&gt;&lt;![CDATA[" . substr($DCValues["description"], 0, 255) . "[...]]]&gt;&lt;/description&gt;\n";
        } else {
		$string .= "&lt;description&gt;&lt;![CDATA[" . $DCValues["description"] .  "]]&gt;&lt;/description&gt;\n";
	}
	$string .= "&lt;content:encoded&gt;&lt;![CDATA[" . $DCValues["description"] . "]]&gt;&lt;/content:encoded&gt;\n";
	$string .= "&lt;/item&gt;\n";
        return $string;
     } 

     function encodeDescription($set, $description, $subjects,  $uri) {
	$tarr = explode("/", $uri);
	$parr = explode(",", $tarr[count($tarr)-1]);
	$ptr = $parr[1];
	$set = $parr[0];
        $string = "&lt;img src="" . BaseURL .  "cgi-bin/getimage.exe?CISOROOT=/" . $set . "&amp;CISOPTR=" . $ptr . "&amp;DMSCALE=10.5&amp;DMWIDTH=250&amp;DMHEIGHT=250" border="0" /&gt;";
	$string .= "&lt;p&gt;" . $description . "&lt;br /&gt;&lt;br /&gt;\n" .
		   "Subjects: " . $subjects . "&lt;br /&gt;\n" .
		   "&lt;a href="" . $uri . ""&gt;Get MetaData&lt;/a&gt;&lt;/p&gt;";
	return $string;
      }
  } 

  $objRSS = new RSS;

  if ($set!="") {
     $oai_url = str_replace("{set}", "&amp;set=" . $set, OAIURL);
  } else {
     $oai_url = str_replace("{set}", "", OAIURL);
  }

  $date = date("m");
  $year = date("Y");

  $oai_url = str_replace("{start}", $year . "-" . sprintf("%02d", $date) . "-01", $oai_url);
  if ($date == "12") {
     $year = intval(date("Y")) + 1;
     $date = "01";
  } else {
     $date = intval(date("m")) + 1;
  }
  $oai_url = str_replace("{end}", $year . "-" . sprintf("%02d", $date) . "-01", $oai_url);

  $_xml = file_get_contents($oai_url);
  $p = xml_parser_create();
  xml_parse_into_struct($p, $_xml, $vals);
  xml_parser_free($p);

  $dc = array();
  $dc['title'] = "";
  $dc['setspec'] = "";
  $dc['identifier'] = "";
  $dc['subject'] = "";
  $dc['creator'] = "";
  $dc['description'] = "";
  $dc['datestamp'] = "";

  if ($set=="") {
	$coll_title = DEF_TITLE;
	$coll_link = BaseURL;
  } else {
        $rc = dmGetCollectionParameters("/" . $set, $coll_title, $path);
 	$coll_link = BaseURL . $set;
  }
  header("Content-type:  text/xml\n\n");
  print $objRSS-&gt;header($coll_title, $coll_link);
  foreach ($vals as $tag) {
     if ($tag['type'] == 'complete') {
	if ($tag['tag']=='DC:TITLE' &amp;&amp; $dc['title']=="") {
	   $dc['title'] = htmlspecialchars($tag['value']);
	} else if ($tag['tag'] == 'DC:IDENTIFIER') {
	   $dc['identifier'] = $tag['value'];
	} else if ($tag['tag'] == 'SETSPEC' &amp;&amp; $dc['setspec'] == "") {
	   $dc['setspec'] = $tag['value'];
	} else if ($tag['tag'] == 'DATESTAMP' &amp;&amp; $dc['datestamp'] == "") {
	   $dc['datestamp'] = $tag['value'];
  	} else if ($tag['tag'] == 'DC:DESCRIPTION' &amp;&amp; $dc['description'] == "") {
	   $dc['description'] = $tag['value'];
	} else if ($tag['tag'] == 'DC:CREATOR' &amp;&amp; $dc['creator'] == "") {
	   $dc['creator'] = htmlspecialchars($tag['value']);
	} else if ($tag['tag'] == 'DC:SUBJECT' &amp;&amp; $dc['subject'] == "") {
	   $dc['subject'] = htmlspecialchars($tag['value']);
	}
     } else if ($tag['type']=='close' &amp;&amp; $tag['tag']=='RECORD') {
	$dc['description'] = $objRSS-&gt;encodeDescription($set, $dc['description'], $dc['subject'],  $dc['identifier']);
	print $objRSS-&gt;buildItem($dc);
	$dc['title'] = "";
	$dc['setspec'] = "";
	$dc['identifier'] = "";
	$dc['subject'] = "";
	$dc['creator'] = "";
	$dc['description'] = "";
	$dc['datestamp'] = "";
     }
  }
  print $objRSS-&gt;footer();

?&gt;
</pre>
<p>And that&#8217;s it.</p>
<p>TR</p>
]]></content:encoded>
			<wfw:commentRss>http://people.oregonstate.edu/~reeset/blog/archives/342/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
