1 package org.paneris.bibliomania.metasearch.amazon; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.File; 5 import java.io.FileNotFoundException; 6 import java.io.IOException; 7 import java.net.URL; 8 import java.net.URLConnection; 9 import java.util.Enumeration; 10 11 import org.melati.util.IoUtils; 12 import org.melati.poem.transaction.ToTidyList; 13 import org.melati.util.UTF8URLEncoder; 14 import org.paneris.bibliomania.BookStocking; 15 import org.paneris.bibliomania.fti.StringDbHash; 16 import org.paneris.bibliomania.metasearch.BookStockingFactory; 17 import org.paneris.bibliomania.metasearch.BookshopBackend; 18 19 import com.sleepycat.db.DatabaseException; 20 21 public class Backend implements BookshopBackend { 22 23 protected final StringDbHash publisherAndImageOfISBN; 24 25 public Backend(File dbHome, int publisherAndImageOfISBNCacheSize) 26 throws FileNotFoundException, DatabaseException { 27 publisherAndImageOfISBN = 28 new StringDbHash( 29 new File(dbHome, "amazon_publisherAndImageOfISBN.db").getPath(), 30 publisherAndImageOfISBNCacheSize); 31 } 32 33 public String retrievedPublisherAndImage(BookStocking stocking) 34 throws IOException { 35 BookPage bookPage = 36 new BookPage(productPage_nonaffil(stocking), stocking.getIsbn_unsafe()); 37 38 if (bookPage.publisher == null) 39 return null; 40 41 return bookPage.image == null 42 ? bookPage.publisher 43 : bookPage.publisher + "\u00b7" + bookPage.image; 44 } 45 46 public void resolve(BookStocking stocking) { 47 if (stocking.getPublisher_unsafe() == null) { 48 String isbn = stocking.getIsbn_unsafe(); 49 String publisherAndImage = publisherAndImageOfISBN.get(isbn); 50 if (publisherAndImage == null) { 51 try { 52 publisherAndImage = retrievedPublisherAndImage(stocking); 53 } catch (IOException e) { 54 } 55 56 if (publisherAndImage == null) 57 publisherAndImage = ""; 58 59 publisherAndImageOfISBN.put(isbn, publisherAndImage); 60 publisherAndImageOfISBN.flush(); 61 } 62 63 int sep = publisherAndImage.indexOf("\u00b7"); 64 if (sep == -1) { 65 stocking.setPublisher_unsafe(publisherAndImage); 66 stocking.setThumbnailurl_unsafe(null); 67 } else { 68 stocking.setPublisher_unsafe(publisherAndImage.substring(0, sep)); 69 stocking.setThumbnailurl_unsafe(publisherAndImage.substring(sep + 1)); 70 } 71 } 72 } 73 74 public byte[] productPage_nonaffil(BookStocking stocking) 75 throws IOException { 76 return IoUtils.slurp(new URL(productURL_nonaffil(stocking)), 32768, 100000); 77 } 78 79 public String productURL_nonaffil(BookStocking stocking) { 80 return "http://www.amazon.com/exec/obidos/ASIN/" 81 + stocking.getIsbn_unsafe(); 82 } 83 84 public String productURL(BookStocking stocking) { 85 return productURL_nonaffil(stocking); 86 } 87 88 public String notifiedOfferedLinkHTML(BookStocking stocking) { 89 return ""; 90 } 91 92 byte[] searchQueryPrefixBytes = "index=books&field-power=".getBytes(); 93 byte[] authorBytes = "author:+".getBytes(); 94 byte[] titleBytes = "title:+".getBytes(); 95 byte[] andBytes = "+AND+".getBytes(); 96 97 public Enumeration booksMatching( 98 BookStockingFactory stockings, 99 String title, 100 String author, 101 String publisher, 102 String keyword, 103 ToTidyList toTidy) 104 throws IOException { 105 106 URLConnection c = 107 new URL( 108 "http://www.amazon.com/exec/obidos/search-handle-form/" 109 + "ref=s_sf_b_ps/?") 110 .openConnection(); 111 112 ByteArrayOutputStream buf = new ByteArrayOutputStream(100); 113 buf.write(searchQueryPrefixBytes); 114 115 if (author != null && !author.trim().equals("")) { 116 buf.write(authorBytes); 117 buf.write(UTF8URLEncoder.encode(author).getBytes()); 118 } 119 if (title != null && !title.trim().equals("")) { 120 if (author != null && !author.trim().equals("")) 121 buf.write(andBytes); 122 buf.write(titleBytes); 123 buf.write(UTF8URLEncoder.encode(title).getBytes()); 124 } 125 126 c.setDoOutput(true); 127 buf.writeTo(c.getOutputStream()); 128 buf.writeTo(System.err); 129 return new SearchResults( 130 IoUtils.slurp(c.getInputStream(), 65536), 131 stockings); 132 } 133 }