Amazon Vancouver Island Regional Library Linky

By Stv. Last update Oct 19, 2009 — Installed 34 times.
// ==UserScript==
// @name          Amazon Vancouver Island Regional Library Linky
// @namespace     http://tannock.net
// @description	  v1.5 Search the Vancouver Public Library Catalog from Amazon book listings.  
// @include       http://*.amazon.*
// ==/UserScript==

//updated to loop over a main array of Library Codes, each assigned a status.

// trivial modification of script by http://fatknowledge.blogspot.com: http://userscripts.org/scripts/show/8432

// Based on work by Carrick Mundell http://userscripts.org/scripts/show/1396

(function(){
//	GM_log('Amazon Vancouver Public Library Linky');	
 
	var libraryIsbnUrlPattern = 'http://hip.virl.bc.ca/ipac20/ipac.jsp?index=ISBNEX&term='
	var libraryTitleUrlPattern = 'http://hip.virl.bc.ca/ipac20/ipac.jsp?index=.TW&term='
	var libraryName = 'the Vancouver Island Regional Library';
	var IsbnLookupUrl = 'http://xisbn.worldcat.org/webservices/xid/isbn/'

	var isbn = getIsbn(window.content.location.href);
	
	var isbns = new Array();
	var isbnsIndex = -1;
	var foundCount = 0;

	var codeArray = [
		['BEING HELD','bad']
		,['BINDERY','bad']
		,['CATALOGUING BINDERY','bad']
		,['CHECKED OUT','bad']
		,['CLAIMS RETURNED','bad']
		,['DAMAGED','bad']
		,['DISPLAY','bad']
		,['HOLIDAY','bad']
		,['IN CATALOGUING','bad']
		,['IN MENDS','bad']
		,['IN PROCESS','bad']
		,['IN TRANSIT','bad']
		,['INFORMATION','good']
		,['LOST\/DAMAGED','bad']
		,['MISSING','bad']
		,['NEWLY ACQUIRED','bad']
		,['ON ORDER','bad']
		,['STORAGE','bad']
		,['STORYTIME','bad']
		,['TRACE','bad']
		,['WORKROOM','bad']
		,['IN','good']
	];

	if (isbn!=0){
		createStatusAndLibraryHTML();
		updateStatusHTML('Searching ' + libraryName + '...');

		getStatusAllISBNs(isbn);
	}
	return;


//get all ISBNs for this book and write to global var isbns
//then call getBookStatuses
function getStatusAllISBNs(isbn) {
	var wbUrl = IsbnLookupUrl + isbn;
	GM_xmlhttpRequest({
	    method: 'GET',
	    url: wbUrl,
	    headers: {
	        'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey/0.3',
	        'Accept': 'application/atom+xml,application/xml,text/xml',
	    },
	    onload: function(responseDetails) {
//			GM_log(responseDetails.responseText);	
	        var parser = new DOMParser();
	        var dom = parser.parseFromString(responseDetails.responseText,
	            "application/xml");

	        var isbnsDom = dom.getElementsByTagName('isbn');
	        for (var i = 0; i < isbnsDom.length; i++){
				isbns[i] = isbnsDom[i].textContent;
			}
			getBookStatuses();
	        
	    }
	});	
}

//loop through all the isbns
//this gets called back after each search to do next isbn
function getBookStatuses(){
	isbnsIndex++;
//	GM_log("getBookStatuses"+isbnsIndex+ " " + isbns.length);

	if (isbnsIndex < isbns.length){
		updateStatusHTML("Searching for ISBN "+ isbns[isbnsIndex] + " in " + libraryName + '...');
		getBookStatus(libraryIsbnUrlPattern, isbns[isbnsIndex]);
	//when done going through isbns, update the status
	} else {
		if (foundCount==0){
			setStatusNoneFound();
		} else if (foundCount==1){
			removeStatus();
		} else {
			setStatusColor("black");
			updateStatusHTML(foundCount+ ' versions found:');
		}
	}
}


//connect to library server to get book status for isbn and then insert result under the book title
//call getBookStatuses when done
function getBookStatus(libraryUrlPattern, isbn){
//	GM_log('Searching: '+libraryUrlPattern);
	var stringColor = "";
	var foundItem = false;
		
	GM_xmlhttpRequest
		({
		method:'GET',
		url: libraryUrlPattern + isbn,
		onload:function(results) {
			page = results.responseText;
			for (var i=0, len=codeArray.length; i<len; ++i) {
				var myString = new RegExp("<a([^>]*)>" + codeArray[i][0] + "</a>","i");
				if(myString.test(page)) {
					foundItem = true;
					if (codeArray[i][1] == 'bad')
						stringColor = "red";
					else
						stringColor = "green";
					setLibraryHTML(
						libraryUrlPattern, isbn,
						codeArray[i][0],
						codeArray[i][0] + " at " + libraryName,
						stringColor);
					foundCount++;
					getBookStatuses();
				}
			}	
		}
	});
}



function createStatusAndLibraryHTML() {
	var title_node = getTitleNode();
	var h1_node = title_node.parentNode;
	var br = document.createElement('br');

	//the div for library status when found
	var splLinkyDiv = document.createElement('div');
	splLinkyDiv.id = 'splLinkyLibraryHTML';
	//resize to 60% to get out of the enlarged h1 size and return back to normal
	splLinkyDiv.style.fontSize = '60%';
	splLinkyDiv.style.color = 'black';

	//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.
	h1_node.insertBefore(splLinkyDiv, title_node.nextSibling);
	h1_node.insertBefore(br, title_node.nextSibling);

	//the div for status as checks are occuring
	var splStatusDiv = document.createElement('div');
	splStatusDiv.id = 'splLinkyStatusHTML';
	//resize to 60% to get out of the enlarged h1 size and return back to normal
	splStatusDiv.style.fontSize = '60%';
	splStatusDiv.style.color = 'brown';

	h1_node.insertBefore(splStatusDiv, splLinkyDiv);
//	h1_node.insertBefore(br, title_node.nextSibling);

}


function updateStatusHTML(text) {
	var splStatusDiv = document.getElementById('splLinkyStatusHTML');
	if (splStatusDiv == null) { return; }

	if (splStatusDiv.firstChild){
		splStatusDiv.removeChild(splStatusDiv.firstChild);
	}
	splStatusDiv.appendChild(document.createTextNode(text));
}

//add status of book below previous ones
function setLibraryHTML(libraryUrlPattern, isbn, title, linktext, color) {
	var splLinkyDiv = document.getElementById('splLinkyLibraryHTML');
	if (splLinkyDiv == null) { return; }

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

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

	//append to existing content
	splLinkyDiv.appendChild(link);
	splLinkyDiv.appendChild(document.createElement('br'));
}

//none found
//add link to search by title
function setStatusNoneFound() {
	var title = getTitle();
	var splStatusDiv = document.getElementById('splLinkyStatusHTML');
	if (splStatusDiv == null) { return; }

	var link = document.createElement('a');
	link.setAttribute('title', title );
	link.setAttribute('href', libraryTitleUrlPattern +encodeURIComponent(title));
	link.setAttribute('target', "_blank");
	link.style.color = "red";

	var label = document.createTextNode('Not found. Search by title in ' + libraryName + '...' );
	link.appendChild(label);

	var link2 = document.createElement('a');
	link2.setAttribute('title', title );
	link2.setAttribute('href', libraryIsbnUrlPattern +encodeURIComponent(isbn));
	link2.setAttribute('target', "_blank");
	link2.style.color = "red";

	var label2 = document.createTextNode(' Or search by ISBN in ' + libraryName + '...' );
	link2.appendChild(label2);

	//remove existing content
	splStatusDiv.removeChild(splStatusDiv.firstChild);
	splStatusDiv.appendChild(link);
	splStatusDiv.appendChild(document.createElement('br'));
	splStatusDiv.appendChild(link2);
}

function setStatusColor(color){
	var splStatusDiv = document.getElementById('splLinkyStatusHTML');
	if (splStatusDiv == null) { return; }

	splStatusDiv.style.color = color;

}

function removeStatus(){
	var splStatusDiv = document.getElementById('splLinkyStatusHTML');
	splStatusDiv.removeChild(splStatusDiv.firstChild);
}


//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 getIsbn(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;
}

function getTitle(){
	var title = getTitleNode();
	if (title==null) { return null; }

	//remove words in parentheses and subtitles (anything after a colon)
	return title.textContent.replace(/\(.+\)/, '').replace(/:.*/, '')
}

// Find the node containing the book title
function getTitleNode()
{
	var titleNodeId = 'btAsinTitle';

	var nodes = document.evaluate("//span[@id='" + titleNodeId + "']", document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
	if(!nodes){
		return null;
	}

	var thisNode = nodes.iterateNext(); 
	var titleNode;
	// Get the last node
	while(thisNode){
		//GM_log( thisNode.textContent );
		titleNode = thisNode;
		thisNode = nodes.iterateNext();
	}

	if (titleNode == null) {
        GM_log("can't find title node");
		return null;
	} else {
       // GM_log("Found title node: " + titleNode.textContent);
	}
	return titleNode;
}


}
)();