acts_as_amazon_product 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|