fletcher 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document CHANGED
File without changes
data/.travis.yml CHANGED
File without changes
data/Gemfile CHANGED
File without changes
data/Gemfile.lock CHANGED
File without changes
data/LICENSE.txt CHANGED
File without changes
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
  [![Build Status](http://travis-ci.org/hulihanapplications/fletcher.png)](http://travis-ci.org/hulihanapplications/fletcher)
3
3
 
4
4
 
5
- Fletcher is a cross-website product/item information fetcher. Give fletcher a product url and you'll get back a nice, simple object that's easy to work with.
5
+ Fletcher is a cross-website product/model information fetcher. Give fletcher a product url and you'll get back a nice, simple object that's easy to work with.
6
6
 
7
7
  ## Features
8
8
 
@@ -12,9 +12,9 @@ Fletcher is a cross-website product/item information fetcher. Give fletcher a pr
12
12
  ## Supported Websites
13
13
 
14
14
  * [Amazon](http://www.amazon.com) (name, description, price, images)
15
- * [eBay](http://www.ebay.com) (name, images)
16
- * [ThinkGeek](http://www.thinkgeek.com) (name, description, images)
17
- * [Etsy](http://www.etsy.com) (name, description, images)
15
+ * [eBay](http://www.ebay.com) (name, price, images)
16
+ * [ThinkGeek](http://www.thinkgeek.com) (name, description, price, images)
17
+ * [Etsy](http://www.etsy.com) (name, description, price, images)
18
18
 
19
19
  ## Installation
20
20
 
@@ -22,37 +22,37 @@ Fletcher is a cross-website product/item information fetcher. Give fletcher a pr
22
22
  gem install fletcher
23
23
  ```
24
24
 
25
- ## Examples
25
+ ## Usage
26
26
 
27
27
  ```ruby
28
28
  require "fletcher"
29
29
 
30
- item = Fletcher.fetch # => "http://www.amazon.com/Avenir-Deluxe-Unicycle-20-Inch-Wheel/dp/B00165Q9F8"
30
+ model = Fletcher.fetch "http://www.amazon.com/Avenir-Deluxe-Unicycle-20-Inch-Wheel/dp/B00165Q9F8"
31
31
 
32
- item.name # => "Avenir Deluxe Unicycle (20-Inch Wheel)"
32
+ model.name # => "Avenir Deluxe Unicycle (20-Inch Wheel)"
33
33
 
34
- item.description # => "A wonderful unicycle"
34
+ model.description # => "A wonderful unicycle"
35
35
 
36
- item.image # => {:url => "http://ecx.images-amazon.com/images/I/41b3TNb3uCL._SL500_AA300_.jpg", :alt => "Picture of Unicycle"}
36
+ model.image # => {:url => "http://ecx.images-amazon.com/images/I/41b3TNb3uCL._SL500_AA300_.jpg", :alt => "Picture of Unicycle"}
37
37
 
38
- item.image.url # => "http://ecx.images-amazon.com/images/I/41b3TNb3uCL._SL500_AA300_.jpg"
38
+ model.image.url # => "http://ecx.images-amazon.com/images/I/41b3TNb3uCL._SL500_AA300_.jpg"
39
39
 
40
- item.price # => #<Money cents:500 currency:USD>
41
- item.price.to_f # => 5.0
42
- item.price.format # => "$5.00"
43
- item.price.currency.symbol # => "$"
40
+ model.price # => #<Money cents:500 currency:USD>
41
+ model.price.to_f # => 5.0
42
+ model.price.format # => "$5.00"
43
+ model.price.currency.symbol # => "$"
44
44
 
45
45
  # Get Raw Nokogiri Document
46
- item.doc.class.name # => Nokogiri::HTML::Document
46
+ model.doc.class.name # => Nokogiri::HTML::Document
47
47
  ```
48
48
 
49
49
  ## Attributes
50
50
 
51
- The following attributes are available from items:
51
+ The following attributes are available from models:
52
52
 
53
- * title - (String) The name of the item/product
54
- * description - (String) The item/product description
55
- * price - (Money) A [Money](https://github.com/RubyMoney/money) object representing the item price. This makes exchange rates and math functionality easy to use.
56
- * image - (Hash) The main image of the item
57
- * images - (Array) Any available images of the item
53
+ * title - (String) The name of the model/product
54
+ * description - (String) The model/product description
55
+ * price - (Money) A [Money](https://github.com/RubyMoney/money) object representing the model price. This makes exchange rates and math functionality easy to use.
56
+ * image - (Hash) The main image of the model
57
+ * images - (Array) Any available images of the model
58
58
 
data/Rakefile CHANGED
@@ -17,8 +17,8 @@ Jeweler::Tasks.new do |gem|
17
17
  gem.name = "fletcher"
18
18
  gem.homepage = "http://github.com/hulihanapplications/fletcher"
19
19
  gem.license = "MIT"
20
- gem.summary = %Q{A cross-website product/item information fetcher.}
21
- gem.description = %Q{Easily fetch product/item information from third party websites such as Amazon, eBay, etc.}
20
+ gem.summary = %Q{A cross-website product/model information fetcher.}
21
+ gem.description = %Q{Easily fetch product/model information from third party websites such as Amazon, eBay, etc.}
22
22
  gem.email = "dave@hulihanapplications.com"
23
23
  gem.authors = ["Dave Hulihan", "Hulihan Applications"]
24
24
  # dependencies defined in Gemfile
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
data/fletcher.gemspec CHANGED
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{fletcher}
8
- s.version = "0.3.0"
7
+ s.name = "fletcher"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Dave Hulihan", "Hulihan Applications"]
12
- s.date = %q{2012-01-01}
13
- s.description = %q{Easily fetch product/item information from third party websites such as Amazon, eBay, etc.}
14
- s.email = %q{dave@hulihanapplications.com}
12
+ s.date = "2012-03-18"
13
+ s.description = "Easily fetch product/model information from third party websites such as Amazon, eBay, etc."
14
+ s.email = "dave@hulihanapplications.com"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
17
  "README.md"
@@ -28,21 +28,20 @@ Gem::Specification.new do |s|
28
28
  "fletcher.gemspec",
29
29
  "lib/fletcher.rb",
30
30
  "lib/fletcher/data.rb",
31
- "lib/fletcher/item/amazon.rb",
32
- "lib/fletcher/item/base.rb",
33
- "lib/fletcher/item/ebay.rb",
34
- "lib/fletcher/item/etsy.rb",
35
- "lib/fletcher/item/image.rb",
36
- "lib/fletcher/item/thinkgeek.rb",
31
+ "lib/fletcher/models/amazon.rb",
32
+ "lib/fletcher/models/base.rb",
33
+ "lib/fletcher/models/ebay.rb",
34
+ "lib/fletcher/models/etsy.rb",
35
+ "lib/fletcher/models/thinkgeek.rb",
37
36
  "lib/fletcher/nokogiri.rb",
38
37
  "lib/fletcher/string.rb",
39
- "spec/factories/item.rb",
38
+ "spec/factories/models.rb",
40
39
  "spec/lib/fletcher/data_spec.rb",
41
- "spec/lib/fletcher/item/amazon_spec.rb",
42
- "spec/lib/fletcher/item/base_spec.rb",
43
- "spec/lib/fletcher/item/ebay_spec.rb",
44
- "spec/lib/fletcher/item/etsy_spec.rb",
45
- "spec/lib/fletcher/item/thinkgeek_spec.rb",
40
+ "spec/lib/fletcher/models/amazon_spec.rb",
41
+ "spec/lib/fletcher/models/base_spec.rb",
42
+ "spec/lib/fletcher/models/ebay_spec.rb",
43
+ "spec/lib/fletcher/models/etsy_spec.rb",
44
+ "spec/lib/fletcher/models/thinkgeek_spec.rb",
46
45
  "spec/lib/fletcher/nokogiri_spec.rb",
47
46
  "spec/lib/fletcher_spec.rb",
48
47
  "spec/spec_helper.rb",
@@ -50,11 +49,11 @@ Gem::Specification.new do |s|
50
49
  "test/helper.rb",
51
50
  "test/test_fletcher.rb"
52
51
  ]
53
- s.homepage = %q{http://github.com/hulihanapplications/fletcher}
52
+ s.homepage = "http://github.com/hulihanapplications/fletcher"
54
53
  s.licenses = ["MIT"]
55
54
  s.require_paths = ["lib"]
56
- s.rubygems_version = %q{1.7.2}
57
- s.summary = %q{A cross-website product/item information fetcher.}
55
+ s.rubygems_version = "1.8.15"
56
+ s.summary = "A cross-website product/model information fetcher."
58
57
 
59
58
  if s.respond_to? :specification_version then
60
59
  s.specification_version = 3
data/lib/fletcher.rb CHANGED
@@ -5,64 +5,72 @@ require "fletcher/data"
5
5
  require "fletcher/string"
6
6
  require "fletcher/nokogiri"
7
7
 
8
- module Fletcher
9
- #autoload :Data, 'fletcher/data'
10
- #autoload :Nokogiri, 'fletcher/nokogiri'
11
-
12
- module Item
13
- dir = 'fletcher/item'
14
- Dir[File.join(dir, "*.rb")].each do |f|
15
- #autoload f
16
- end
17
- autoload :Base, 'fletcher/item/base'
18
- autoload :Amazon, 'fletcher/item/amazon'
19
- autoload :Ebay, 'fletcher/item/ebay'
20
- autoload :Thinkgeek, 'fletcher/item/thinkgeek'
21
- autoload :Etsy, 'fletcher/item/etsy'
22
- end
23
-
24
- # Detect service by url
25
- # Fletcher.identify_service("http://www.amazon.com/whatever") => :amazon
26
- def self.identify_service(url)
27
- if url =~ ::URI::regexp
28
- uri = ::URI::parse(url)
29
- host = uri.host
30
- if host =~ Fletcher::Item::Amazon.regexp
31
- service = :amazon
32
- elsif host =~ Fletcher::Item::Ebay.regexp
33
- service = :ebay
34
- elsif host =~ Fletcher::Item::Thinkgeek.regexp
35
- service = :thinkgeek
36
- elsif host =~ Fletcher::Item::Etsy.regexp
37
- service = :etsy
8
+ module Fletcher
9
+ class << self
10
+ # Detect model by url
11
+ # Fletcher.identify_model("http://www.amazon.com/whatever") => :amazon
12
+ def identify_model(url)
13
+ if url =~ ::URI::regexp
14
+ uri = ::URI::parse(url)
15
+ host = uri.host
16
+ if host =~ Fletcher::Model::Amazon.regexp
17
+ model = :amazon
18
+ elsif host =~ Fletcher::Model::Ebay.regexp
19
+ model = :ebay
20
+ elsif host =~ Fletcher::Model::Thinkgeek.regexp
21
+ model = :thinkgeek
22
+ elsif host =~ Fletcher::Model::Etsy.regexp
23
+ model = :etsy
24
+ else
25
+ model = :unknown
26
+ raise ArgumentError, "Fletcher doesn't support #{host} yet."
27
+ end
38
28
  else
39
- service = :unknown
40
- raise ArgumentError, "Fletcher doesn't support #{host} yet."
29
+ raise ArgumentError, "not a url"
41
30
  end
42
- else
43
- raise ArgumentError, "not a url"
44
31
  end
45
- end
46
-
47
- # Fetch information based on url
48
- def self.fetch(url)
49
- service = identify_service(url)
50
- data = Fletcher::Data.read(url)
51
- item = Fletcher::Item::Base.generate(service, data)
52
- # Store url
53
- item.url = url
54
32
 
55
- item.parse(data)
56
- return item
57
- end
58
-
59
- # Get gem version
60
- def self.version
61
- File.read(File.join(root, "VERSION"))
33
+ # Fetch information based on url
34
+ def fetch(url)
35
+ model = identify_model(url)
36
+ data = Fletcher::Data.read(url)
37
+ model = Fletcher::Model::Base.generate(model, data)
38
+ # Store url
39
+ model.url = url
40
+
41
+ model.parse(data)
42
+ return model
43
+ end
44
+
45
+ # Get gem version
46
+ def version
47
+ File.read(File.join(root, "VERSION"))
48
+ end
49
+
50
+ # Get gem root directory
51
+ def root
52
+ File.expand_path("../..", __FILE__)
53
+ end
54
+
55
+ # Create mattrs
56
+ attr_accessor :models
62
57
  end
63
58
 
64
- # Get gem root directory
65
- def self.root
66
- File.expand_path("../..", __FILE__)
67
- end
59
+ # Initialize models mattr & Load models array from dir
60
+ @models = Array.new
61
+ Dir[File.join(File.dirname(__FILE__), "fletcher", "models", "*.rb")].each do |f|
62
+ model = File.basename(f, ".rb").to_sym
63
+ @models << model unless model == :base
64
+ end
65
+
66
+ # Load Models/Models
67
+ module Model
68
+ # Dir[File.join(dir, "*.rb")].each do |f|
69
+ # autoload f
70
+ # end
71
+ autoload :Base, 'fletcher/models/base'
72
+ for model in Fletcher.models
73
+ autoload model.capitalize, "fletcher/models/#{model}"
74
+ end
75
+ end
68
76
  end
data/lib/fletcher/data.rb CHANGED
@@ -5,13 +5,19 @@ module Fletcher
5
5
  # This class is responsible for fetching and parsing data.
6
6
  class Data
7
7
  # Get read url and get data object
8
- def self.read(url)
9
- remote_file = open(url).read
10
- doc = ::Nokogiri::HTML(remote_file)
8
+ def self.read(url, options = {})
9
+ # Set Defaults
10
+ options[:user_agent] ||= "Ruby/#{RUBY_VERSION}"
11
+
12
+ response = open(url, "User-Agent" => options[:user_agent])
13
+ doc = ::Nokogiri::HTML(response.read)
11
14
 
12
- # Save contents of URL/Remote File
13
- #last_url_file = File.expand_path(File.join("..", "..", "remote_file"), File.dirname(__FILE__))
14
- #File.new(last_url_file, "w+").write(remote_file.read)
15
+ # Save contents of URL/Remote File for debugging
16
+ # response.rewind
17
+ # last_response_file = File.expand_path(File.join("..", "..", "last_response"), File.dirname(__FILE__))
18
+ # File.new(last_response_file, "w+").write(response.read)
19
+
20
+ return doc
15
21
  end
16
22
  end
17
23
  end
@@ -1,6 +1,6 @@
1
1
  module Fletcher
2
- module Item
3
- class Amazon < Fletcher::Item::Base
2
+ module Model
3
+ class Amazon < Fletcher::Model::Base
4
4
  # A regular expression for determining if a url comes from a specific service/website
5
5
  def self.regexp
6
6
  /amazon\.com/
@@ -8,8 +8,7 @@ module Fletcher
8
8
 
9
9
  # Parse data and look for object attributes to give to object
10
10
  def parse(data)
11
- # Store raw document object
12
- self.doc = data
11
+ super(data)
13
12
 
14
13
  case doc
15
14
  when Nokogiri::HTML::Document
@@ -2,24 +2,24 @@ require "hashie"
2
2
  require "money"
3
3
 
4
4
  module Fletcher
5
- module Item
5
+ module Model
6
6
  class Base < ::Hashie::Mash
7
7
  # Create a product object based on service
8
- # Fletcher::Item::Base.generate(:amazon, "<html>...") # => #<Fletcher::Item::Amazon:0x...>
8
+ # Fletcher::Model::Base.generate(:amazon, "<html>...") # => #<Fletcher::Model::Amazon:0x...>
9
9
  def self.generate(service = nil, data = nil)
10
10
  case service
11
11
  when :amazon
12
- item = Fletcher::Item::Amazon.new
12
+ model = Fletcher::Model::Amazon.new
13
13
  when :ebay
14
- item = Fletcher::Item::Ebay.new
14
+ model = Fletcher::Model::Ebay.new
15
15
  when :thinkgeek
16
- item = Fletcher::Item::Thinkgeek.new
16
+ model = Fletcher::Model::Thinkgeek.new
17
17
  when :etsy
18
- item = Fletcher::Item::Etsy.new
18
+ model = Fletcher::Model::Etsy.new
19
19
  end
20
20
 
21
- item.parse(data)
22
- return item
21
+ model.parse(data)
22
+ return model
23
23
  end
24
24
 
25
25
  # Parse data and set object attributes
@@ -28,13 +28,13 @@ module Fletcher
28
28
  end
29
29
 
30
30
  # Parse a raw price string to get usable data
31
- # item.parse_price("$5.00") # => #<Money cents:500 currency:USD>
32
- # item.price.to_f # => 5.0
33
- # item.price.currency.symbol # => '$'
31
+ # model.parse_price("$5.00") # => #<Money cents:500 currency:USD>
32
+ # model.price.to_f # => 5.0
33
+ # model.price.currency.symbol # => '$'
34
34
  def parse_price(raw_price = nil)
35
35
  return if raw_price.nil?
36
36
  self.price = ::Money.parse(raw_price)
37
37
  end
38
38
  end # Base
39
- end # Item
39
+ end # Model
40
40
  end # Fletcher
@@ -1,6 +1,6 @@
1
1
  module Fletcher
2
- module Item
3
- class Ebay < Fletcher::Item::Base
2
+ module Model
3
+ class Ebay < Fletcher::Model::Base
4
4
  # A regular expression for determining if a url comes from a specific service/website
5
5
  def self.regexp
6
6
  /ebay\.com/
@@ -8,9 +8,8 @@ module Fletcher
8
8
 
9
9
  # Parse data and look for object attributes to give to object
10
10
  def parse(data)
11
- # Store raw document object
12
- self.doc = data
13
-
11
+ super(data)
12
+
14
13
  case doc
15
14
  when Nokogiri::HTML::Document
16
15
  # Get Name
@@ -20,7 +19,8 @@ module Fletcher
20
19
  # OMITTED: This is tough to get because ebay item descriptions are custom html/content created by sellers
21
20
 
22
21
  # Get Price
23
- parse_price(doc.xpath("//span[@itemprop='price']").first_string.gsub(/US/, ""))
22
+ raw_price = doc.xpath("//span[@itemprop='price']").first_string
23
+ parse_price(raw_price.gsub(/US/, "")) if raw_price
24
24
 
25
25
  # Get Image
26
26
  self.images = [{:url => doc.xpath("//span[@itemprop='image']/img").first_string}]
@@ -1,6 +1,6 @@
1
1
  module Fletcher
2
- module Item
3
- class Etsy < Fletcher::Item::Base
2
+ module Model
3
+ class Etsy < Fletcher::Model::Base
4
4
  # A regular expression for determining if a url comes from a specific service/website
5
5
  def self.regexp
6
6
  /etsy\.com/
@@ -8,8 +8,7 @@ module Fletcher
8
8
 
9
9
  # Parse data and look for object attributes to give to object
10
10
  def parse(data)
11
- # Store raw document object
12
- self.doc = data
11
+ super(data)
13
12
 
14
13
  case doc
15
14
  when Nokogiri::HTML::Document
@@ -1,6 +1,6 @@
1
1
  module Fletcher
2
- module Item
3
- class Thinkgeek < Fletcher::Item::Base
2
+ module Model
3
+ class Thinkgeek < Fletcher::Model::Base
4
4
  # A regular expression for determining if a url comes from a specific service/website
5
5
  def self.regexp
6
6
  /thinkgeek\.com/
@@ -8,8 +8,7 @@ module Fletcher
8
8
 
9
9
  # Parse data and look for object attributes to give to object
10
10
  def parse(data)
11
- # Store raw document object
12
- self.doc = data
11
+ super(data)
13
12
 
14
13
  case doc
15
14
  when Nokogiri::HTML::Document
@@ -11,7 +11,7 @@ module Fletcher
11
11
 
12
12
  module XML
13
13
  module NodeSet
14
- # get string from first nodeset item
14
+ # get string from first nodeset model
15
15
  def first_string
16
16
  node = first
17
17
  case node
@@ -24,7 +24,7 @@ module Fletcher
24
24
  end
25
25
  end
26
26
 
27
- # convert nodeset items to an array of hashes
27
+ # convert nodeset models to an array of hashes
28
28
  # @doc.xpath("//img")).attribute_array # => [{:element => "img", :src => ".../someimage.png"}]
29
29
  def attribute_array
30
30
  a = Array.new
File without changes
@@ -0,0 +1,39 @@
1
+ require "hashie"
2
+
3
+ Factory.define :base, :class => Fletcher::Model::Base do |o|
4
+ o.url "http://www.example.com"
5
+ end
6
+
7
+ Factory.define :sample, :parent => :base do |o|
8
+ o.url "http://www.example.com"
9
+ o.name "Sample Model"
10
+ o.description "This is a sample description."
11
+ o.raw_price "$5.00"
12
+ end
13
+
14
+ Factory.define :invalid, :parent => :base do |o|
15
+ o.url "http://invalid"
16
+ end
17
+
18
+ Factory.define :valid, :parent => :base do |o|
19
+ o.url "http://www.amazon.com/Kindle-Fire-Amazon-Tablet/dp/B0051VVOB2"
20
+ o.title_xpath "//h1[@class='parseasinTitle']"
21
+ o.images_xpath "//table[@class='productImageGrid']//img"
22
+ end
23
+
24
+ Factory.define :amazon, :parent => :base do |o|
25
+ o.url "http://www.amazon.com/Kindle-Fire-Amazon-Tablet/dp/B0051VVOB2"
26
+ end
27
+
28
+ # This may need to be updated if the item is expired/deleted
29
+ Factory.define :ebay, :parent => :base do |o|
30
+ o.url "http://www.ebay.com/itm/Franklin-Library-3V-ESSAYS-MONTAIGNE-Leather-Great-Books-1979-Donald-Frame-/190654183378"
31
+ end
32
+
33
+ Factory.define :thinkgeek, :parent => :base do |o|
34
+ o.url "http://www.thinkgeek.com/geektoys/plush/e7f8/"
35
+ end
36
+
37
+ Factory.define :etsy, :parent => :base do |o|
38
+ o.url "http://www.etsy.com/listing/78608690/farm-fresh-125-x-19-in-pick-your-color"
39
+ end
@@ -3,18 +3,18 @@ require 'spec_helper'
3
3
  describe Fletcher::Data do
4
4
  describe "open-uri" do
5
5
  it "tells me how long it taks to open an uri file" do
6
- #puts benchmark{ file = open(Factory(:valid_item).url)}.to_s
6
+ #puts benchmark{ file = open(Factory(:valid_model).url)}.to_s
7
7
  end
8
8
  end
9
9
 
10
10
  describe "read" do
11
11
  it "should return a valid document" do
12
- doc = Fletcher::Data.read(Factory(:valid_item).url)
12
+ doc = Fletcher::Data.read(Factory(:valid).url)
13
13
  end
14
14
 
15
15
  # This is just a rough indicator of how long a data should take to download
16
16
  it "shouldn't take too long" do
17
- # benchmark{ doc = Fletcher::Data.read(Factory(:valid_item).url)}.should_not be_slower_than(5.0)
17
+ # benchmark{ doc = Fletcher::Data.read(Factory(:valid_model).url)}.should_not be_slower_than(5.0)
18
18
  end
19
19
  end
20
20
  end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fletcher::Model::Amazon do
4
+ describe "parse" do
5
+ context "with valid data" do
6
+ it "should return correct model info" do
7
+ model = described_class.new
8
+ model.parse Fletcher::Data.read(Factory(:amazon).url)
9
+ model.name.should_not be_nil
10
+ model.description.should_not be_nil
11
+ model.price.should_not be_nil
12
+ model.image.should_not be_nil
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Fletcher::Item::Base do
3
+ describe Fletcher::Model::Base do
4
4
  describe "generate" do
5
5
  end
6
6
 
@@ -11,10 +11,10 @@ describe Fletcher::Item::Base do
11
11
 
12
12
  describe "parse_price" do
13
13
  it "should return a price float and currency" do
14
- item = Factory.build(:sample_item)
15
- item.parse_price(item.raw_price)
16
- item.price.is_a?(Money).should == true
17
- item.price.currency.should_not be_nil
14
+ model = Factory.build(:sample)
15
+ model.parse_price(model.raw_price)
16
+ model.price.is_a?(Money).should == true
17
+ model.price.currency.should_not be_nil
18
18
  end
19
19
  end
20
20
  end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fletcher::Model::Ebay do
4
+ describe "parse" do
5
+ context "with valid data" do
6
+ it "should return correct model info" do
7
+ model = described_class.new
8
+ model.parse Fletcher::Data.read(Factory(:ebay).url)
9
+ model.name.should_not be_nil
10
+ model.price.should_not be_nil
11
+ model.image.should_not be_nil
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fletcher::Model::Etsy do
4
+ describe "parse" do
5
+ context "with valid data" do
6
+ it "should return correct model info" do
7
+ model = described_class.new
8
+ model.parse Fletcher::Data.read(Factory(:etsy).url)
9
+ model.name.should_not be_nil
10
+ model.description.should_not be_nil
11
+ model.price.should_not be_nil
12
+ model.image.should_not be_nil
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fletcher::Model::Thinkgeek do
4
+ describe "parse" do
5
+ context "with valid data" do
6
+ it "should return correct model info" do
7
+ model = described_class.new
8
+ model.parse Fletcher::Data.read(Factory(:thinkgeek).url)
9
+ model.name.should_not be_nil
10
+ model.price.should_not be_nil
11
+ model.image.should_not be_nil
12
+ end
13
+ end
14
+ end
15
+ end
@@ -6,12 +6,12 @@ end
6
6
 
7
7
  describe Fletcher::Nokogiri::XML::NodeSet do
8
8
  before :each do
9
- @doc = Fletcher::Data.read(Factory(:valid_item).url)
9
+ @doc = Fletcher::Data.read(Factory(:valid).url)
10
10
  end
11
11
 
12
12
  describe "first_string" do
13
13
  it "should return a valid string" do
14
- nodeset = @doc.xpath(Factory(:valid_item).title_xpath)
14
+ nodeset = @doc.xpath(Factory(:valid).title_xpath)
15
15
  string = nodeset.first_string
16
16
  string.should_not be_nil
17
17
  end
@@ -19,7 +19,7 @@ describe Fletcher::Nokogiri::XML::NodeSet do
19
19
 
20
20
  describe "attribute_array" do
21
21
  it "should return an array of attribute hashes" do
22
- nodeset = @doc.xpath(Factory(:valid_item).images_xpath)
22
+ nodeset = @doc.xpath(Factory(:valid).images_xpath)
23
23
  attribute_array = nodeset.attribute_array
24
24
  attribute_array.class.should == Array
25
25
  end
@@ -1,53 +1,29 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Fletcher do
4
- describe :service do
5
- it "should raise an error when using an unsupported domain" do
6
- lambda{described_class.identify_service(Factory(:item).url)}.should raise_error
7
- end
8
-
9
- it "should return :amazon when using an amazon domain" do
10
- described_class.identify_service(Factory(:amazon_item).url).should == :amazon
11
- end
12
-
13
- it "should return :ebay when using an ebay domain" do
14
- described_class.identify_service(Factory(:ebay_item).url).should == :ebay
15
- end
16
- end
17
-
18
- describe :fetch do
19
- context :amazon do
20
- it "should fetch amazon item info successfully" do
21
- item = described_class.fetch(Factory(:amazon_item).url)
22
- item.should_not be_nil
23
- item.name.should_not be_nil
24
- item.description.should_not be_nil
25
- end
26
- end
27
-
28
- context :ebay do
29
- it "should fetch item info successfully" do
30
- item = described_class.fetch(Factory(:ebay_item).url)
31
- item.should_not be_nil
32
- item.name.should_not be_nil
33
- end
34
- end
4
+ context :models do
5
+ describe :itendify_model do
6
+ it "should raise an error when using an unsupported domain" do
7
+ lambda{described_class.identify_model(Factory(:invalid).url)}.should raise_error
8
+ end
9
+
10
+ for model in Fletcher.models
11
+ it "should return #{model} sym when using a #{model} domain" do
12
+ described_class.identify_model(Factory(model).url).should == model
13
+ end
14
+ end
15
+ end
35
16
 
36
- context :thinkgeek do
37
- it "should fetch item info successfully" do
38
- item = described_class.fetch(Factory(:thinkgeek_item).url)
39
- item.should_not be_nil
40
- item.name.should_not be_nil
41
- end
17
+ describe :fetch do
18
+ for model in [Fletcher.models[2]]
19
+ it "should return valid data for #{model} model" do
20
+ item = described_class.fetch(Factory(model).url)
21
+ item.should_not be_nil
22
+ item.name.should_not be_nil
23
+ item.description.should_not be_nil if model == :amazon
24
+ end
25
+ end
42
26
  end
43
-
44
- context :etsy do
45
- it "should fetch item info successfully" do
46
- item = described_class.fetch(Factory(:etsy_item).url)
47
- item.should_not be_nil
48
- item.name.should_not be_nil
49
- end
50
- end
51
27
  end
52
28
 
53
29
  describe :version do
@@ -55,4 +31,13 @@ describe Fletcher do
55
31
  described_class.version.should_not be_nil
56
32
  end
57
33
  end
34
+
35
+ describe :models do
36
+ it "should return an array of models" do
37
+ described_class.models.should_not be_nil
38
+ # Test append
39
+ described_class.models << :somemodel
40
+ described_class.models.include?(:somemodel).should == true
41
+ end
42
+ end
58
43
  end
File without changes
data/test/helper.rb CHANGED
File without changes
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fletcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-01-01 00:00:00.000000000Z
13
+ date: 2012-03-18 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: hashie
17
- requirement: &71525050 !ruby/object:Gem::Requirement
17
+ requirement: &13008300 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *71525050
25
+ version_requirements: *13008300
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: nokogiri
28
- requirement: &71524600 !ruby/object:Gem::Requirement
28
+ requirement: &13007540 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *71524600
36
+ version_requirements: *13007540
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: money
39
- requirement: &71524080 !ruby/object:Gem::Requirement
39
+ requirement: &13006520 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: '0'
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *71524080
47
+ version_requirements: *13006520
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: shoulda
50
- requirement: &71523400 !ruby/object:Gem::Requirement
50
+ requirement: &12980420 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '0'
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *71523400
58
+ version_requirements: *12980420
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: bundler
61
- requirement: &71522560 !ruby/object:Gem::Requirement
61
+ requirement: &12979040 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ~>
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 1.0.0
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *71522560
69
+ version_requirements: *12979040
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: jeweler
72
- requirement: &71521590 !ruby/object:Gem::Requirement
72
+ requirement: &12978400 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ~>
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: 1.6.4
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *71521590
80
+ version_requirements: *12978400
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: rcov
83
- requirement: &71520830 !ruby/object:Gem::Requirement
83
+ requirement: &12976820 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,10 +88,10 @@ dependencies:
88
88
  version: '0'
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *71520830
91
+ version_requirements: *12976820
92
92
  - !ruby/object:Gem::Dependency
93
93
  name: rspec
94
- requirement: &71519900 !ruby/object:Gem::Requirement
94
+ requirement: &12975180 !ruby/object:Gem::Requirement
95
95
  none: false
96
96
  requirements:
97
97
  - - ! '>='
@@ -99,10 +99,10 @@ dependencies:
99
99
  version: '0'
100
100
  type: :development
101
101
  prerelease: false
102
- version_requirements: *71519900
102
+ version_requirements: *12975180
103
103
  - !ruby/object:Gem::Dependency
104
104
  name: factory_girl
105
- requirement: &71519240 !ruby/object:Gem::Requirement
105
+ requirement: &12973720 !ruby/object:Gem::Requirement
106
106
  none: false
107
107
  requirements:
108
108
  - - ! '>='
@@ -110,10 +110,10 @@ dependencies:
110
110
  version: '0'
111
111
  type: :development
112
112
  prerelease: false
113
- version_requirements: *71519240
113
+ version_requirements: *12973720
114
114
  - !ruby/object:Gem::Dependency
115
115
  name: i18n
116
- requirement: &71518690 !ruby/object:Gem::Requirement
116
+ requirement: &12972540 !ruby/object:Gem::Requirement
117
117
  none: false
118
118
  requirements:
119
119
  - - ! '>='
@@ -121,8 +121,8 @@ dependencies:
121
121
  version: '0'
122
122
  type: :development
123
123
  prerelease: false
124
- version_requirements: *71518690
125
- description: Easily fetch product/item information from third party websites such
124
+ version_requirements: *12972540
125
+ description: Easily fetch product/model information from third party websites such
126
126
  as Amazon, eBay, etc.
127
127
  email: dave@hulihanapplications.com
128
128
  executables: []
@@ -142,21 +142,20 @@ files:
142
142
  - fletcher.gemspec
143
143
  - lib/fletcher.rb
144
144
  - lib/fletcher/data.rb
145
- - lib/fletcher/item/amazon.rb
146
- - lib/fletcher/item/base.rb
147
- - lib/fletcher/item/ebay.rb
148
- - lib/fletcher/item/etsy.rb
149
- - lib/fletcher/item/image.rb
150
- - lib/fletcher/item/thinkgeek.rb
145
+ - lib/fletcher/models/amazon.rb
146
+ - lib/fletcher/models/base.rb
147
+ - lib/fletcher/models/ebay.rb
148
+ - lib/fletcher/models/etsy.rb
149
+ - lib/fletcher/models/thinkgeek.rb
151
150
  - lib/fletcher/nokogiri.rb
152
151
  - lib/fletcher/string.rb
153
- - spec/factories/item.rb
152
+ - spec/factories/models.rb
154
153
  - spec/lib/fletcher/data_spec.rb
155
- - spec/lib/fletcher/item/amazon_spec.rb
156
- - spec/lib/fletcher/item/base_spec.rb
157
- - spec/lib/fletcher/item/ebay_spec.rb
158
- - spec/lib/fletcher/item/etsy_spec.rb
159
- - spec/lib/fletcher/item/thinkgeek_spec.rb
154
+ - spec/lib/fletcher/models/amazon_spec.rb
155
+ - spec/lib/fletcher/models/base_spec.rb
156
+ - spec/lib/fletcher/models/ebay_spec.rb
157
+ - spec/lib/fletcher/models/etsy_spec.rb
158
+ - spec/lib/fletcher/models/thinkgeek_spec.rb
160
159
  - spec/lib/fletcher/nokogiri_spec.rb
161
160
  - spec/lib/fletcher_spec.rb
162
161
  - spec/spec_helper.rb
@@ -178,7 +177,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
178
177
  version: '0'
179
178
  segments:
180
179
  - 0
181
- hash: -857180173
180
+ hash: -4046280218337247213
182
181
  required_rubygems_version: !ruby/object:Gem::Requirement
183
182
  none: false
184
183
  requirements:
@@ -187,8 +186,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
186
  version: '0'
188
187
  requirements: []
189
188
  rubyforge_project:
190
- rubygems_version: 1.7.2
189
+ rubygems_version: 1.8.15
191
190
  signing_key:
192
191
  specification_version: 3
193
- summary: A cross-website product/item information fetcher.
192
+ summary: A cross-website product/model information fetcher.
194
193
  test_files: []
@@ -1,8 +0,0 @@
1
- require "hashie"
2
-
3
- module Fletcher
4
- module Item
5
- class Image < ::Hashie::Mash
6
- end # Image
7
- end # Item
8
- end # Fletcher
@@ -1,37 +0,0 @@
1
- require "hashie"
2
-
3
- Factory.define :item, :class => Fletcher::Item::Base do |o|
4
- o.url "http://www.example.com"
5
- end
6
-
7
- Factory.define :sample_item, :parent => :item do |o|
8
- o.url "http://www.example.com"
9
- o.name "Sample Item"
10
- o.description "This is a sample description."
11
- o.raw_price "$5.00"
12
- end
13
-
14
- Factory.define :invalid_item, :parent => :item do |o|
15
- end
16
-
17
- Factory.define :valid_item, :parent => :item do |o|
18
- o.url "http://www.amazon.com/Kindle-Fire-Amazon-Tablet/dp/B0051VVOB2"
19
- o.title_xpath "//h1[@class='parseasinTitle']"
20
- o.images_xpath "//table[@class='productImageGrid']//img"
21
- end
22
-
23
- Factory.define :amazon_item, :parent => :item do |o|
24
- o.url "http://www.amazon.com/Kindle-Fire-Amazon-Tablet/dp/B0051VVOB2"
25
- end
26
-
27
- Factory.define :ebay_item, :parent => :item do |o|
28
- o.url "http://www.ebay.com/itm/24-Wheel-Leakproof-Butyl-Tire-Adjustable-Unicycle-Free-Stand-Cycling-Bike-Green-/370564417915"
29
- end
30
-
31
- Factory.define :thinkgeek_item, :parent => :item do |o|
32
- o.url "http://www.thinkgeek.com/geektoys/plush/e7f8/"
33
- end
34
-
35
- Factory.define :etsy_item, :parent => :item do |o|
36
- o.url "http://www.etsy.com/listing/78608690/farm-fresh-125-x-19-in-pick-your-color"
37
- end
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Fletcher::Item::Amazon do
4
- describe "parse" do
5
- context "with valid data" do
6
- it "should return correct item info" do
7
- item = described_class.new
8
- item.parse Fletcher::Data.read(Factory(:amazon_item).url)
9
- item.name.should_not be_nil
10
- item.description.should_not be_nil
11
- item.price.should_not be_nil
12
- item.image.should_not be_nil
13
- end
14
- end
15
- end
16
- end
@@ -1,15 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Fletcher::Item::Ebay do
4
- describe "parse" do
5
- context "with valid data" do
6
- it "should return correct item info" do
7
- item = described_class.new
8
- item.parse Fletcher::Data.read(Factory(:ebay_item).url)
9
- item.name.should_not be_nil
10
- item.price.should_not be_nil
11
- item.image.should_not be_nil
12
- end
13
- end
14
- end
15
- end
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Fletcher::Item::Etsy do
4
- describe "parse" do
5
- context "with valid data" do
6
- it "should return correct item info" do
7
- item = described_class.new
8
- item.parse Fletcher::Data.read(Factory(:etsy_item).url)
9
- item.name.should_not be_nil
10
- item.description.should_not be_nil
11
- item.price.should_not be_nil
12
- item.image.should_not be_nil
13
- end
14
- end
15
- end
16
- end
@@ -1,15 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Fletcher::Item::Thinkgeek do
4
- describe "parse" do
5
- context "with valid data" do
6
- it "should return correct item info" do
7
- item = described_class.new
8
- item.parse Fletcher::Data.read(Factory(:thinkgeek_item).url)
9
- item.name.should_not be_nil
10
- item.price.should_not be_nil
11
- item.image.should_not be_nil
12
- end
13
- end
14
- end
15
- end