<?php
/*
 * LibraryThing Covers Local Cache 
 *
 * This program lets you use LibraryThing's covers without worrying about the 1000 images per day limit.
 * Every time you get a cover, it is cached on your own server. Any time you need the same cover again,
 * it is provided by your own server without bothering LibraryThing. Over time, your local cache will
 * grow to contain all of the covers in your own collection.
 *
 * ltcovers.php by Art Zemon, art@zemon.name
 * August 10, 2008
 *
 * Please let me know if you are using this program.
 *
 * This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.
 * See http://creativecommons.org/licenses/by-nc-sa/3.0/us/ for the full text of the license.
 *
 * Usage:
 *		Embed image tags in your OPAC something like this (your syntax will vary slightly, of course)
 *		<img src="http://YOUROPAC.YOURDOMAIN.ORG/ltcovers.php?size=$size&isbn=$isbn" alt="...">
 *		e.g.
 *		<img src="http://YOUROPAC.YOURDOMAIN.ORG/ltcovers.php?size=medium&isbn=9780805080438" alt="...">
 *
 *		size must be one of: small, medium, large
 *		isbn must be either 10 or 13 characters long and can contain only the digits and the letter X (or x)
 *
 * Installation:
 *		1) Copy this file to your web server
 *		2) Create a directory where all of the book covers will be stored. Enter the directory name in the TOP
 *			definition below.
 *		3) Make sure that the directory permissions allow PHP scripts to create new files.
 *		4) Enter your own LibraryThing developer key in the KEY definition below. If you do not have your own
 *			developer get, get one at http://www.librarything.com/developers.php ; it's free.
 *		5) Pick a default image to be served up if LibraryThing does not have the cover you need (or if your
 *			developer key has already been used 1000 times today). Put that image on your server and put its
 *			local file name in the DEFAULT_IMAGE definition below. 
 */
define('TOP', 'covers');
define('KEY', '651b192f66f9565697bff92a8b18d5b3');
$nocover = "/covers/blank.png";
$dbhost = "127.0.0.1:3306";
$dbuser = "root";
$dbpass = "n03ntry";
$dbname = "koha";

$debugging = ($_REQUEST['debug'] == 'on');

/*
 * ================= change nothing below this line =================
 */
if ($debugging) {
	header("Content-type: text/html");
	print "<h1>Debugging output</h1>";
}

if (isset($_REQUEST['biblio'])) {
        // Connect to the database - the connection will be reused later if we try to update the Biblio
        mysql_connect($dbhost, $dbuser, $dbpass) or die                      ('Error connecting to mysql');
        mysql_select_db($dbname);

        // Now, see if there's anything interesting in there

        $result = mysql_query("SELECT coverlocation FROM bibliocovers WHERE biblionumber=".$_REQUEST['biblio']);
        if (mysql_num_rows($result) > 0) {
                $coverlocation = mysql_result($result, 0);
		if ((strlen($coverlocation) > 4) && ((file_exists(".".$coverlocation)) || (substr($coverlocation, 0, 4) == "http"))) {
                       	if ($debugging) print "<p>Found a cached item location! Serving it up from: $coverlocation";
			header("Location: $coverlocation");
               	        exit;
		} // if the file *doesn't* exist, it might be an amazon image!
        } ;
} 

$size = strtolower($_REQUEST['size']);
if ('small' != $size && 'medium' != $size && 'large' != $size) {
	if ( $debugging) print "<p>Illegal size - setting to medium</p>";
	$size = 'medium';
}

$isbn = $_REQUEST['isbn'];
$isbnExplosion = explode(" ", $isbn);
$isbn = strtoupper(preg_replace('/[^0-9Xx]/', '', $isbnExplosion[0]));	// remove everything except digits and "X"

if (10 != strlen($isbn) && 13 != strlen($isbn)) {
	if ($debugging) print "<p>Illegal ISBN: --".$isbn."--</p><p>Have an empty png instead...</p>";
	header("Location: $nocover");
	updateDB("none");
	exit;
}

if (strlen($isbn) == 13) {
	$isbn = substr($isbn,3,9);
	$checksum = 0;
	$weight = 10;
	$isbnCharArray = str_split($isbn);
	foreach($isbnCharArray as $char) {
		$checksum += $char * $weight;
	   $weight--;
	}
	$checksum = 11-($checksum % 11);
	if ($checksum == 10) {
		$isbn += "X";
	} else if ($checksum == 11) {
		$isbn += "0";
	} else {
		$isbn .= $checksum;
	}
	if ($debugging) print "<p>Got a new isbn of ".$isbn."</p>";
}

// Fall back to a manual search of the ISBN 	
$imageFile = getDirectory($isbn)."${isbn}.jpg";

