Amazon Washington County Public Library Linky

By Rudi Pittman Last update Nov 30, 2007 — Installed 69 times. Daily Installs: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0
// ==UserScript==
// @name          Amazon Washington County Public Library Linky
// @namespace     
// @description	  v1.0 Search the Washington County Public Library Catalog from Amazon book listings.  
// @include       http://*.amazon.*
// ==/UserScript==

// Based on work by Carrick Mundell http://userscripts.org/scripts/show/1396
// Now handles the case where books are on hold


(function(){
//	GM_log('Amazon Washington County Public Library Linky');	
 
	var libraryUrlPattern = 'http://www.wccls.org/polaris/search/searchresults.aspx?ctx=1.1033.0.0.1&type=Keyword&term='
        var libraryUrlPattern2 = '&by=ISBN&sort=TI_PD&limit=TOM=*&query=&page=0'
	var libraryName = 'the Washington County Public Library';

	var isbn = get_isbn(window.content.location.href);
	if (isbn==0) { return;}
	else { getBookStatus(isbn); }


//check if there is a ISBN in the URL
//URL looks like http://www.amazon.com/Liseys-Story-Stephen-King/dp/0743289412/ref=xarw/002-5799652-4968811
function get_isbn(url){
	try { 
		//match if there is a / followed by a 7-9 digit number followed by either another number or an x 
		//followed by a / or end of url 
		var isbn = url.match(/\/(\d{7,9}[\d|X])(\/|$)/)[1]; 
	} catch (e) { return 0; }

	return isbn;
}

//connect to library server to get book status for isbn and then insert result under the book title
function getBookStatus(isbn){
	GM_log('Amazon Washington County Public Library Linky Searching');	

	var libraryAvailability = / In /;
	var libraryOnOrder = /On-Order/;
	var libraryInProcess = /In-Process/;
	var libraryDueBack = /(\d{2}\/\d{2}\/\d{4})/;
	var libraryHolds = /Held/;
        var libraryTransit = /In-Transit/;

	var notFound = /No titles found/;

	GM_xmlhttpRequest
		({
		method:'GET',
		url: libraryUrlPattern + isbn + libraryUrlPattern2,
		onload:function(results) {
			page = results.responseText;
			if ( notFound.test(page) )
				{
				var due = page.match(notFound)[1]
				setLibraryHTML(
					isbn,
					"Not carried",
					"Not in " + libraryName,
					"red"
					);
				}
			//if there are holds
			else if ( libraryHolds.test(page) ) {
				
				setLibraryHTML(
					isbn,
					"Holds!",
					"Held at " + libraryName,
					"#AA7700"  // dark yellow
					);
			}
			else if ( libraryAvailability.test(page) )
				{
				setLibraryHTML(
					isbn,
					"On the shelf now!",
					"Available in " + libraryName,
					"green" 
					);
				}
			else if ( libraryOnOrder.test(page) )
				{
				setLibraryHTML(
					isbn,
					"On order!",
					"On order at " + libraryName,
					"#AA7700"  // dark yellow
					);
				}                    
			else if ( libraryInProcess.test(page) )
				{
				setLibraryHTML(
					isbn,
					"In process!",
					"In process (available soon) at ",
					"#AA7700"  // dark yellow
					);
				}                    
                        else if ( libraryTransit.test(page) )
				{
				setLibraryHTML(
					isbn,
					"Transit Request!",
					"Transit Request at " + libraryName,
					"#AA7700"  // dark yellow
					);
				}                     
			else if ( libraryDueBack.test(page) )
				{
				var due = page.match(libraryDueBack)[1]
				setLibraryHTML(
					isbn,
					"Due back " + due,
					"Due back at " + libraryName + " on " + due,
					"#AA7700"  // dark yellow
					);
				}
			else
				{
				setLibraryHTML(
					isbn,
					"Unknown Status",
					"Unknown Status or Not Found at " + libraryName,
					"orange"
					);
				}
			}
		});
}

//print status of book below book title
function setLibraryHTML(isbn, title, linktext, color) {
	GM_log(linktext);	

	var titleNode = getBookTitleNode();
	var div = titleNode.parentNode;

	var br = document.createElement('br');

	var link = document.createElement('a');
	link.setAttribute('title', title );
	link.setAttribute('href', libraryUrlPattern + isbn + libraryUrlPattern2);
	link.setAttribute('style','color: ' + color);

	var label = document.createTextNode( linktext );
	link.appendChild(label);

	//How lame is this javascript DOM syntax?  Instead of having an insertAfter function, you have an insertBefore
	//and then pass in the .nextSibling attribute of the element.  Really inuitive guys.
	div.insertBefore(link, titleNode.nextSibling);
	div.insertBefore(br, titleNode.nextSibling);
}

//find the node associated with the title of the book
//currently this is done by getting all objects that are <b class="sans"> and then taking the last one
function getBookTitleNode(){
	//find all node objects that are <b class="sans">
	var iterator = document.evaluate("//b[@class='sans']", document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );

	//get the last node
	try {
	  var thisNode = iterator.iterateNext();
	  
	  while (thisNode) {
	//    GM_log( thisNode.textContent );
		titleNode = thisNode;
		thisNode = iterator.iterateNext();
	  }	

	} catch (e) {
	  dump( 'Error: Document tree modified during iteraton ' + e );
	}

    //if there was only one instance of <b class='sans'> you could use this code
    //var titleNode = document.evaluate("count(//b[@class='sans'])", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;

	if ( !titleNode)  {GM_log("can't find title node"); return; }
	return titleNode;
}

}
)();