acts_as_amazon_product 1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +51 -0
- data/lib/acts_as_amazon_product.rb +90 -0
- data/lib/amazon_product.rb +54 -0
- data/test/acts_as_amazon_product_test.rb +85 -0
- data/test/config-example.yml +8 -0
- metadata +58 -0
data/README
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
= ActsAsAmazonProduct
|
2
|
+
|
3
|
+
This "acts_as" module makes it extremely simple to add Amazon integration to an existing model.
|
4
|
+
|
5
|
+
== Setup
|
6
|
+
|
7
|
+
This code does not require changing any current database tables. It only requires adding one migration for a single new table used to cache responses from Amazon:
|
8
|
+
|
9
|
+
ActiveRecord::Base.connection.create_table :amazon_products do |t|
|
10
|
+
t.column :asin, :string
|
11
|
+
t.column :xml, :text
|
12
|
+
t.column :created_at, :datetime, :null => false
|
13
|
+
t.column :amazonable_id, :integer, :default => 0, :null => false
|
14
|
+
t.column :amazonable_type, :string, :limit => 15, :default => "", :null => false
|
15
|
+
end
|
16
|
+
|
17
|
+
== Using acts_as_amazon_product
|
18
|
+
|
19
|
+
Add the "acts_as" line to your model. Only :access_key is required. The :asin and :name assignments override what attributes in your class should be used for a direct lookup (item_looup) or general search (item_search). If no value is assigned to :asin then a general search is made and the first item (sorted by salesrank) is assigned (this functionality will likely change).
|
20
|
+
|
21
|
+
require 'acts_as_amazon_product'
|
22
|
+
|
23
|
+
class Book < ActiveRecord::Base
|
24
|
+
acts_as_amazon_product :asin => 'isbn', :name => 'title', :access_key => '0123456', :associate_tag => 'assoc-20'
|
25
|
+
end
|
26
|
+
|
27
|
+
You can now access the Amazon data in your views like so (see):
|
28
|
+
|
29
|
+
@book = Book.new(:title => 'Getting Things Done')
|
30
|
+
@book.amazon.isbn
|
31
|
+
@book.amazon.title
|
32
|
+
@book.amazon.author
|
33
|
+
@book.amazon.small_image_url
|
34
|
+
|
35
|
+
or
|
36
|
+
@book.amazon.get('itemattributes/foobar')
|
37
|
+
|
38
|
+
== Unit tests
|
39
|
+
|
40
|
+
There are tests you can run in the [gem]/test directory. Just create a test/config.yml from the example and run "Rake test" from the [gem] directory.
|
41
|
+
|
42
|
+
= Credits
|
43
|
+
acts_as_amazon_product was credited by Scott Nedderman and Chris Beck from netphase.com
|
44
|
+
|
45
|
+
We'd love to here how you like it. Also, if you'd like us to help out with your next project, let us know.
|
46
|
+
|
47
|
+
http://netphase.com
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# ActsAsAmazonProduct
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_support'
|
5
|
+
require 'active_record'
|
6
|
+
require 'amazon/ecs'
|
7
|
+
require 'amazon_product'
|
8
|
+
|
9
|
+
module Netphase
|
10
|
+
module Acts #:nodoc:
|
11
|
+
module Amazonable #:nodoc:
|
12
|
+
|
13
|
+
def self.included(base)
|
14
|
+
base.extend ClassMethods
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
|
19
|
+
def acts_as_amazon_product(options = {})
|
20
|
+
defaults = {
|
21
|
+
:asin => 'asin',
|
22
|
+
:name => 'name'
|
23
|
+
}
|
24
|
+
options = defaults.merge options
|
25
|
+
|
26
|
+
Amazon::Ecs.options = {:aWS_access_key_id => options[:access_key], :associate_tag => options[:associate_tag] }
|
27
|
+
|
28
|
+
write_inheritable_attribute(:amazon_asin, options[:asin])
|
29
|
+
write_inheritable_attribute(:amazon_name, options[:name])
|
30
|
+
write_inheritable_attribute(:amazon_associate_key, options[:associate_key])
|
31
|
+
class_inheritable_reader :amazon_asin, :amazon_name, :amazon_associate_key
|
32
|
+
|
33
|
+
has_one :amazon_product, :as => :amazonable #, :dependent => :delete
|
34
|
+
include Netphase::Acts::Amazonable::InstanceMethods
|
35
|
+
extend Netphase::Acts::Amazonable::SingletonMethods
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
# This module contains class methods
|
41
|
+
module SingletonMethods
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
# This module contains instance methods
|
46
|
+
module InstanceMethods
|
47
|
+
|
48
|
+
def amazon
|
49
|
+
if self.amazon_product.nil?
|
50
|
+
asin = (self.respond_to?('amazon_asin')) ? self.send(self.amazon_asin) : nil
|
51
|
+
name = (self.respond_to?('amazon_name')) ? self.send(self.amazon_name) : nil
|
52
|
+
|
53
|
+
if !asin.nil? && asin.length > 0
|
54
|
+
#puts "Looking up #{asin}"
|
55
|
+
res = Amazon::Ecs.item_lookup(self.send(self.amazon_asin), :response_group => 'Medium')
|
56
|
+
|
57
|
+
self.amazon_product =
|
58
|
+
AmazonProduct.new(:xml => res.doc.to_html, :asin => res.doc.at('itemattributes/isbn').inner_html)
|
59
|
+
self.amazon_product.save
|
60
|
+
elsif !name.nil? && name.length > 0
|
61
|
+
#puts "Searching for #{name}"
|
62
|
+
res = Amazon::Ecs.item_search(self.send(self.amazon_name), :response_group => 'Medium') #, :sort => 'salesrank'
|
63
|
+
res = res.doc.at('items/item')
|
64
|
+
self.amazon_product =
|
65
|
+
AmazonProduct.new(:xml => res.to_html, :asin => res.at('itemattributes/isbn').inner_html)
|
66
|
+
self.amazon_product.save
|
67
|
+
else
|
68
|
+
logger.error "No known attributes to search by"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
self.amazon_product
|
72
|
+
end
|
73
|
+
|
74
|
+
def after_save
|
75
|
+
unless self.amazon_product.nil?
|
76
|
+
self.amazon_product.destroy
|
77
|
+
self.reload
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
ActiveRecord::Base.class_eval do
|
88
|
+
include Netphase::Acts::Amazonable
|
89
|
+
end
|
90
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'hpricot'
|
2
|
+
|
3
|
+
class AmazonProduct < ActiveRecord::Base
|
4
|
+
# belongs_to :amazonable, :polymorphic => true
|
5
|
+
|
6
|
+
def hdoc(key)
|
7
|
+
@doc ||= Hpricot.XML(xml)
|
8
|
+
@doc.at(key).inner_html
|
9
|
+
end
|
10
|
+
|
11
|
+
def get(key)
|
12
|
+
hdoc(key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def isbn
|
16
|
+
hdoc("itemattributes/isbn")
|
17
|
+
end
|
18
|
+
|
19
|
+
def title
|
20
|
+
hdoc("itemattributes/title")
|
21
|
+
end
|
22
|
+
|
23
|
+
def author
|
24
|
+
hdoc("itemattributes/author")
|
25
|
+
end
|
26
|
+
|
27
|
+
def binding
|
28
|
+
hdoc("itemattributes/binding")
|
29
|
+
end
|
30
|
+
|
31
|
+
def price
|
32
|
+
hdoc("itemattributes/listprice/amount")
|
33
|
+
end
|
34
|
+
|
35
|
+
def pages
|
36
|
+
hdoc("itemattributes/numberofpages")
|
37
|
+
end
|
38
|
+
|
39
|
+
def small_image_url
|
40
|
+
hdoc("smallimage/url")
|
41
|
+
end
|
42
|
+
|
43
|
+
def medium_image_url
|
44
|
+
hdoc("mediumimage/url")
|
45
|
+
end
|
46
|
+
|
47
|
+
def large_image_url
|
48
|
+
hdoc("largeimage/url")
|
49
|
+
end
|
50
|
+
|
51
|
+
def detail_url
|
52
|
+
hdoc("detailpageurl")
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + "/../lib/acts_as_amazon_product")
|
5
|
+
|
6
|
+
#require File.expand_path(File.dirname(__FILE__) + "/../init")
|
7
|
+
|
8
|
+
config = open(File.dirname(__FILE__) + "/../test/config.yml") { |f| YAML.load(f.read)}
|
9
|
+
ActiveRecord::Base.establish_connection(config["database"])
|
10
|
+
|
11
|
+
#Amazon::Ecs.options = {:aWS_access_key_id => config['amazon']['access_key']}
|
12
|
+
@@access_key = config['amazon']['access_key']
|
13
|
+
@@associate_tag = config['amazon']['associate_tag']
|
14
|
+
|
15
|
+
ActiveRecord::Base.connection.drop_table :amazon_products rescue nil
|
16
|
+
ActiveRecord::Base.connection.drop_table :books rescue nil
|
17
|
+
|
18
|
+
ActiveRecord::Base.connection.create_table :books do |t|
|
19
|
+
t.column :title, :string
|
20
|
+
t.column :author, :string
|
21
|
+
t.column :isbn, :string
|
22
|
+
end
|
23
|
+
|
24
|
+
ActiveRecord::Base.connection.create_table :amazon_products do |t| # , :id => false
|
25
|
+
t.column :asin, :string
|
26
|
+
t.column :xml, :text
|
27
|
+
t.column :created_at, :datetime, :null => false
|
28
|
+
t.column :amazonable_id, :integer, :default => 0, :null => false
|
29
|
+
t.column :amazonable_type, :string, :limit => 15, :default => "", :null => false
|
30
|
+
end
|
31
|
+
|
32
|
+
class Book < ActiveRecord::Base
|
33
|
+
acts_as_amazon_product :asin => 'isbn', :name => 'title', :access_key => @@access_key, :associate_tag => @@associate_tag
|
34
|
+
end
|
35
|
+
|
36
|
+
AmazonProduct.delete_all
|
37
|
+
|
38
|
+
class ActAsAmazonProductTest < Test::Unit::TestCase
|
39
|
+
|
40
|
+
def setup
|
41
|
+
Book.delete_all
|
42
|
+
@book_gtd = Book.create(:title => 'Getting Things Done', :author => 'Dude', :isbn => '0142000280')
|
43
|
+
@book_ror = Book.create(:title => 'Rails Recipes')
|
44
|
+
@book_perl = Book.create(:title => 'Perl')
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_isbn
|
48
|
+
assert_not_nil(@book_gtd.amazon)
|
49
|
+
assert_equal("0142000280", @book_gtd.amazon.isbn)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_title
|
53
|
+
assert_not_nil(@book_gtd.amazon)
|
54
|
+
assert_equal("Getting Things Done: The Art of Stress-Free Productivity", @book_gtd.amazon.title)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_small_image
|
58
|
+
assert_not_nil(@book_gtd.amazon)
|
59
|
+
assert_match(/01PBN79FHEL\.jpg/, @book_gtd.amazon.small_image_url)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_author
|
63
|
+
assert_not_nil(@book_gtd.amazon)
|
64
|
+
assert_equal("David Allen", @book_gtd.amazon.author)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_binding
|
68
|
+
assert_not_nil(@book_gtd.amazon)
|
69
|
+
assert_equal("Paperback", @book_gtd.amazon.binding)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_find_with_multiple
|
73
|
+
assert_equal("Rails Recipes (Pragmatic Programmers)", @book_ror.amazon.title)
|
74
|
+
assert_equal("Chad Fowler", @book_ror.amazon.author)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_update
|
78
|
+
assert_not_nil(@book_perl.amazon)
|
79
|
+
isbn = @book_perl.amazon.isbn
|
80
|
+
@book_perl.title = "Websters"
|
81
|
+
@book_perl.save
|
82
|
+
assert_not_equal(isbn, @book_perl.amazon.isbn)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: acts_as_amazon_product
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "1.0"
|
7
|
+
date: 2007-09-25 00:00:00 -04:00
|
8
|
+
summary: A package for simplifying use of the Amazon/ECS API
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: scott@netphase.com
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: acts_as_amazon_product
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Scott Nedderman
|
31
|
+
files:
|
32
|
+
- lib/acts_as_amazon_product.rb
|
33
|
+
- lib/amazon_product.rb
|
34
|
+
- test/acts_as_amazon_product_test.rb
|
35
|
+
- test/config-example.yml
|
36
|
+
- README
|
37
|
+
test_files: []
|
38
|
+
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README
|
43
|
+
executables: []
|
44
|
+
|
45
|
+
extensions: []
|
46
|
+
|
47
|
+
requirements: []
|
48
|
+
|
49
|
+
dependencies:
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: amazon-ecs
|
52
|
+
version_requirement:
|
53
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.5.1
|
58
|
+
version:
|