fletcher 0.3.0 → 0.4.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/.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