if (file_exists(TOP."/openlibrary".$imageFile)) {
	if ($debugging) print "<p>Serving from openlibrary archive: ".TOP."/openlibrary".$imageFile."</p>";
	updateDB("/".TOP."/openlibrary".$imageFile);
	outputImageFile(TOP."/openlibrary".$imageFile);
	exit;
} else if (file_exists(TOP."/librarything".$imageFile)) {
	if ($debugging) print "<p>Serving from librarything archive: ".TOP."/librarything".$imageFile."</p>";
	updateDB("/".TOP."/librarything".$imageFile);
	outputImageFile(TOP."/librarything".$imageFile);
	exit;
}


// At this point, we haven't found an image :( - so we make one! :)
$olUrl = 'http://covers.openlibrary.org/b/isbn/' . $isbn . "-".strtoupper(substr($size,0,1)).".jpg";
if ($debugging) print "<p>We don't have a local copy. Trying to fetch the image from $olUrl</p>\n";
if ($remote = fopen($olUrl, 'r') )
{
	$image = '';
	while ( ! feof($remote) )
		$image .= fread($remote, 8192);
	fclose($remote);

	if (isValidImage($image)) {
		if ($debugging) print "Serving from OpenLibrary";	
		saveAndOutput($image, TOP."/openlibrary".$imageFile);
		exit;
	}
}

$ltUrl = 'http://covers.librarything.com/devkey/' . KEY . "/$size/isbn/$isbn";
if ($debugging) print "<p>We don't have a local copy. Trying to fetch the image from $ltUrl</p>\n";
if ($remote = fopen($ltUrl, 'r') )
{
	$image = '';
	while ( ! feof($remote) )
		$image .= fread($remote, 8192);
	fclose($remote);

	if (isValidImage($image)) {
		if ($debugging) print "Serving from LibraryThing";
		saveAndOutput($image, TOP."/librarything".$imageFile);
		exit;
	}
}

$amUrl = 'http://images.amazon.com/images/P/' . $isbn . '.01.MMZZZZZZ.jpg';
if ($debugging) print "<p>Trying to get an amazon image frin $amUrl</p>\n";
if ($remote = fopen($amUrl, 'r') ) {
	$image = '';
	while ( ! feof($remote) )
		$image .= fread($remote, 8192);
	fclose($remote);
	if (isValidImage($image)) {
		updateDB($amUrl);
		if ($debugging) print "Serving from Amazon";
		header("Content-Type: image/jpeg");
		header("Content-Length: " . strlen($image));
		header("X-Pad: avoid browser bug");
		print $image;
		exit;
	}
}

if ($debugging) print "<p>Well, this is embarressing. I can't find anything. So I'll put up a blank image.</p>";	
header("Location: $nocover");
updateDB("none");
exit;


	function isValidImage($image) {
		return ((strlen($image) > 807) && (substr($image, 0, 5) != "<html"));
	}

	function saveAndOutput($imageData, $imageFile) {
		global $debugging;
		makeDirectory($imageFile, $debugging);
		if ($debugging) print "<p>Saving to ${imageFile}</p>";
		$local = fopen($imageFile, 'w');
		fwrite($local, $imageData);
		fclose($local);
		if ($debugging) {print "Going to run updateDB($imageFile);"; }
		updateDB("/".$imageFile);
                if ($debugging) {
                        print "<p>Now serving image</p>\n\n";
                } else {
                        header("Content-Type: image/jpeg");
                        header("Content-Length: " . strlen($imageData));
                        header("X-Pad: avoid browser bug");
                }
                print $imageData;
	}

	function outputImageFile($imageToServe) {
		global $debugging;
		if ($debugging) { 
			print "<p>Now serving image $imageToServe of size " . filesize($imageToServe) . "</p>\n\n"; }
		else {
			header("Content-Type: image/jpeg");
			header("Content-Length: " . filesize($imageToServe));
			header("X-Pad: avoid browser bug");
		}
		readfile($imageToServe);
	}

	function getDirectory($isbn) {
		global $debugging;
		$parts = Array(substr($isbn, 0, 3), substr($isbn, 3, 3), substr($isbn, 6, 3), substr($isbn, 9, 3));
                if (13 == strlen($isbn))
                        array_push($parts, substr($isbn, 12, 3));
                $dirName = join('/', $parts);
                return "/".$dirName;
	}

	function makeDirectory($imageFile) {
		global $debugging;
		$path = dirname($imageFile);
		return mkdir($path, 0777, true);
	}

	function updateDB($imageLocation) {
		global $debugging;
		global $dbhost, $dbuser, $dbpass, $dbname;
                if (isset($_REQUEST['biblio'])) {
		        mysql_connect($dbhost, $dbuser, $dbpass) or die                      ('Error connecting to mysql');
		        mysql_select_db($dbname);

                        $biblio = mysql_real_escape_string($_REQUEST['biblio']);
                        $imageLocation = mysql_real_escape_string($imageLocation);
                        $sqlUpdate = "INSERT INTO bibliocovers (biblionumber, coverlocation) VALUES ($biblio, '$imageLocation') ON DUPLICATE KEY UPDATE coverlocation='$imageLocation'";
                        if ($debugging) { print "<p>Trying to do the following query: $sqlUpdate </p>"; }
                        mysql_query($sqlUpdate);
                }
	}

?>
