remote_book 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/Gemfile +10 -0
- data/README.rdoc +38 -0
- data/Rakefile +6 -0
- data/VERSION +1 -0
- data/lib/remote_book.rb +35 -0
- data/lib/remote_book/amazon.rb +89 -0
- data/lib/remote_book/barnes_and_noble.rb +46 -0
- data/lib/remote_book/base.rb +31 -0
- data/remote_book.gemspec +36 -0
- data/spec/fixtures/amazon_1433506254.xml +1 -0
- data/spec/lib/amazon_spec.rb +21 -0
- data/spec/lib/barnes_and_noble_spec.rb +16 -0
- data/spec/spec_helper.rb +30 -0
- data/tasks/spec.rake +33 -0
- metadata +78 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
= RemoteBook
|
2
|
+
|
3
|
+
RemoteBook is a gem for creating affiliate links to Amazon & B&N for books.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
It's a gem. Either run `gem install remote_book` at the command line, or add `gem 'remote_book'` to your Gemfile.
|
8
|
+
|
9
|
+
== Usage
|
10
|
+
|
11
|
+
Get your affiliate digits:
|
12
|
+
|
13
|
+
https://affiliate-program.amazon.com/
|
14
|
+
http://affiliates.barnesandnoble.com/ - sign up with LinkShare, wonder why Amazon is more popular
|
15
|
+
|
16
|
+
for rails, add something like this to an initializer
|
17
|
+
|
18
|
+
RemoteBook::Amazon.associate_keys = {:associates_id => "me",
|
19
|
+
:key_id => "digits",
|
20
|
+
:secret_key => "secret_digits"}
|
21
|
+
|
22
|
+
RemoteBook::BarnesAndNoble.associate_keys = {:web_service_token => "token"}
|
23
|
+
To get the token, login to LinkShare, Links => Web Services (something like: http://cli.linksynergy.com/cli/publisher/links/webServices.php)
|
24
|
+
|
25
|
+
Right now it just searches by ISBN, so:
|
26
|
+
|
27
|
+
a = RemoteBook::Amazon.find_by_isbn("somedigits")
|
28
|
+
a.large_image
|
29
|
+
a.medium_image
|
30
|
+
a.small_image
|
31
|
+
a.link
|
32
|
+
a.author
|
33
|
+
a.title
|
34
|
+
|
35
|
+
b = RemoteBook::BarnesAndNoble.find_by_isbn("digits")
|
36
|
+
b.link
|
37
|
+
|
38
|
+
Barnes And Noble's LinkShare api isn't really much of an API, so all the BN class returns is a link. The Barnes And Noble API is very slow, everything returned from these classes should be cached on your end. You have been warned.
|
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/remote_book.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "uri"
|
3
|
+
require "net/http"
|
4
|
+
require "openssl"
|
5
|
+
require "typhoeus"
|
6
|
+
require "nokogiri"
|
7
|
+
|
8
|
+
require "remote_book/base"
|
9
|
+
require "remote_book/amazon"
|
10
|
+
require "remote_book/barnes_and_noble"
|
11
|
+
|
12
|
+
module RemoteBook
|
13
|
+
VERSION = File.read(File.dirname(__FILE__) + "/../VERSION").chomp
|
14
|
+
|
15
|
+
def self.get_url(url, options = {:read_timeout => 2, :open_timeout => 2})
|
16
|
+
uri = URI.parse(url)
|
17
|
+
|
18
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
19
|
+
http.read_timeout = options[:read_timeout]
|
20
|
+
http.open_timeout = options[:open_timeout]
|
21
|
+
# this return structure is pretty ugly
|
22
|
+
begin
|
23
|
+
res = http.start { |web|
|
24
|
+
g = Net::HTTP::Get.new(uri.request_uri)
|
25
|
+
web.request(g)
|
26
|
+
}
|
27
|
+
rescue Timeout::Error
|
28
|
+
return {:body => "error: timeout", :status => :error}
|
29
|
+
rescue Exception => e
|
30
|
+
return {:body => "error: #{e}", :status => :error}
|
31
|
+
else
|
32
|
+
return res
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module RemoteBook
|
2
|
+
class Amazon < RemoteBook::Base
|
3
|
+
attr_accessor :large_image, :medium_image, :small_image, :authors, :title, :isbn, :digital_link
|
4
|
+
|
5
|
+
# FIXME: failed digest support should raise exception.
|
6
|
+
# mac os 10.5 does not ship with SHA256 support built into ruby, 10.6 does.
|
7
|
+
DIGEST_SUPPORT = ::OpenSSL::Digest.constants.include?('SHA256') || ::OpenSSL::Digest.constants.include?(:SHA256)
|
8
|
+
DIGEST = ::OpenSSL::Digest::Digest.new('sha256') if DIGEST_SUPPORT
|
9
|
+
|
10
|
+
def self.find(options)
|
11
|
+
a = new
|
12
|
+
# unless DIGEST_SUPPORT raise "no digest sup"
|
13
|
+
if options[:isbn]
|
14
|
+
req = build_isbn_lookup_query(options[:isbn])
|
15
|
+
response = RemoteBook.get_url(req)
|
16
|
+
|
17
|
+
if response.respond_to?(:code) && "200" == response.code
|
18
|
+
xml_doc = Nokogiri.XML(response.body)
|
19
|
+
else
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
|
23
|
+
if 1 == xml_doc.xpath("//xmlns:Items").size
|
24
|
+
if xml_doc.xpath("//xmlns:Items/xmlns:Item/xmlns:LargeImage/xmlns:URL")
|
25
|
+
a.large_image = xml_doc.xpath("//xmlns:Items/xmlns:Item/xmlns:LargeImage/xmlns:URL").inner_text
|
26
|
+
end
|
27
|
+
if xml_doc.xpath("//xmlns:Items/xmlns:Item/xmlns:MediumImage/xmlns:URL")
|
28
|
+
a.medium_image = xml_doc.xpath("//xmlns:Items/xmlns:Item/xmlns:MediumImage/xmlns:URL").inner_text
|
29
|
+
end
|
30
|
+
if xml_doc.xpath("//xmlns:Items/xmlns:Item/xmlns:SmallImage/xmlns:URL")
|
31
|
+
a.small_image = xml_doc.xpath("//xmlns:Items/xmlns:Item/xmlns:SmallImage/xmlns:URL")
|
32
|
+
end
|
33
|
+
a.title = xml_doc.xpath("//xmlns:Items/xmlns:Item/xmlns:ItemAttributes/xmlns:Title").inner_text
|
34
|
+
a.authors = []
|
35
|
+
xml_doc.xpath("//xmlns:Items/xmlns:Item/xmlns:ItemAttributes/xmlns:Author").each do |author|
|
36
|
+
a.authors << author.inner_text
|
37
|
+
end
|
38
|
+
# ewww
|
39
|
+
if xml_doc.xpath("//xmlns:Items/xmlns:Item/xmlns:ItemLinks/xmlns:ItemLink/xmlns:Description='Technical Details'")
|
40
|
+
xml_doc.xpath("//xmlns:Items/xmlns:Item/xmlns:ItemLinks/xmlns:ItemLink").each do |item_link|
|
41
|
+
if "Technical Details" == item_link.xpath("xmlns:Description").inner_text
|
42
|
+
a.link = item_link.xpath("xmlns:URL").inner_text
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
return a
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def self.build_isbn_lookup_query(item_id)
|
53
|
+
base = "http://ecs.amazonaws.com/onca/xml"
|
54
|
+
query = "Service=AWSECommerceService&"
|
55
|
+
query << "AWSAccessKeyId=#{associate_keys[:key_id]}&"
|
56
|
+
query << "AssociateTag=#{associate_keys[:associates_id]}&"
|
57
|
+
query << "Operation=ItemLookup&"
|
58
|
+
query << "ItemId=#{item_id}&"
|
59
|
+
query << "ResponseGroup=ItemAttributes,Offers,Images&"
|
60
|
+
# query << "ResponseGroup=ItemAttributes&"
|
61
|
+
query << "Version=2009-07-01"
|
62
|
+
sig_query = sign_query base, query, associate_keys[:secret_key]
|
63
|
+
base + "?" + sig_query
|
64
|
+
end
|
65
|
+
# most of this is from http://www.justinball.com/2009/09/02/amazon-ruby-and-signing_authenticating-your-requests/
|
66
|
+
# which is actually from the ruby-aaws gem
|
67
|
+
def self.sign_query(uri, query, amazon_secret_access_key = "", locale = :us)
|
68
|
+
uri = URI.parse(uri)
|
69
|
+
# only add current timestamp if it's not in the query, a timestamp passed in via query takes precedence
|
70
|
+
# I'm only doing this so the checksum comes out correctly with the example from the amazon documentation
|
71
|
+
query << "&Timestamp=#{Time.now.utc.strftime('%Y-%m-%dT%H:%M:%SZ')}" unless query.include?("Timestamp")
|
72
|
+
new_query = query.split('&').collect{|param| "#{param.split('=')[0]}=#{url_encode(param.split('=')[1])}"}.sort.join('&')
|
73
|
+
to_sign = "GET\n%s\n%s\n%s" % [uri.host, uri.path, new_query]
|
74
|
+
# step 7 of http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?rest-signature.html
|
75
|
+
hmac = OpenSSL::HMAC.digest(DIGEST, amazon_secret_access_key, to_sign)
|
76
|
+
base64_hmac = [hmac].pack('m').chomp
|
77
|
+
signature = url_encode(base64_hmac)
|
78
|
+
|
79
|
+
new_query << "&Signature=#{signature}"
|
80
|
+
end
|
81
|
+
|
82
|
+
# Shamelessly plagiarised from Wakou Aoyama's cgi.rb, but then altered slightly to please AWS.
|
83
|
+
def self.url_encode(str)
|
84
|
+
str.gsub( /([^a-zA-Z0-9_.~-]+)/ ) do
|
85
|
+
'%' + $1.unpack( 'H2' * $1.bytesize ).join( '%' ).upcase
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module RemoteBook
|
2
|
+
class BarnesAndNoble < RemoteBook::Base
|
3
|
+
ISBN_SEARCH_BASE_URI = "http://search.barnesandnoble.com/booksearch/isbnInquiry.asp?ISBSRC=Y&ISBN="
|
4
|
+
LINK_SHARE_DEEP_LINK_BASE = "http://getdeeplink.linksynergy.com/createcustomlink.shtml"
|
5
|
+
BN_LINK_SHARE_MID = "36889"
|
6
|
+
|
7
|
+
def self.find(options)
|
8
|
+
b = new
|
9
|
+
if options[:isbn]
|
10
|
+
bn_page = barnes_and_noble_page_link_for(options[:isbn])
|
11
|
+
return nil unless bn_page
|
12
|
+
|
13
|
+
b.link = link_share_deep_link_for(bn_page)
|
14
|
+
end
|
15
|
+
b
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def self.build_isbn_lookup_query(isbn)
|
20
|
+
ISBN_SEARCH_BASE_URI + isbn
|
21
|
+
end
|
22
|
+
# pass the ISBN to the search service, read the redirect information, and use that as store link
|
23
|
+
def self.barnes_and_noble_page_link_for(isbn)
|
24
|
+
search_path = build_isbn_lookup_query(isbn)
|
25
|
+
response = RemoteBook.get_url(search_path, :read_timeout => 6, :open_timeout => 4)
|
26
|
+
if response.respond_to?(:each_header)
|
27
|
+
response.each_header do |name, value|
|
28
|
+
return value if "location" == name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
false
|
32
|
+
end
|
33
|
+
# based on a pdf linked at the bottom of this page: http://helpcenter.linkshare.com/publisher/questions.php?questionid=61
|
34
|
+
# direct pdf link (working 20 aug 2011):
|
35
|
+
# http://helpcenter.linkshare.com/publisher/getattachment.php?data=NjF8QXV0b21hdGVkIExpbmtHZW5lcmF0b3IgMi4xLS1NYXkgMjAxMS5wZGY%3D
|
36
|
+
def self.link_share_deep_link_for(url)
|
37
|
+
token = associate_keys[:web_service_token]
|
38
|
+
deep_link_lookup = LINK_SHARE_DEEP_LINK_BASE + "?token=" + token + "&mid=" + BN_LINK_SHARE_MID + "&murl=" + url
|
39
|
+
a = RemoteBook.get_url(deep_link_lookup, :read_timeout => 6, :open_timeout => 4)
|
40
|
+
if a.response.respond_to?(:code) && "200" == a.response.code
|
41
|
+
return a.response.body
|
42
|
+
end
|
43
|
+
return nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module RemoteBook
|
2
|
+
class Base
|
3
|
+
attr_accessor :link, :isbn
|
4
|
+
|
5
|
+
def author
|
6
|
+
@authors.join(", ")
|
7
|
+
end
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def associate_keys
|
11
|
+
@@associate_keys ||= {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def associate_keys=(obj)
|
15
|
+
@@associate_keys = obj
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup
|
19
|
+
yield self
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_by_isbn(isbn)
|
23
|
+
find(:isbn => isbn)
|
24
|
+
end
|
25
|
+
|
26
|
+
def find(options)
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/remote_book.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "remote_book"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "remote_book"
|
7
|
+
s.version = RemoteBook::VERSION
|
8
|
+
s.authors = ["Seth Faxon"]
|
9
|
+
s.email = ["seth.faxon@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/sfaxon/remote_book"
|
11
|
+
s.summary = %q{Pull book affiliate links and images from Amazon, Barns & Noble}
|
12
|
+
s.description = %q{Pull book affiliate links and images from Amazon, Barns & Noble}
|
13
|
+
|
14
|
+
s.rubyforge_project = "remote_book"
|
15
|
+
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
|
25
|
+
if s.respond_to? :specification_version then
|
26
|
+
s.specification_version = 3
|
27
|
+
|
28
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
29
|
+
s.add_runtime_dependency(%q<nokogiri>)
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<nokogiri>)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
s.add_dependency(%q<nokogiri>)
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<?xml version="1.0" ?><ItemLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2009-07-01"><OperationRequest><HTTPHeaders><Header Name="UserAgent" Value="Typhoeus - http://github.com/dbalatero/typhoeus/tree/master"></Header></HTTPHeaders><RequestId>463d3e16-ef6a-4ed0-b4f5-300b26e1aad7</RequestId><Arguments><Argument Name="Operation" Value="ItemLookup"></Argument><Argument Name="Service" Value="AWSECommerceService"></Argument><Argument Name="Signature" Value="usV9ajvcYWKBk4NWIS7STUtvelKgBlWJGGxWhQAhIGQ="></Argument><Argument Name="AssociateTag" Value="theresurgence-20"></Argument><Argument Name="Version" Value="2009-07-01"></Argument><Argument Name="ItemId" Value="1433506254"></Argument><Argument Name="AWSAccessKeyId" Value="1A7ETSHYVGJVYADTM6G2"></Argument><Argument Name="Timestamp" Value="2011-08-20T03:56:30Z"></Argument><Argument Name="ResponseGroup" Value="ItemAttributes,Offers,Images"></Argument></Arguments><RequestProcessingTime>0.0422470000000000</RequestProcessingTime></OperationRequest><Items><Request><IsValid>True</IsValid><ItemLookupRequest><Condition>New</Condition><DeliveryMethod>Ship</DeliveryMethod><IdType>ASIN</IdType><MerchantId>Amazon</MerchantId><OfferPage>1</OfferPage><ItemId>1433506254</ItemId><ResponseGroup>ItemAttributes</ResponseGroup><ResponseGroup>Offers</ResponseGroup><ResponseGroup>Images</ResponseGroup><ReviewPage>1</ReviewPage><ReviewSort>-SubmissionDate</ReviewSort><VariationPage>All</VariationPage></ItemLookupRequest></Request><Item><ASIN>1433506254</ASIN><DetailPageURL>http://www.amazon.com/Doctrine-What-Christians-Should-Believe/dp/1433506254%3FSubscriptionId%3D1A7ETSHYVGJVYADTM6G2%26tag%3Dtheresurgence-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1433506254</DetailPageURL><ItemLinks><ItemLink><Description>Technical Details</Description><URL>http://www.amazon.com/Doctrine-What-Christians-Should-Believe/dp/tech-data/1433506254%3FSubscriptionId%3D1A7ETSHYVGJVYADTM6G2%26tag%3Dtheresurgence-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D1433506254</URL></ItemLink><ItemLink><Description>Add To Baby Registry</Description><URL>http://www.amazon.com/gp/registry/baby/add-item.html%3Fasin.0%3D1433506254%26SubscriptionId%3D1A7ETSHYVGJVYADTM6G2%26tag%3Dtheresurgence-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D1433506254</URL></ItemLink><ItemLink><Description>Add To Wedding Registry</Description><URL>http://www.amazon.com/gp/registry/wedding/add-item.html%3Fasin.0%3D1433506254%26SubscriptionId%3D1A7ETSHYVGJVYADTM6G2%26tag%3Dtheresurgence-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D1433506254</URL></ItemLink><ItemLink><Description>Add To Wishlist</Description><URL>http://www.amazon.com/gp/registry/wishlist/add-item.html%3Fasin.0%3D1433506254%26SubscriptionId%3D1A7ETSHYVGJVYADTM6G2%26tag%3Dtheresurgence-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D1433506254</URL></ItemLink><ItemLink><Description>Tell A Friend</Description><URL>http://www.amazon.com/gp/pdp/taf/1433506254%3FSubscriptionId%3D1A7ETSHYVGJVYADTM6G2%26tag%3Dtheresurgence-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D1433506254</URL></ItemLink><ItemLink><Description>All Customer Reviews</Description><URL>http://www.amazon.com/review/product/1433506254%3FSubscriptionId%3D1A7ETSHYVGJVYADTM6G2%26tag%3Dtheresurgence-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D1433506254</URL></ItemLink><ItemLink><Description>All Offers</Description><URL>http://www.amazon.com/gp/offer-listing/1433506254%3FSubscriptionId%3D1A7ETSHYVGJVYADTM6G2%26tag%3Dtheresurgence-20%26linkCode%3Dxm2%26camp%3D2025%26creative%3D386001%26creativeASIN%3D1433506254</URL></ItemLink></ItemLinks><SmallImage><URL>http://ecx.images-amazon.com/images/I/41xMfBAsMnL._SL75_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">47</Width></SmallImage><MediumImage><URL>http://ecx.images-amazon.com/images/I/41xMfBAsMnL._SL160_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">100</Width></MediumImage><LargeImage><URL>http://ecx.images-amazon.com/images/I/41xMfBAsMnL.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">313</Width></LargeImage><ImageSets><ImageSet Category="primary"><SwatchImage><URL>http://ecx.images-amazon.com/images/I/41xMfBAsMnL._SL30_.jpg</URL><Height Units="pixels">30</Height><Width Units="pixels">19</Width></SwatchImage><SmallImage><URL>http://ecx.images-amazon.com/images/I/41xMfBAsMnL._SL75_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">47</Width></SmallImage><ThumbnailImage><URL>http://ecx.images-amazon.com/images/I/41xMfBAsMnL._SL75_.jpg</URL><Height Units="pixels">75</Height><Width Units="pixels">47</Width></ThumbnailImage><TinyImage><URL>http://ecx.images-amazon.com/images/I/41xMfBAsMnL._SL110_.jpg</URL><Height Units="pixels">110</Height><Width Units="pixels">69</Width></TinyImage><MediumImage><URL>http://ecx.images-amazon.com/images/I/41xMfBAsMnL._SL160_.jpg</URL><Height Units="pixels">160</Height><Width Units="pixels">100</Width></MediumImage><LargeImage><URL>http://ecx.images-amazon.com/images/I/41xMfBAsMnL.jpg</URL><Height Units="pixels">500</Height><Width Units="pixels">313</Width></LargeImage></ImageSet></ImageSets><ItemAttributes><Author>Mark Driscoll</Author><Author>Gerry Breshears</Author><Binding>Hardcover</Binding><DeweyDecimalNumber>230</DeweyDecimalNumber><EAN>9781433506253</EAN><Feature>ISBN13: 9781433506253</Feature><Feature>Condition: New</Feature><Feature>Notes: BRAND NEW FROM PUBLISHER! 100% Satisfaction Guarantee. Tracking provided on most orders. Buy with Confidence! Millions of books sold!</Feature><ISBN>1433506254</ISBN><Label>Crossway Books</Label><Languages><Language><Name>English</Name><Type>Unknown</Type></Language><Language><Name>English</Name><Type>Original Language</Type></Language><Language><Name>English</Name><Type>Published</Type></Language></Languages><ListPrice><Amount>2299</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$22.99</FormattedPrice></ListPrice><Manufacturer>Crossway Books</Manufacturer><NumberOfItems>1</NumberOfItems><NumberOfPages>464</NumberOfPages><PackageDimensions><Height Units="hundredths-inches">118</Height><Length Units="hundredths-inches">858</Length><Weight Units="hundredths-pounds">163</Weight><Width Units="hundredths-inches">575</Width></PackageDimensions><ProductGroup>Book</ProductGroup><ProductTypeName>ABIS_BOOK</ProductTypeName><PublicationDate>2010-03-18</PublicationDate><Publisher>Crossway Books</Publisher><SKU>ST1433506254</SKU><Studio>Crossway Books</Studio><Title>Doctrine: What Christians Should Believe (RE: Lit)</Title></ItemAttributes><OfferSummary><LowestNewPrice><Amount>1417</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$14.17</FormattedPrice></LowestNewPrice><LowestUsedPrice><Amount>1401</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$14.01</FormattedPrice></LowestUsedPrice><TotalNew>51</TotalNew><TotalUsed>17</TotalUsed><TotalCollectible>0</TotalCollectible><TotalRefurbished>0</TotalRefurbished></OfferSummary><Offers><TotalOffers>1</TotalOffers><TotalOfferPages>1</TotalOfferPages><Offer><Merchant><MerchantId>ATVPDKIKX0DER</MerchantId><GlancePage>http://www.amazon.com/gp/help/seller/home.html?seller=ATVPDKIKX0DER</GlancePage><AverageFeedbackRating>0.0</AverageFeedbackRating><TotalFeedback>0</TotalFeedback></Merchant><OfferAttributes><Condition>New</Condition><SubCondition>new</SubCondition></OfferAttributes><OfferListing><OfferListingId>EDEpY3kBcSJkX8ndCQNbHcnumz1mrH3F8xPIujEqFichzusTRh3rVJUdhhGrfe8uT14X%2BoEWy4PRueVjhcDpA9pREsiD%2BUqm8BNGILgpLbGw1OunCi792Q%3D%3D</OfferListingId><Price><Amount>1503</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$15.03</FormattedPrice></Price><AmountSaved><Amount>796</Amount><CurrencyCode>USD</CurrencyCode><FormattedPrice>$7.96</FormattedPrice></AmountSaved><PercentageSaved>35</PercentageSaved><Availability>Usually ships in 24 hours</Availability><AvailabilityAttributes><AvailabilityType>now</AvailabilityType><MinimumHours>0</MinimumHours><MaximumHours>0</MaximumHours></AvailabilityAttributes><Quantity>-1</Quantity><IsEligibleForSuperSaverShipping>1</IsEligibleForSuperSaverShipping></OfferListing></Offer></Offers></Item></Items></ItemLookupResponse>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RemoteBook::Amazon do
|
4
|
+
before(:each) do
|
5
|
+
RemoteBook::Amazon.associate_keys = {:associates_id => 'foo',
|
6
|
+
:key_id => 'bar',
|
7
|
+
:secret_key => 'baz'}
|
8
|
+
end
|
9
|
+
it "should set large_image on successful get" do
|
10
|
+
FakeWeb.register_uri(:get, %r|http://ecs\.amazonaws\.com/(.*)|, :body => load_file("amazon_1433506254.xml"))
|
11
|
+
a = RemoteBook::Amazon.find_by_isbn("1433506254")
|
12
|
+
a.large_image.should == "http://ecx.images-amazon.com/images/I/41xMfBAsMnL.jpg"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "find_by_isbn should return false when error code returned by web service" do
|
16
|
+
FakeWeb.register_uri(:get, %r|http://ecs\.amazonaws\.com/(.*)|, :body => "Error", :status => ["404", "not found"])
|
17
|
+
a = RemoteBook::Amazon.find_by_isbn("unicorn")
|
18
|
+
a.should be_false
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RemoteBook::BarnesAndNoble do
|
4
|
+
before(:each) do
|
5
|
+
RemoteBook::BarnesAndNoble.associate_keys = {:web_service_token => 'doesntmatterfortest'}
|
6
|
+
end
|
7
|
+
it "should set link on successful get" do
|
8
|
+
dest = "http://click.linksynergy.com/fs-bin/some_ugly_path"
|
9
|
+
FakeWeb.register_uri(:get, RemoteBook::BarnesAndNoble::ISBN_SEARCH_BASE_URI+"1433506254",
|
10
|
+
:body => "redirect",
|
11
|
+
:location => "http://search.barnesandnoble.com/bookpath/")
|
12
|
+
FakeWeb.register_uri(:get, %r|http://getdeeplink\.linksynergy\.com/(.*)|, :body => dest)
|
13
|
+
a = RemoteBook::BarnesAndNoble.find_by_isbn("1433506254")
|
14
|
+
a.link.should == dest
|
15
|
+
end
|
16
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
2
|
+
# in spec/support/ and its subdirectories.
|
3
|
+
# Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
4
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
|
5
|
+
|
6
|
+
require 'fakeweb'
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
# == Mock Framework
|
10
|
+
#
|
11
|
+
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
12
|
+
#
|
13
|
+
# config.mock_with :mocha
|
14
|
+
# config.mock_with :flexmock
|
15
|
+
# config.mock_with :rr
|
16
|
+
config.mock_with :rspec
|
17
|
+
|
18
|
+
FakeWeb.allow_net_connect = false
|
19
|
+
|
20
|
+
config.before(:each) do
|
21
|
+
FakeWeb.clean_registry
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def load_file(name)
|
26
|
+
file = File.open("spec/fixtures/#{name}", "rb")
|
27
|
+
contents = file.read
|
28
|
+
file.close
|
29
|
+
return contents
|
30
|
+
end
|
data/tasks/spec.rake
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
ENV['BUNDLE_GEMFILE'] = File.dirname(__FILE__) + '/../Gemfile'
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rspec'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
desc "Run the test suite"
|
9
|
+
task :spec => ['spec:setup', 'spec:remote_book_lib', 'spec:cleanup']
|
10
|
+
|
11
|
+
namespace :spec do
|
12
|
+
desc "Setup the test environment"
|
13
|
+
task :setup do
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Cleanup the test environment"
|
17
|
+
task :cleanup do
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Test the remote_book library"
|
21
|
+
RSpec::Core::RakeTask.new(:remote_book_lib) do |task|
|
22
|
+
remote_book_root = File.expand_path(File.dirname(__FILE__) + '/..')
|
23
|
+
task.pattern = remote_book_root + '/spec/lib/**/*_spec.rb'
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Run the coverage report"
|
27
|
+
RSpec::Core::RakeTask.new(:rcov) do |task|
|
28
|
+
remote_book_root = File.expand_path(File.dirname(__FILE__) + '/..')
|
29
|
+
task.pattern = remote_book_root + '/spec/lib/**/*_spec.rb'
|
30
|
+
task.rcov=true
|
31
|
+
task.rcov_opts = %w{--rails --exclude osx\/objc,gems\/,spec\/,features\/}
|
32
|
+
end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: remote_book
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Seth Faxon
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-20 00:00:00.000000000 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: nokogiri
|
17
|
+
requirement: &70195227487660 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *70195227487660
|
26
|
+
description: Pull book affiliate links and images from Amazon, Barns & Noble
|
27
|
+
email:
|
28
|
+
- seth.faxon@gmail.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
files:
|
34
|
+
- .gitignore
|
35
|
+
- Gemfile
|
36
|
+
- README.rdoc
|
37
|
+
- Rakefile
|
38
|
+
- VERSION
|
39
|
+
- lib/remote_book.rb
|
40
|
+
- lib/remote_book/amazon.rb
|
41
|
+
- lib/remote_book/barnes_and_noble.rb
|
42
|
+
- lib/remote_book/base.rb
|
43
|
+
- remote_book.gemspec
|
44
|
+
- spec/fixtures/amazon_1433506254.xml
|
45
|
+
- spec/lib/amazon_spec.rb
|
46
|
+
- spec/lib/barnes_and_noble_spec.rb
|
47
|
+
- spec/spec_helper.rb
|
48
|
+
- tasks/spec.rake
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: https://github.com/sfaxon/remote_book
|
51
|
+
licenses: []
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
requirements: []
|
69
|
+
rubyforge_project: remote_book
|
70
|
+
rubygems_version: 1.6.2
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Pull book affiliate links and images from Amazon, Barns & Noble
|
74
|
+
test_files:
|
75
|
+
- spec/fixtures/amazon_1433506254.xml
|
76
|
+
- spec/lib/amazon_spec.rb
|
77
|
+
- spec/lib/barnes_and_noble_spec.rb
|
78
|
+
- spec/spec_helper.rb
|