<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml"
>

<channel>
	<title>LiquidFoot &#187; Computing</title>
	<atom:link href="http://www.liquidfoot.com/category/computing/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.liquidfoot.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Sat, 17 Apr 2010 16:36:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Openlayers and Mobile Devices</title>
		<link>http://www.liquidfoot.com/2009/11/25/openlayers-and-mobile-devices/</link>
		<comments>http://www.liquidfoot.com/2009/11/25/openlayers-and-mobile-devices/#comments</comments>
		<pubDate>Wed, 25 Nov 2009 15:03:09 +0000</pubDate>
		<dc:creator>Wayne</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[gis]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[openlayers]]></category>

		<guid isPermaLink="false">http://www.liquidfoot.com/?p=326</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>After some really good conversations last week at the Institute on Enabling Geospatial Scholarship about mobile devices and mapping as an interpretive device, I mocked up a quick page to see how <a href="http://openlayers.org/">OpenLayers</a> looked on the Safari mobile browser. The theory to test out here was that you could pretty easily pull up your current location and plot your (approximate) location on a historic map (or any map for that matter) without having to install an application (like <a href="http://emergencestudios.com/historicearth/">Old Map App</a>). There are various hurdles in higher education to actually releasing software application through vendors like Apple&#8217;s App Store (restrictions on individual employees entering into contractual agreements), so we thought we&#8217;d explore using the browser to provide some of this functionality to users.</p>
<p>We have a few historic maps from our McGregor collection available through our <a href="http://geoserver.org">Geoserver</a> installation, so I looked up their layer ids and manually added them into a page with OpenLayers. Nothing fancy here, just a test to see what it looks like.</p>
<pre class="brush: jscript;">

var lat, long layer;
var zoom = 10;

var lat, lon, layer;
 var zoom = 10;

 map = new OpenLayers.Map('map');
 map.addControl(new OpenLayers.Control.LayerSwitcher());

 layer1 = new OpenLayers.Layer.WMS(&quot;Map of the Southern States&quot;,
 &quot;http://lat.lib.virginia.edu:8080/geoserver/gwc/service/wms&quot;,
 {layers: &quot;McGregor:000003056_00011&quot;}
 );
 layer2 = new OpenLayers.Layer.WMS(&quot;Nova Virginae tabula&quot;,
 &quot;http://lat.lib.virginia.edu:8080/geoserver/gwc/service/wms&quot;,
 {layers: &quot;McGregor:000003482_00011&quot;}
 );
 layer3 = new OpenLayers.Layer.WMS(&quot;A map of the most inhabited part of Virginia&quot;,
 &quot;http://lat.lib.virginia.edu:8080/geoserver/gwc/service/wms&quot;,
 {layers: &quot;McGregor:000003012_st1&quot;}
 );
 layer4 = new OpenLayers.Layer.WMS(&quot;Carte de la campagne en Virginie du Major General Mis. de la Fayette&quot;,
 &quot;http://lat.lib.virginia.edu:8080/geoserver/gwc/service/wms&quot;,
 {layers: &quot;McGregor:000003013_st1&quot;}
 );
 layer5 = new OpenLayers.Layer.WMS(&quot;Carte de la campagne en Virginie du Major General Mis. de la Fayette&quot;,
 &quot;http://lat.lib.virginia.edu:8080/geoserver/gwc/service/wms&quot;,
 {layers: &quot;McGregor:000003019_00011&quot;}
 );

 map.addLayer(layer1);
 map.addLayer(layer2);
 map.addLayer(layer3);
 map.addLayer(layer4);
 map.addLayer(layer5);

if(navigator.geolocation){
 navigator.geolocation.getCurrentPosition(function(position){
 lat = position.coords.latitude;
 lon = position.coords.longitude;
 map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);

 var vectorLayer = new OpenLayers.Layer.Vector(&quot;Overlay&quot;);
 var feature = new OpenLayers.Feature.Vector(
 new OpenLayers.Geometry.Point(lon, lat),
 {some:'data'},
 {externalGraphic: 'http://geocoder.ca/marker.png', graphicHeight: 64, graphicWidth: 48});
 vectorLayer.addFeatures(feature);
 map.addLayer(vectorLayer);
 });
 }

map.addControl(new OpenLayers.Control.PanZoomBar());
</pre>
<p>This actually worked surprisingly well the first time I launched it. With Firefox 3.5 I tested it on my laptop. At first I wasn&#8217;t using the <a href="http://geoserver.org/display/GEOSDOC/5.+GWC+-+GeoWebCache">geowebcache</a> we had set up, so it was a bit slow. I changed to the geowebcache WMS service and things in the browser were noticeably faster.</p>
<p>At lunch, I handed an iPhone to <a href="http://iconocla.st/">Schuyler Erle</a> who&#8217;s first instinct was to try to drag things around and zoom-in and out. Well, there was a fail as the controls you normally use in OpenLayers were far too small to actually be useful and it just didn&#8217;t feel right.</p>
<p>I then attempted to add in a touchHandler function to help with the interactions from the user. I found Ross Boucher&#8217;s post &#8220;<a title="Permanent Link: iPhone Touch Events in JavaScript" rel="bookmark" href="http://rossboucher.com/2008/08/19/iphone-touch-events-in-javascript/">iPhone Touch Events in JavaScript</a>&#8221; and used his code to get the sliding working:</p>
<pre class="brush: jscript;">

function touchHandler(event)
{
   var touches = event.changedTouches,
   first = touches[0],
   type = &quot;&quot;;

   switch(event.type)
   {
     case &quot;touchstart&quot;: type = &quot;mousedown&quot;; break;
     case &quot;touchmove&quot;:  type=&quot;mousemove&quot;; break;
     case &quot;touchend&quot;:   type=&quot;mouseup&quot;; break;
     default: return;
 }

 // initMouseEvent(type, canBubble, cancelable, view, clickCount,
 // screenX, screenY, clientX, clientY, ctrlKey,
 // altKey, shiftKey, metaKey, button, relatedTarget);

    var simulatedEvent = document.createEvent(&quot;MouseEvent&quot;);
    simulatedEvent.initMouseEvent(type, true, true, window, 1,
    first.screenX, first.screenY,
    first.clientX, first.clientY, false,
    false, false, false, 0/*left*/, null);

    first.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
 }

 document.addEventListener(&quot;touchstart&quot;, touchHandler, true);
 document.addEventListener(&quot;touchmove&quot;, touchHandler, true);
 document.addEventListener(&quot;touchend&quot;, touchHandler, true);
 document.addEventListener(&quot;touchcancel&quot;, touchHandler, true);
