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 }