</pre>
<p>Now the scrolling worked, but you could no longer zoom into the map (and we want real zoom, not just making the image bigger). I haven&#8217;t found a fix for this yet, but I have to say that this is a kind of cool way of interacting with these materials.</p>
<p>Something I need to talk with Joe about next week making your location a query to <a href="http://geonetwork-opensource.org/">Geonetwork</a> and then using the top n maps returned to build this interface. It&#8217;s a little like a coverage map for your current location.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liquidfoot.com/2009/11/25/openlayers-and-mobile-devices/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More on Omeka Packaging</title>
		<link>http://www.liquidfoot.com/2009/11/20/more-on-omeka-packaging/</link>
		<comments>http://www.liquidfoot.com/2009/11/20/more-on-omeka-packaging/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 15:42:11 +0000</pubDate>
		<dc:creator>Wayne</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[fedorea]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[omeka]]></category>
		<category><![CDATA[rpm]]></category>

		<guid isPermaLink="false">http://www.liquidfoot.com/?p=316</guid>
		<description><![CDATA[I had meant to get this info out there a bit earlier, but we were sponsoring an NEH Institute on Enabling Geospatial Scholarship. That&#8217;s a different post, but I did want to get back to Omeka and flush out building the RPM for Omeka. What I&#8217;m going to do here is go through the setup [...]]]></description>
			<content:encoded><![CDATA[<p>I had meant to get this info out there a bit earlier, but we were sponsoring an <a href="http://www2.lib.virginia.edu/scholarslab/geospatial/">NEH Institute on Enabling Geospatial Scholarship</a>. That&#8217;s a different post, but I did want to get back to Omeka and flush out building the RPM for Omeka.</p>
<p>What I&#8217;m going to do here is go through the setup for building the RPM and the spec file. This <em>should</em> work on just about any OS that uses RPM for installing software, but this isn&#8217;t tested very extensively.</p>
<p>So I guess the first thing to cover is what exactly an RPM is. RPM is the Redhat Package Manager and is an implementation of a container for other files. It allows you to quickly install software, including necessary programs to run the program, provides information about the program you are installing, informs users about potential conflicts between your program and the software currently installed on the system, and provides a path to install, upgrade, and remove the software.</p>
<p>Now, in the case of Omeka, you don&#8217;t really need a package manager if you&#8217;re a seasoned system administrator. However, if you&#8217;re wanting to run this yourself, and you have to convince others to manage the software for you (e.g. you&#8217;re running it at an institution), have an RPM that your systems administrator installs will save a lot of headaches, especially since upgrades to the software can be integrated into scheduled maintenance with kernel and other software upgrades.</p>
<p>Building RPMs requires two things, the source you want to install and a specification (spec) file that tells the software what to do. You&#8217;ll need to first set your system up to have the tools to build software which you can do with a couple of lines (as the root user):</p>
<pre class="brush: bash;">

yum groupinstall &quot;Development Tools&quot;
yum install rpmdevtools
</pre>
<p>Next we need the directory hierarchy for building the RPMs. You can do this manually, but there&#8217;s a handy tool for helping out called rpmdev-setuptree. In the terminal, if you run this command, it will create a new folder in your home directory named &#8220;rpmbuild&#8221; with the correct directories made for you.</p>
<pre class="brush: bash;">
rpmdev-setuptree
</pre>
<p>If you want these in a different location, say omeka_rpm, you can manually create the following hierarchy:</p>
<pre class="brush: bash;">

mkdir -p ~/omeka_rpm/BUILD
mkdir -p ~/omeka_rpm/BUILDROOT
mkdir -p ~/omeka_rpm/RPMS
mkdir -p ~/omeka_rpm/SOURCES
mkdir -p ~/omeka_rpm/SPECS
mkdir -p ~/omeka_rpm/SRPMS
</pre>
<p>For our purposes, we&#8217;re really going to be dealing in the SOURCES and SPEC directories. Let&#8217;s start with the setup for the source files. First you need to get the source files from <a href="http://omeka.org/download">Omeka&#8217;s website</a> and put it into your SOURCES folder. We have to do some additional work with this file since it&#8217;s packaged using zip and the RPM is expecting a gzipped tarball. The following code snip assumes you&#8217;re using the default structure from the rpmdev-setuptree command and if a release after Omeka 1.1 is the most current, you will need to update the revision numbers.</p>
<pre class="brush: bash;">

cd ~/rpmbuild/SOURCES
wget http://omeka.org/files/omeka-1.1.zip
unzip omeka-1.1.zip
mv omeka-1.1 omeka
tar -czvf omeka-1.1.tar.gz omeka
</pre>
<p>Now if take a look at the directory, you should see a new file named &#8220;omeka-1.1.tar.gz&#8221; which is in the correct format for using it to build our RPM. There are two more files we need in here, an httpd configuration file and a readme for its use. Let&#8217;s just touch these so they exist and we can come back and add content to them a little later after I discuss them.</p>
<pre class="brush: bash;">

cd ~/rpmbuild/SOURCES
touch fedora-http-conf
touch README.fedora.omeka
</pre>
<p>Ok, let&#8217;s look at the real meat of this now. You need to create an omeka.spec file in the SPECS directory. This is the script that tells the rpmbuild tool how to set up the system.</p>
<p>I use gedit when I have a GUI, but emacs or vi work just as well (better if you&#8217;re good at the commands).</p>
<p>The idea behind this setup is to set up Omeka much like other software on the system is set up. This assumes that there will be only one installation of Omeka running on the system and takes into account that MySQL may be running on another server, so only the php &amp;gt;= 5.2.4, httpd, php-mysql, and ImageMagick packages are required. The configuration for the database connection is set in /etc/omeka/db.ini and uses a symbolic link to the application files in /usr/share/omeka (though this isn&#8217;t quite working yet). Themes and the archive folder shouldn&#8217;t get overwritten, so those directories stay in place. An httpd configuration for omeka (which aliases &#8220;/omeka&#8221;) is added into the httpd.conf directory. Since this software does not actually need to be compiled for a processor architecture type, the build archicture is set to noarch.</p>
<pre class="brush: bash;">
Summary: Omeka web publishing software
URL: http://omeka.org
Name: omeka
Version: 1.1
Group: Application/Publishing
Release: 1%{?dist}
License: GPL
Source0: %{name}-%{version}.tar.gz
Source1: omeka-http-conf
Source2: README.fedora.omeka
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Requires: php &amp;gt;= 5.2.4, httpd, php-mysql, ImageMagick
BuildArch: noarch

%description
Omeka is a free and open source collections based web-based publishing platform for scholars, librarians, archivists, museum professionals, educators, and cultural enthusiasts.

%prep
%setup -q -n omeka

%install
 mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/omeka
 mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/omeka
 install -m 0644 -D -p %{SOURCE1} ${RPM_BUILD_ROOT}%{_sysconfdir}/httpd/conf.d/omeka.conf
 cp -pr * ${RPM_BUILD_ROOT}%{_datadir}/omeka
 #cat db.ini | sed -e &quot;s|dirname(__FILE__).'/'|'/usr/share/omeka/!|g&quot; &amp;gt; ${RPM_BUILD_ROOT}%{_sysconfdir}/omeka/db.ini
 #/bin/ln -sf ../../../etc/omeka/db.ini ${RPM_BUILD_ROOT}%{_datadir}/omeka/db.ini
 /bin/cp %{SOURCE2} ./README.fedora
 # Remove empty files for rmplint
 find ${RPM_BUILD_ROOT} -empty -exec rm -f {} \;
 # These are docs; remove and docify later
 rm -f ${RPM_BUILD_ROOT}%{_datadir}/omeka/{readme.txt,license.txt,release.txt,changelog.txt}

%clean
 rm -rf ${RPM_BUILD_ROOT}

%files
 %defattr(-,root,root,-)
 %config(noreplace) %{_sysconfdir}/httpd/conf.d/omeka.conf
 %dir %{_datadir}/omeka
 %{_datadir}/omeka/admin
 %{_datadir}/omeka/application
 %{_datadir}/omeka/archive
 %doc changelog.txt
 %config(noreplace) %{_sysconfdir}/omeka/db.ini
 %{_datadir}/omeka/index.php
 %doc license.txt
 %{_datadir}/omeka/paths.php
 %{_datadir}/omeka/install
 %{_datadir}/omeka/plugins
 %doc readme.txt
 %doc release.txt
 %{_datadir}/omeka/robots.txt
 %{_datadir}/omeka/themes
 %dir %{_sysconfdir}/omeka

%changelog
* Mon Nov 09 2009 Wayne Graham &amp;lt;wayne dot graham at virginia dot edu&amp;gt; - 1.1
- Initial build
</pre>
<p>Now we can add in the httpd configuration that will get written. Open up SOURCES/omeka-http-conf and add</p>
<pre class="brush: plain;">

Alias /omeka /var/www/omeka

&amp;lt;Directory /var/www/omeka&amp;gt;
 AllowOverride Options
&amp;lt;/Directory&amp;gt;
</pre>
<p>And README.fedora.omeka</p>
<pre class="brush: plain;">

Omeka is a database driven web publishing program.

Once this package is installed, there are a few configuration items which need
to be performed before Omeka is usable.  First, you need to establish a
username and password with which to connect to your MySQL database. You also need to make both
MySQL and Omeka aware of this configuration.  Let's start by creating the database and the
username / password inside MySQL first:

 # mysql
 mysql&amp;gt; create database omeka;
 Query OK, 1 row affected (0.00 sec)

 mysql&amp;gt; grant all privileges on omeka.* to omeka identified by '1superPrivateOmekaPassword!';
 Query OK, 0 rows affected (0.00 sec)

 mysql&amp;gt; flush privileges;
 Query OK, 0 rows affected (0.00 sec)

 mysql&amp;gt; exit
 Bye
 #

Under certain curcumstances, you may need to run variations of the &quot;grant&quot;
command:
mysql&amp;gt; grant all privileges on omeka.* to omeka@localhost identified by 'omeka';
 OR
mysql&amp;gt; grant all privileges on omeka.* to omeka@'%' identified by 'omeka';

This has created an empty database named 'omeka', created a user named
'omeka' with a password of '1superPrivateOmekaPassword!', and given the 'omeka' user total
permission over the 'omeka' database.  Obviously, you'll want to select a
different password, and you may want to choose different database and user
names depending on your installation.  The specific values you choose are
not constrained, they simply need to be consistent between the database and the
config file.

Next, you need to edit your /var/www/omeka/db.ini file to reflect the
values you've chosen.  These values will go in the appropriate places at the
beginning of that file.

Once that's done and the database server and web server have been started,
open a web browser to http://localhost/omeka/install/ and
follow the instructions given to you on the pages you see to set up the
database tables and begin publishing your Omeka instace.
</pre>
<p>Now everything is in place. Let&#8217;s try to build this thing. Go in to the SPEC directory and build the binary for the rpm.</p>
<pre class="brush: bash;">

cd ~/rpmbuild/SPECS
rpmbuild -bb omeka.spec
</pre>
<p>This takes a while, and if you&#8217;re running this through VMWare of VirtualServer, this process will demand some pretty hefty system resources and your system will slow down.</p>
<p>If everything has gone correctly, you should now have a nice new RPM package named omeka-1.1.fc11.noarch.rpm in the RPMS/noarch directory. You can test it out by installing the package with</p>
<pre class="brush: bash;">

rpm -Uvh omeka-1.1.fc11.noarch.rpm
</pre>
<h2>What&#8217;s Next</h2>
<p>For packaging RPMs like this, a few more infrastructure elements need to be in place. The following outlines some of them (if you have more, leave a comment).</p>
<ul>
<li>Put the build files into SCM (currently only in our private SVN repo)</li>
<li>Auto-install dependencies</li>
<li>Set up an RPM repository to work with yum
<ul>
<li>Target specific Linux builds</li>
</ul>
</li>
<li>Automate build</li>
<li>Run MySQL setup script after initial install</li>
<li>Build aptitude package (using <a href="http://packages.debian.org/lenny/alien">alien</a>?)</li>
</ul>
<h2>Additional Resources</h2>
<ul>
<li><a href="http://docs.fedoraproject.org//developers-guide/ch-rpm-building.html">Chapter 4. Building RPM Packages</a></li>
<li><a title="How To Build RPM Packages on Fedora" rel="bookmark" href="http://www.g-loaded.eu/2006/04/05/how-to-build-rpm-packages-on-fedora/">How To Build RPM Packages on Fedora</a></li>
<li><a href="http://fedoraproject.org/wiki/Packaging/ScriptletSnippets">RPM scriptlet recipes</a></li>
<li><a href="http://fedoraproject.org/wiki/Packaging/NamingGuidelines">Package Naming Guidelines</a></li>
<li><a href="http://fedoraproject.org/wiki/Packaging/Guidelines">Packaging Guidelines</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.liquidfoot.com/2009/11/20/more-on-omeka-packaging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sherlock/OpenSearch Plugins for Libraries</title>
		<link>http://www.liquidfoot.com/2009/01/15/sherlockopensearch-plugins-for-libraries/</link>
		<comments>http://www.liquidfoot.com/2009/01/15/sherlockopensearch-plugins-for-libraries/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 19:34:12 +0000</pubDate>
		<dc:creator>Wayne</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[opensearch]]></category>

		<guid isPermaLink="false">http://www.liquidfoot.com/?p=240</guid>
		<description><![CDATA[Back in the day, I used to work on the <a href="http://mycroft.mozdev.org/">Mycroft Project</a>. At the time, only Firefox/Netscape could actually used these plugins as they were based on Apple's Sherlock specification (Mycroft is Sherlock Holmes' brother, btw). These plugins have been a staple in the Firefox browser, but the Sherlock spec was a little arcane. More recently, both Firefox and IE have implemented support for the <a href="http://www.opensearch.org/Home">OpenSearch specification</a>. I have to say that the OpenSearchDescription is a significant update (at least from a readability standpoint) than Sherlock.]]></description>
			<content:encoded><![CDATA[<p>Back in the day, I used to work on the <a href="http://mycroft.mozdev.org/">Mycroft Project</a>. At the time, only Firefox/Netscape could actually used these plugins as they were based on Apple&#8217;s Sherlock specification (Mycroft is Sherlock Holmes&#8217; brother, btw). These plugins have been a staple in the Firefox browser, but the Sherlock spec was a little arcane. More recently, both Firefox and IE have implemented support for the <a href="http://www.opensearch.org/Home">OpenSearch specification</a>. I have to say that the OpenSearchDescription is a significant update (at least from a readability standpoint) than Sherlock.</p>
<p>A few years ago, I had written a bunch of Sherlock plugins for <a href="http://swem.wm.edu/resources/tools/">searching various library</a> catalogs. Those pretty much lay dormant until I was talking with my student worker this last semester and he got quite excited about these, and wondered if there might be a way to also search the databases the library subscribes to, and provide off-campus access to these through our proxy server. This code is in a very basic stage right now, but essentially what I did was create a database driven application in PHP that generates OpenSearch XML for various targets to search against.</p>
<p>Right now, this only supports HTTP GET requests (POST parameters require an additional table), but here&#8217;s the DDL:</p>
<pre name="code" class="sql">CREATE TABLE `plugins` (
  `id` char(36) NOT NULL,
  `short_name` varchar(50) NOT NULL,
  `description` varchar(255) NOT NULL,
  `engine` varchar(25) NOT NULL,
  `image` varchar(25) NOT NULL,
  `input_encoding` varchar(10) NOT NULL,
  `url` varchar(550) NOT NULL,
  `method` varchar(4) NOT NULL default 'get',
  `proxy` tinyint(1) NOT NULL default '1',
  KEY `engine_index` (`engine`),
  KEY `short_name_index` (`short_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1</pre>
<p>You don&#8217;t need all of these fields for every record, and here is some useful records&#8230;</p>
<pre name="code" class="sql">INSERT INTO plugins (id, short_name, engine, input_encoding, method, proxy, url)
VALUES (UUID(), ' JStor', 'jstor', 'UTF-8', 'get', 1, 'http://www.jstor.org/action/doBasicSearch?Query=');

INSERT INTO plugins (id, short_name, engine, input_encoding, method, proxy, url)
VALUES (UUID(), 'Google Your University', 'google', 'UTF-8', 'get', 1, 'http://www.google.com/univ/wm?hl=en&amp;ie=ISO-8859-1&amp;btnG=Google+Search&amp;q=');

INSERT INTO plugins (id, short_name, engine, input_encoding, method, proxy, url)
VALUES (UUID(), 'Google Scholar', 'googlescholar', 'UTF-8', 'get', 1, 'http://scholar.google.com/scholar?&amp;hl=en&amp;lr=&amp;btnG=Search&amp;q=');

INSERT INTO plugins (id, short_name, engine, input_encoding, method, proxy, url)
VALUES (UUID(), 'Ebrary', 'ebrary', 'UTF-8', 'get', 1, 'http://site.ebrary.com/lib//Top?layout=search&amp;nosr=1&amp;sch=sch&amp;frm=smp.x&amp;p00=');

INSERT INTO plugins (id, short_name, engine, input_encoding, method, proxy, url)
VALUES (UUID(), 'EbscoHost', 'ebsco', 'UTF-8', 'get', 1, 'http://search.ebscohost.com/login.aspx?db=aph&amp;direct=true&amp;bQuery=');

INSERT INTO plugins (id, short_name, engine, input_encoding, method, proxy, url)
VALUES (UUID(), 'LexisNexis', 'lexisnexis', 'UTF-8', 'get', 1, 'http://www.lexisnexis.com/us/lnacademic/search/homesubmitForm.do');

INSERT INTO plugins (id, short_name, engine, input_encoding, method, proxy, url)
VALUES (UUID(), 'Proquest UMI', 'umi', 'UTF-8', 'get', 1, 'http://proquest.umi.com/pqdweb?RQT=305&amp;FT=1&amp;DBId=414&amp;SQ=');

INSERT INTO plugins (id, short_name, engine, input_encoding, method, proxy, url)
VALUES (UUID(), 'Science Direct', 'sciencedirect', 'UTF-8', 'get', 1, 'http://www.sciencedirect.com/science/quicksearch?query=');</pre>
<p>Apparently I wrote the queries with MDB2, I&#8217;ve since moved most of my interactions to Zend Db (you should be able to write that part pretty quickly) and just dump the names of the plugins in the tableon a view:</p>
<pre name="code" class="php">foreach($plugins as $plugin):

    echo('&amp;lt;li&amp;gt;' . $plugin['short_name'] . ': ');
       echo(' &amp;lt;a href="openSearch.php?id=' . $plugin['id'] . '"&amp;gt;&amp;lt;img src="images/a9.png" title="OpenSearch" /&amp;gt;&amp;lt;/a&amp;gt;'); 

        if(strlen($plugin['url']) &amp;gt; 0){
        	echo(' &amp;lt;a href="search.php?engine=' . $plugin['engine'] . '&amp;q=regulators"&amp;gt;test search');
            echo(' | &amp;lt;a href="#" title="Ref: ' . $plugin['engine'] . '" onClick="addOpenSearch(\'' . $plugin['engine'] . '\', \'gif\', \'Education\', \'' . $plugin['id'] . '\'); return false;"&amp;gt;add&amp;lt;/a&amp;gt;');
        }

        echo('&amp;lt;/li&amp;gt;);

');
endforeach;</pre>
<p>The add code is straight-forward</p>
<pre name="code" class="php">$result = $result[0];

$short_name = $result['short_name'];
$description = $result['description'];
$engine = $result['engine'];
$id = $result['id'];

$xml = &amp;lt;&amp;lt;&amp;lt;EOT
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
xmlns:moz="http://www.mozilla.org/2006/browser/search/"&amp;gt;
&amp;lt;ShortName&amp;gt;$short_name&amp;lt;/ShortName&amp;gt;
&amp;lt;Description&amp;gt;$description&amp;lt;/Description&amp;gt;
&amp;lt;Url type="text/html" method="get" template="http://&amp;lt;your_server&amp;gt;/plugins/proxy.php?engine=$engine&amp;q="/&amp;gt;
&amp;lt;Contact&amp;gt;libsys@wm.edu&amp;lt;/Contact&amp;gt;
&amp;lt;Image width="16" height="16"&amp;gt;http://&amp;lt;your_server&amp;gt;/favicon.ico&amp;lt;/Image&amp;gt;
&amp;lt;Developer&amp;gt;Wayne Graham&amp;lt;/Developer&amp;gt;
&amp;lt;InputEncoding&amp;gt;UTF-8&amp;lt;/InputEncoding&amp;gt;
&amp;lt;moz:SearchForm&amp;gt;http://&amp;lt;your_server&amp;gt;/plugins/search.php?engine=$engine&amp;lt;/moz:SearchForm&amp;gt;
&amp;lt;moz:UpdateUrl&amp;gt;http://&amp;lt;your_server&amp;gt;/plugins/opensearch.php?$id&amp;lt;/moz:UpdateUrl&amp;gt;
&amp;lt;moz:IconUpdateUrl&amp;gt;http://swem.wm.edu/favicon.ico&amp;lt;/moz:IconUpdateUrl&amp;gt;
&amp;lt;moz:UpdateInterval&amp;gt;7&amp;lt;/moz:UpdateInterval&amp;gt;
&amp;lt;/OpenSearchDescription&amp;gt;
EOT;
header("Content-Type: text/xml");
echo($xml);</pre>
<p>You just need a little JavaScript to add this in to IE and Firefox:</p>
<pre name="code" class="JavaScript">
function addOpenSearch(name,ext,cat,pid,meth)
{
  if ((typeof window.external == "object") &#038;&#038; ((typeof window.external.AddSearchProvider == "unknown") || (typeof window.external.AddSearchProvider == "function"))) {
    // See bugs 430058/430067/430070 for Camino
    if (((typeof window.external.AddSearchProvider == "unknown") || (window.navigator.vendor == 'Camino'))&#038;&#038; meth == "p") {
      alert("This plugin uses POST which is not currently supported by your browser's implementation of OpenSearch.");
    } else {
      window.external.AddSearchProvider("http://<your_server>/plugins/install.php?id=" + pid);
    }
  } else {
    alert("You will need a browser which supports OpenSearch to install this plugin.");
  }
}
</pre>
<p>If I get some time soon, I&#8217;ll wrap this up into a package; rudimentary, but a decent start to your own app!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liquidfoot.com/2009/01/15/sherlockopensearch-plugins-for-libraries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>It Works!</title>
		<link>http://www.liquidfoot.com/2008/12/17/it-works/</link>
		<comments>http://www.liquidfoot.com/2008/12/17/it-works/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 03:39:13 +0000</pubDate>
		<dc:creator>Wayne</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.liquidfoot.com/?p=143</guid>
		<description><![CDATA[With my departure from W&#38;M we talked about the deployment of the second Sun X4500 for the library. My original plan was to wait until the 10/08 system came out (which had the SAMBA stuff in the kernel) and then deploy the hardware with ZFS and Z-RAID. However, no one else really has any experience [...]]]></description>
			<content:encoded><![CDATA[<p>With my departure from W&amp;M we talked about the deployment of the second Sun X4500 for the library. My original plan was to wait until the 10/08 system came out (which had the SAMBA stuff in the kernel) and then deploy the hardware with ZFS and Z-RAID. However, no one else really has any experience with either administering SAMBA or Solaris. I had read that Windows could be installed on these servers. It&#8217;s a bit of a sacrilege, but it should help out until they find a replacement.</p>
<p>The Sun Installation Assistant CD really took all the work out of setting the thing up&#8230;it includes all the required drivers for the hard drives and NIC. Took a while since I was redirecting the KVM through the ILOM and sharing my ROM drive. Everything went very well, but I did notice that the OS I installed (Windows 2003 R2 Standard) has a limit of 4GB. I couldn&#8217;t for the life of me figure out what happend to the other 12GB. Been in *nix too long and forgot that Microsoft puts limits on the amount of RAM a server can support. I just need to reinstall with Enterprise edition. Not a huge deal, but it&#8217;s one of those things I wish I would have known/remembered.</p>
<p>I did set up a &#8220;test&#8221; share (it&#8217;s primarily to give our media center access to a lot of storage), but I ran into an issue(s) with OS X. Seems the mount would take, but you can&#8217;t see any of the files. You can move files to the server, but they don&#8217;t show up.</p>
<p>I think the bandwidth should be ok coming from the media center. There&#8217;s full gigE from the desktop to the server and I ganged the NICs.</p>
<p>I wished I could have used the Z-RAID, and I&#8217;m not sure that the Windows Dynamic RAID-5 will do quite the same job, but it&#8217;s a step forward in getting some storage (and not attached hard drives) for media production.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liquidfoot.com/2008/12/17/it-works/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open Search</title>
		<link>http://www.liquidfoot.com/2008/11/06/open-search/</link>
		<comments>http://www.liquidfoot.com/2008/11/06/open-search/#comments</comments>
		<pubDate>Thu, 06 Nov 2008 16:32:45 +0000</pubDate>
		<dc:creator>Wayne</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[opensearch]]></category>

		<guid isPermaLink="false">http://www.liquidfoot.com/?p=116</guid>
		<description><![CDATA[It&#8217;s been a while since I last posted, but the NEH Slave Quarters project is coming to a close and the next grant is out the door (to build a digital archive of the newspaper articles of Elizabeth Stoddard). So I showed my student worker the search plugins I had made a few years ago [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I last posted, but the NEH Slave Quarters project is coming to a close and the next grant is out the door (to build a digital archive of the newspaper articles of Elizabeth Stoddard).</p>
<p>So I showed my student worker the search plugins I had made a few years ago and he got really excited. They&#8217;re burried on our website right now (but then again, so is everything), but he like the convienence. He actually got me to start thinking about it a bit more. IE 7 and Firefox both use OpenSearch now for their search plugins. There&#8217;s not a whole lot to this description (and it&#8217;s a lot more convienent than the Sherlock format). What if I built a quick app that could generate the XML for these and them people could install them? We could quickly develop a collection of useful plugins that would help folks get to data (hopefully) faster.</p>
<p>I started looking at it yesterday and it&#8217;s pretty straight forward&#8230;with a few exceptions. Most search engines use a get method, but I&#8217;m finding a bunch of our most popular search engine providers (e.g. lexisnexis, factiva, etc.) use a post method with weird session variables.</p>
<p>Focusing on just the &#8220;easy&#8221; stuff first, I wrote a database table (which is still in flux) that recorded the basic OpenSearch fields first: short_name, description, input_encoding, and url. I populated the fields with some basic search engines that folks use here at William and Mary: all the libraries, Google Scholar, Ebrary, JStor, EbscoHost, ScienceDirect, and our federated searching engine). I wrote a search proxy to rewrite the search URLs, though it&#8217;s really not necessary (and I may change that).</p>
<p>Since I got on the kick, I figured I&#8217;d write something up real quick for Vufind too. By adding a few lines of code, folks will be able to add the Vufind instance to their search list without doing much!</p>
<p>After I get the code a bit cleaner, and work through some of the other &#8220;issues&#8221; with search providers who use &#8216;POST&#8217; for queries, I&#8217;ll add some code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liquidfoot.com/2008/11/06/open-search/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NFS Geek Out</title>
		<link>http://www.liquidfoot.com/2008/10/01/nfs-geek-out/</link>
		<comments>http://www.liquidfoot.com/2008/10/01/nfs-geek-out/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 23:23:34 +0000</pubDate>
		<dc:creator>Wayne</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[geek]]></category>
		<category><![CDATA[nfs]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://www.liquidfoot.com/?p=112</guid>
		<description><![CDATA[And that&#8217;s not Need for Speed A while back I got a couple of Sun Thumpers (24TB each) to help out with our storage needs in the library. I&#8217;ve gotten to the point to deploy them. I have to admit I really dig the Solaris admin tools (web based ILOM) and the ZFS configuration tools. [...]]]></description>
			<content:encoded><![CDATA[<p>And that&#8217;s not Need for Speed <img src='http://www.liquidfoot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>A while back I got a couple of Sun Thumpers (24TB each) to help out with our storage needs in the library. I&#8217;ve gotten to the point to deploy them. I have to admit I really dig the Solaris admin tools (web based ILOM) and the ZFS configuration tools.</p>
<p>The idea for the first Thumper is to make that the primary storage for of content for our institutional repository (we&#8217;re running DSpace). The last couple of days I&#8217;ve been getting down to a really geeky level in systems administration. I created an NFS share, but the question was on how to mount it. We use nfs3 in the integrated graphics labs to mount the high performance computing clusters, so I did this for DSpace and added an fstab entry</p>
<p>&lt;server&gt;:/dspace /dspace_nfs nfs rw,nosuid,hard,intr,rsize=32768,wsize=32768,tcp 0 0</p>
<p>I then ran some test to see what kind of throughput I could get.</p>
<p>time dd if=/dev/zero of=/dspace_nfs/dspace/testfile bs=16 count=16384</p>
<p>I got a result of</p>
<p>262144 bytes (262 kB) copied, 0.088866 seconds, 2.9 MB/s</p>
<p>Then, just to compare it against normal disk I/O, I did the same on the local hard drive</p>
<p>time dd if=dev/zero of=~/testfile bs=16 count=16384</p>
<p>This was quite a bit faster (as you probably would guess)</p>
<p>262144 bytes (262 kB) copied, 0.041865 seconds, 6.3 MB/s</p>
<p>To test the read speed, I took the same file and brought it back.</p>
<p>time dd if=/dspace_nfs/dspace/testfile of=/dev/null bs=16</p>
<p>On the NFS mount I got</p>
<p>262144 bytes (262 kB) copied, 0.017822 seconds, 14.7 MB/s</p>
<p>and on the local file system I got</p>
<p>262144 bytes (262 kB) copied, 0.015867 seconds, 16.5 MB/s</p>
<p>I was kind of surprised at how close the reads were. It&#8217;s not a huge file it&#8217;s moving (our larger files are around 350MB), but it&#8217;s reasonably consistence with an arbitrary file size of the PDFs we have in the collection.</p>
<p>I was corresponding with a colleague who&#8217;s been doing this way longer than I have and he suggested using a larger blocksize and writing/reading some files larger than the RAM size. I also wanted to test against NFS4 (I was using NFS3 in the fstab entry).</p>
<p>To do this, I just created a mount point and mounted the filesystem.</p>
<p>mkdir /mnt/nfs4<br />
mount -t nfs4 &lt;server&gt;:/dspace /mnt/nfs4</p>
<p>I ran the same test on the new mount and got a result of</p>
<p>262144 bytes (262 kB) copied, 0.055023 seconds, 4.8 MB/s</p>
<p>and for the read</p>
<p>262144 bytes (262 kB) copied, 0.014205 seconds, 18.5 MB/s</p>
<p>So, it looks like NFSv4 is much improved over NFSv3!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liquidfoot.com/2008/10/01/nfs-geek-out/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Virtualbox 2.0</title>
		<link>http://www.liquidfoot.com/2008/09/11/virtualbox-20/</link>
		<comments>http://www.liquidfoot.com/2008/09/11/virtualbox-20/#comments</comments>
		<pubDate>Thu, 11 Sep 2008 13:18:41 +0000</pubDate>
		<dc:creator>Wayne</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[virtual box]]></category>

		<guid isPermaLink="false">http://www.liquidfoot.com/?p=65</guid>
		<description><![CDATA[I saw this morning that Sun released VirtualBox 2.0 (it was released last Thursday, but had missed that). The big update (at least to me) is that it now supports 64-bit guests (on 64-bit hosts). I added the deb packages for my Ubuntu box and installed the virtualbox-2.0. The package installed properly, but the icon [...]]]></description>
			<content:encoded><![CDATA[<p>I saw this morning that Sun released VirtualBox 2.0 (it was released last Thursday, but had missed that). The big update (at least to me) is that it now supports 64-bit guests (on 64-bit hosts). I added the <a href="http://www.virtualbox.org/wiki/Linux_Downloads">deb packages for my Ubuntu</a> box and installed the virtualbox-2.0. The package installed properly, but the icon I had been using to launch the program went away and launching from the terminal also disappered.</p>
<p>The fix was pretty quick, but took a couple of minutes to locate. On top of installing the new package, you also need to run the vboxdrv setup to recompile the kernel module.</p>
<pre class="brush: php;">sudo /etc/init.d/vboxdrv setup</pre>
<p>After you run this, everything runs wonderfly again <img src='http://www.liquidfoot.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.liquidfoot.com/2008/09/11/virtualbox-20/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solr and Coldfusion &#8212; Setting Up</title>
		<link>http://www.liquidfoot.com/2007/10/05/solr-and-coldfusion-setting-up/</link>
		<comments>http://www.liquidfoot.com/2007/10/05/solr-and-coldfusion-setting-up/#comments</comments>
		<pubDate>Fri, 05 Oct 2007 19:22:14 +0000</pubDate>
		<dc:creator>Wayne</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[coldfusion]]></category>
		<category><![CDATA[solr]]></category>

		<guid isPermaLink="false">http://www.liquidfoot.com/?p=180</guid>
		<description><![CDATA[To get up and running with Solr, you&#8217;ll need some type of Servlet container. Typically when folks start talking about servlet containers, they&#8217;re talking about Tomcat or Jetty. In fact, Solr comes with Jetty 6.1.3 (they haven&#8217;t upgraded to 6.1.5 yet in the distribution). You may also hear about Resin, but in my experience, it [...]]]></description>
			<content:encoded><![CDATA[<div class="body">
<p>To get up and running with Solr, you&#8217;ll need some type of Servlet container. Typically when folks start talking about servlet containers, they&#8217;re talking about <a href="http://tomcat.apache.org/">Tomcat</a> or <a href="http://jetty.mortbay.org/">Jetty</a>. In fact, Solr comes with Jetty 6.1.3 (they haven&#8217;t upgraded to 6.1.5 yet in the distribution). You may also hear about <a href="http://www.caucho.com/">Resin</a>, but in my experience, it runs a bit slower than Jetty and Tomcat. As a small note, servlet containers are different than J2EE application servers like JRun, Geronimo, GlassFish, and JBoss (which use servlet containers like Tomcat and Jetty, but also have EJB containers and can handle other types of logic). If you have a J2EE application server running, you can easily use Solr, and if not, consider using Jetty or Tomcat as your container server.</p>
<p>Since your environment can be as varied as there are IT departments, I won&#8217;t try to cover everything. Essentially you need to have at least the Java 1.5 JRE. However, I would <strong>strongly</strong> suggest the most current <a href="http://java.sun.com/">Java JDK (and not the JRE)</a> as it has performance enhancements to run in server mode (with -server). If you don&#8217;t already have this Java version installed on your server (assuming this is the same server running CF), don&#8217;t worry, ColdFusion will still work if you install the required Java runtime.</p>
<p>Essentially the process for deploying Solr, once you have a servlet container up-and-running is to drop the solr.war file into the webapps directory on the server. It won&#8217;t do anything at this point as you need to set the configuration files for Solr. The easiest way to do this is copy the files from example/solr into a new directory (which I will refer to now as solr_home).</p>
<p>You can tell Java about the home directory by setting the solr.solr.home (-Dsolr.sol.home), set the JNDI lookup (&#8220;java:comp/env/solr/home&#8221;), or just throw it into the JVM&#8217;s working directory (the default path is ./solr). Now you just need to make sure everything is running. Just point your browser to http://&lt;server&gt;:&lt;port&gt;/solr/admin. You should then see the administration interface (you may need to restart your servlet container to get everything working properly), but it&#8217;s not an administrative interface like you get in CFAdmin. This is more of an informational administration panel. You can make sure everything is running, that there are documents in your index is set up properly, check out the schema and configuration files, and thread information. Really the only thing you can administer here is the log level.</p>
<p>For some more specific notes on intalling Solr in <a href="http://wiki.apache.org/solr/SolrTomcat">Tomcat</a> and <a href="http://wiki.apache.org/solr/SolrJetty">Jetty</a>, check out <a href="http://wiki.apache.org/solr/SolrInstall">Solr&#8217;s wiki</a>. In particular, if you&#8217;re going to need multiple instances of Solr to run, pay attention to the sections on Multipe Solr apps on those wiki pages.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.liquidfoot.com/2007/10/05/solr-and-coldfusion-setting-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coldfusion Solr Client &#8211; SolColdfusion</title>
		<link>http://www.liquidfoot.com/2007/10/04/coldfusion-solr-client-solcoldfusion/</link>
		<comments>http://www.liquidfoot.com/2007/10/04/coldfusion-solr-client-solcoldfusion/#comments</comments>
		<pubDate>Thu, 04 Oct 2007 22:19:47 +0000</pubDate>
		<dc:creator>Wayne</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[coldfusion]]></category>
		<category><![CDATA[lucene]]></category>
		<category><![CDATA[solr]]></category>

		<guid isPermaLink="false">http://www.liquidfoot.com/?p=182</guid>
		<description><![CDATA[As I hinted at yesterday, I was close to having some code in the pipeline to abstract using Solr. I&#8217;ve finished the initial code with the following built in. Here&#8217;s a brief setup guide to start playing with the code. First, you&#8217;re going to need to grab the latest release version of Solr (currently 1.2). [...]]]></description>
			<content:encoded><![CDATA[<div class="body">
<p>As I hinted at yesterday, I was close to having some code in the pipeline to abstract using Solr. I&#8217;ve finished the initial code with the following built in. Here&#8217;s a brief setup guide to start playing with the code.</p>
<p>First, you&#8217;re going to need to grab the latest <a href="http://www.apache.org/dyn/closer.cgi/lucene/solr/">release version of Solr (currently 1.2)</a>. The only real requirement to run this software is that you have a JRE of 1.5 or higher. Untar/zip the file somewhere convenient and open a command prompt. Get to the example directory in the apache-solr.1.2.x folder (cd /example). To start up the sample server running Jetty, just issue the following command:</p>
<div class="code">java -jar start.jar</div>
<p>This will start a new instance of the Solr server on your computer on port 8983. You can make sure this is running by navigating to <a href="http://localhost:8983/solr">http://localhost:8983/solr</a> (NOTE: this is a link to your computer. If you get an error, it&#8217;s because your computer isn&#8217;t running an instance of Solr on port 8983).</p>
<p>At this point, it&#8217;s probably good to send you over to the Solr website to take a look at <a href="http://lucene.apache.org/solr/tutorial.html">their tutorial</a>. Go ahead. I&#8217;ll wait&#8230;</p>
<p>&#8230;</p>
<p>Great, you&#8217;re back.</p>
<p>You&#8217;ve seen some basic inserting, deleting, and querying of Solr index data. You may have also noticed that there are clients for PHP, Ruby, Python, and Java&#8230;no ColdFusion. I want to do a little more testing on this before I submit the patch, but I&#8217;ve added the initial code as an encosure here to do updating, deleting, and searching in Coldfusion.</p>
<p>The CFC SolColdfusion should be in the path org/apache/client (at least that&#8217;s where I&#8217;m putting in for the purposes of this initial demonstration). The initialization takes one required parameter (the Solr host) and then has two optional parameters (port and path).</p>
<p>To set this up, create an instance with</p>
<div class="code"><span style="color: #800000;">&lt;cfset solr = createObject(<span style="color: #0000ff;">&#8220;component&#8221;</span>, <span style="color: #0000ff;">&#8220;org.apache.solr.client.SolColdfusion&#8221;</span>).init(<span style="color: #0000ff;">&#8220;<a href="http://localhost/" target="_blank">http://localhost</a>&#8220;</span>, <span style="color: #0000ff;">&#8220;8983&#8243;</span>, <span style="color: #0000ff;">&#8220;/solr&#8221;</span>) /&gt;</span></div>
<p>Now, there are a lot of different parameters you can send to Solr to perform different queries. And, since some of these key names can repeat, I chose to implement sending these parameters as an array. So, let&#8217;s set this up.</p>
<div class="code"><span style="color: #800000;">&lt;cfset params = arrayNew(<span style="color: #0000ff;">1</span>) /&gt;</span></p>
<p><span style="color: #800000;">&lt;cfset params[1][1] = <span style="color: #0000ff;">&#8220;indent&#8221;</span>&gt;</span><br />
<span style="color: #800000;">&lt;cfset params[1][2] = <span style="color: #0000ff;">&#8220;on&#8221;</span> /&gt;</span><br />
<span style="color: #800000;">&lt;cfset params[2][1] = <span style="color: #0000ff;">&#8220;wt&#8221;</span>&gt;</span><br />
<span style="color: #800000;">&lt;cfset params[2][2] = <span style="color: #0000ff;">&#8220;standard&#8221;</span> /&gt;</span><br />
<span style="color: #800000;">&lt;cfset params[3][1] = <span style="color: #0000ff;">&#8220;fl&#8221;</span> /&gt;</span><br />
<span style="color: #800000;">&lt;cfset params[3][2] = <span style="color: #0000ff;">&#8220;*,score&#8221;</span> /&gt;</span><br />
<span style="color: #800000;">&lt;cfset params[4][1] = <span style="color: #0000ff;">&#8220;qt&#8221;</span> /&gt;</span><br />
<span style="color: #800000;">&lt;cfset params[4][2] = <span style="color: #0000ff;">&#8220;standard&#8221;</span> /&gt;</span><br />
<span style="color: #800000;">&lt;cfset params[5][1] = <span style="color: #0000ff;">&#8220;wt&#8221;</span> /&gt;</span><br />
<span style="color: #800000;">&lt;cfset params[5][2] = <span style="color: #0000ff;">&#8220;standard&#8221;</span> /&gt;</span></div>
<p>These parameters are basically what are the defaults that Solr will return back to you. If you want highlighting, you would need to add two additional row vectors with &#8216;hl = on&#8217; and &#8216;hl.fl = &#8216;.</p>
<p>Searching is straight forward, taking a query, the start row, number of rows to return, and the array of parameters:</p>
<div class="code"><span style="color: #800000;">&lt;cfset results = solr.search(<span style="color: #0000ff;">&#8220;*:*&#8221;</span>,<span style="color: #0000ff;"> 0</span>,<span style="color: #0000ff;"> 10</span>, params) /&gt;</span></div>
<p>This searches all fields and all content and returns back an XML document with the search results in it.</p>
<div class="code"><span style="color: #800000;">&lt;cfdump var=<span style="color: #0000ff;">&#8220;#results#&#8221;</span> /&gt;</span></div>
<p>In the result node, you&#8217;ll see that Solr returns an xmlAttribute of</p>
<div class="code">numFound</div>
<p>of 0 (assuming you don&#8217;t have anything in the index). Let&#8217;s add an example document from the documents that come with Solr.</p>
<div class="code"><span style="color: #808080;"><em>&lt;!&#8212; Create a new sample document &#8212;&gt;</em></span><br />
<span style="color: #800000;">&lt;cfxml variable=<span style="color: #0000ff;">&#8220;sample&#8221;</span>&gt;</span><br />
<span style="color: #000080;">&lt;doc&gt;</span><br />
<span style="color: #ff8000;">&lt;field name=<span style="color: #0000ff;">&#8220;id&#8221;</span>&gt;</span>F8V7067-APL-KIT<span style="color: #ff8000;">&lt;/field&gt;</span><br />
<span style="color: #ff8000;">&lt;field name=<span style="color: #0000ff;">&#8220;name&#8221;</span>&gt;</span>Belkin Mobile Power Cord for iPod w/ Dock<span style="color: #ff8000;">&lt;/field&gt;</span><br />
<span style="color: #ff8000;">&lt;field name=<span style="color: #0000ff;">&#8220;manu&#8221;</span>&gt;</span>Belkin<span style="color: #ff8000;">&lt;/field&gt;</span><br />
<span style="color: #ff8000;">&lt;field name=<span style="color: #0000ff;">&#8220;cat&#8221;</span>&gt;</span>electronics<span style="color: #ff8000;">&lt;/field&gt;</span><br />
<span style="color: #ff8000;">&lt;field name=<span style="color: #0000ff;">&#8220;cat&#8221;</span>&gt;</span>connector<span style="color: #ff8000;">&lt;/field&gt;</span><br />
<span style="color: #ff8000;">&lt;field name=<span style="color: #0000ff;">&#8220;features&#8221;</span>&gt;</span>car power adapter, white<span style="color: #ff8000;">&lt;/field&gt;</span><br />
<span style="color: #ff8000;">&lt;field name=<span style="color: #0000ff;">&#8220;weight&#8221;</span>&gt;</span>4<span style="color: #ff8000;">&lt;/field&gt;</span><br />
<span style="color: #ff8000;">&lt;field name=<span style="color: #0000ff;">&#8220;price&#8221;</span>&gt;</span>19.95<span style="color: #ff8000;">&lt;/field&gt;</span><br />
<span style="color: #ff8000;">&lt;field name=<span style="color: #0000ff;">&#8220;popularity&#8221;</span>&gt;</span>1<span style="color: #ff8000;">&lt;/field&gt;</span><br />
<span style="color: #ff8000;">&lt;field name=<span style="color: #0000ff;">&#8220;inStock&#8221;</span>&gt;</span>false<span style="color: #ff8000;">&lt;/field&gt;</span><br />
<span style="color: #000080;">&lt;/doc&gt;</span><br />
<span style="color: #800000;">&lt;/cfxml&gt;</span></p>
<p><span style="color: #808080;"><em>&lt;!&#8212; add this document to the index &#8212;&gt;</em></span><br />
<span style="color: #800000;">&lt;cfset solr.add(sample) /&gt;</span><br />
<span style="color: #800000;">&lt;cfset solr.commit() /&gt;</span><br />
<span style="color: #800000;">&lt;cfset solr.optimize() /&gt;</span></p>
<p><span style="color: #808080;"><em>&lt;!&#8212; search for the newly added document &#8212;&gt;</em></span><br />
<span style="color: #800000;">&lt;cfset results = solr.search(<span style="color: #0000ff;">&#8220;id:F8V7067-APL-KIT&#8221;</span>,<span style="color: #0000ff;"> 0</span>,<span style="color: #0000ff;"> 10</span>, params) /&gt;</span></p>
<p><span style="color: #800000;">&lt;cfdump var=<span style="color: #0000ff;">&#8220;#xmlParse(results)#&#8221;</span> /&gt;</span></div>
<p>You&#8217;ll notice I used a commit and optmize statement. Neither of these statements are necessary every time you add a document, but be aware that Solr caches documents and won&#8217;t flush the new documents to disk unless you either commit the documents or the mergefactor setting you used in your solrconfig.xml file has been reached.</p>
<p>Now, let&#8217;s delete this document&#8230;</p>
<div class="code"><span style="color: #800000;">&lt;cfset solr.deleteById(<span style="color: #0000ff;">&#8220;F8V7067-APL-KIT&#8221;</span>) /&gt;</span><br />
<span style="color: #800000;">&lt;cfset solr.commit() /&gt;</span></div>
<p>Don&#8217;t forget to commit deletions to the index!</p>
<p>There&#8217;ll be more soon (add multiple documents, delete by queries). In the mean time, try it out. If you have any comments, questions, concerns, whatever, let me know.</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.liquidfoot.com/2007/10/04/coldfusion-solr-client-solcoldfusion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
