fletcher 0.2.0 → 0.3.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/.travis.yml +2 -1
- data/Gemfile +2 -0
- data/Gemfile.lock +7 -0
- data/README.md +12 -3
- data/VERSION +1 -1
- data/fletcher.gemspec +8 -2
- data/lib/fletcher.rb +10 -0
- data/lib/fletcher/item/amazon.rb +3 -0
- data/lib/fletcher/item/base.rb +10 -0
- data/lib/fletcher/item/ebay.rb +3 -0
- data/lib/fletcher/item/etsy.rb +3 -0
- data/lib/fletcher/item/thinkgeek.rb +3 -0
- data/spec/factories/item.rb +8 -1
- data/spec/lib/fletcher/data_spec.rb +1 -1
- data/spec/lib/fletcher/item/amazon_spec.rb +1 -0
- data/spec/lib/fletcher/item/base_spec.rb +9 -0
- data/spec/lib/fletcher/item/ebay_spec.rb +2 -1
- data/spec/lib/fletcher/item/etsy_spec.rb +1 -0
- data/spec/lib/fletcher/item/thinkgeek_spec.rb +1 -0
- data/spec/lib/fletcher_spec.rb +6 -0
- metadata +41 -19
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -8,10 +8,15 @@ GEM
|
|
8
8
|
activesupport
|
9
9
|
git (1.2.5)
|
10
10
|
hashie (1.2.0)
|
11
|
+
i18n (0.6.0)
|
11
12
|
jeweler (1.6.4)
|
12
13
|
bundler (~> 1.0)
|
13
14
|
git (>= 1.2.5)
|
14
15
|
rake
|
16
|
+
json (1.6.4)
|
17
|
+
money (4.0.1)
|
18
|
+
i18n (~> 0.4)
|
19
|
+
json
|
15
20
|
multi_json (1.0.4)
|
16
21
|
nokogiri (1.5.0)
|
17
22
|
rake (0.9.2)
|
@@ -33,7 +38,9 @@ DEPENDENCIES
|
|
33
38
|
bundler (~> 1.0.0)
|
34
39
|
factory_girl
|
35
40
|
hashie
|
41
|
+
i18n
|
36
42
|
jeweler (~> 1.6.4)
|
43
|
+
money
|
37
44
|
nokogiri
|
38
45
|
rcov
|
39
46
|
rspec
|
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
# Fletcher
|
1
|
+
# Fletcher
|
2
|
+
[](http://travis-ci.org/hulihanapplications/fletcher)
|
3
|
+
|
2
4
|
|
3
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.
|
4
6
|
|
@@ -9,7 +11,7 @@ Fletcher is a cross-website product/item information fetcher. Give fletcher a pr
|
|
9
11
|
|
10
12
|
## Supported Websites
|
11
13
|
|
12
|
-
* [Amazon](http://www.amazon.com) (name, description, images)
|
14
|
+
* [Amazon](http://www.amazon.com) (name, description, price, images)
|
13
15
|
* [eBay](http://www.ebay.com) (name, images)
|
14
16
|
* [ThinkGeek](http://www.thinkgeek.com) (name, description, images)
|
15
17
|
* [Etsy](http://www.etsy.com) (name, description, images)
|
@@ -23,7 +25,9 @@ gem install fletcher
|
|
23
25
|
## Examples
|
24
26
|
|
25
27
|
```ruby
|
26
|
-
|
28
|
+
require "fletcher"
|
29
|
+
|
30
|
+
item = Fletcher.fetch # => "http://www.amazon.com/Avenir-Deluxe-Unicycle-20-Inch-Wheel/dp/B00165Q9F8"
|
27
31
|
|
28
32
|
item.name # => "Avenir Deluxe Unicycle (20-Inch Wheel)"
|
29
33
|
|
@@ -33,6 +37,10 @@ item.image # => {:url => "http://ecx.images-amazon.com/images/I/41b3TNb3uCL._SL5
|
|
33
37
|
|
34
38
|
item.image.url # => "http://ecx.images-amazon.com/images/I/41b3TNb3uCL._SL500_AA300_.jpg"
|
35
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 # => "$"
|
36
44
|
|
37
45
|
# Get Raw Nokogiri Document
|
38
46
|
item.doc.class.name # => Nokogiri::HTML::Document
|
@@ -44,6 +52,7 @@ The following attributes are available from items:
|
|
44
52
|
|
45
53
|
* title - (String) The name of the item/product
|
46
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.
|
47
56
|
* image - (Hash) The main image of the item
|
48
57
|
* images - (Array) Any available images of the item
|
49
58
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/fletcher.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{fletcher}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.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{
|
12
|
+
s.date = %q{2012-01-01}
|
13
13
|
s.description = %q{Easily fetch product/item information from third party websites such as Amazon, eBay, etc.}
|
14
14
|
s.email = %q{dave@hulihanapplications.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -62,31 +62,37 @@ Gem::Specification.new do |s|
|
|
62
62
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
63
63
|
s.add_runtime_dependency(%q<hashie>, [">= 0"])
|
64
64
|
s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
|
65
|
+
s.add_runtime_dependency(%q<money>, [">= 0"])
|
65
66
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
66
67
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
67
68
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
68
69
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
69
70
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
70
71
|
s.add_development_dependency(%q<factory_girl>, [">= 0"])
|
72
|
+
s.add_development_dependency(%q<i18n>, [">= 0"])
|
71
73
|
else
|
72
74
|
s.add_dependency(%q<hashie>, [">= 0"])
|
73
75
|
s.add_dependency(%q<nokogiri>, [">= 0"])
|
76
|
+
s.add_dependency(%q<money>, [">= 0"])
|
74
77
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
75
78
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
76
79
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
77
80
|
s.add_dependency(%q<rcov>, [">= 0"])
|
78
81
|
s.add_dependency(%q<rspec>, [">= 0"])
|
79
82
|
s.add_dependency(%q<factory_girl>, [">= 0"])
|
83
|
+
s.add_dependency(%q<i18n>, [">= 0"])
|
80
84
|
end
|
81
85
|
else
|
82
86
|
s.add_dependency(%q<hashie>, [">= 0"])
|
83
87
|
s.add_dependency(%q<nokogiri>, [">= 0"])
|
88
|
+
s.add_dependency(%q<money>, [">= 0"])
|
84
89
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
85
90
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
86
91
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
87
92
|
s.add_dependency(%q<rcov>, [">= 0"])
|
88
93
|
s.add_dependency(%q<rspec>, [">= 0"])
|
89
94
|
s.add_dependency(%q<factory_girl>, [">= 0"])
|
95
|
+
s.add_dependency(%q<i18n>, [">= 0"])
|
90
96
|
end
|
91
97
|
end
|
92
98
|
|
data/lib/fletcher.rb
CHANGED
@@ -55,4 +55,14 @@ module Fletcher
|
|
55
55
|
item.parse(data)
|
56
56
|
return item
|
57
57
|
end
|
58
|
+
|
59
|
+
# Get gem version
|
60
|
+
def self.version
|
61
|
+
File.read(File.join(root, "VERSION"))
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get gem root directory
|
65
|
+
def self.root
|
66
|
+
File.expand_path("../..", __FILE__)
|
67
|
+
end
|
58
68
|
end
|
data/lib/fletcher/item/amazon.rb
CHANGED
@@ -22,6 +22,9 @@ module Fletcher
|
|
22
22
|
# Get description from meta title if not found
|
23
23
|
self.description = doc.xpath("//meta[@name='description']/@content").first_string if description.nil?
|
24
24
|
|
25
|
+
# Get Price
|
26
|
+
parse_price(doc.css("b.priceLarge").first_string)
|
27
|
+
|
25
28
|
# Get Images
|
26
29
|
self.images = doc.xpath("//table[@class='productImageGrid']//img").attribute_array
|
27
30
|
self.image = images.first
|
data/lib/fletcher/item/base.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "hashie"
|
2
|
+
require "money"
|
2
3
|
|
3
4
|
module Fletcher
|
4
5
|
module Item
|
@@ -25,6 +26,15 @@ module Fletcher
|
|
25
26
|
def parse(data)
|
26
27
|
self.doc = data # save data for if user wants to access it later
|
27
28
|
end
|
29
|
+
|
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 # => '$'
|
34
|
+
def parse_price(raw_price = nil)
|
35
|
+
return if raw_price.nil?
|
36
|
+
self.price = ::Money.parse(raw_price)
|
37
|
+
end
|
28
38
|
end # Base
|
29
39
|
end # Item
|
30
40
|
end # Fletcher
|
data/lib/fletcher/item/ebay.rb
CHANGED
@@ -18,6 +18,9 @@ module Fletcher
|
|
18
18
|
|
19
19
|
# Get Description
|
20
20
|
# OMITTED: This is tough to get because ebay item descriptions are custom html/content created by sellers
|
21
|
+
|
22
|
+
# Get Price
|
23
|
+
parse_price(doc.xpath("//span[@itemprop='price']").first_string.gsub(/US/, ""))
|
21
24
|
|
22
25
|
# Get Image
|
23
26
|
self.images = [{:url => doc.xpath("//span[@itemprop='image']/img").first_string}]
|
data/lib/fletcher/item/etsy.rb
CHANGED
@@ -18,6 +18,9 @@ module Fletcher
|
|
18
18
|
|
19
19
|
# Get Description
|
20
20
|
self.description = doc.xpath("//div[@id='item-description']/div[@class='section-content']").first_string
|
21
|
+
|
22
|
+
# Get Price
|
23
|
+
parse_price(doc.xpath("//div[@class='item-amount']").first_string)
|
21
24
|
|
22
25
|
# Get Images
|
23
26
|
self.images = doc.xpath("//div[@id='item-main']//div[@id='fullimage_link1']//img").attribute_array
|
@@ -19,6 +19,9 @@ module Fletcher
|
|
19
19
|
# Get Description
|
20
20
|
self.description = doc.xpath("//meta[@property='og:description']/@content").first_string
|
21
21
|
|
22
|
+
# Get Price
|
23
|
+
parse_price(doc.xpath("//form[@id='buy']/h3").first_string)
|
24
|
+
|
22
25
|
# Get Images
|
23
26
|
self.images = [{:url => doc.xpath("//meta[@property='og:image']/@content").first_string}]
|
24
27
|
self.image = images.first
|
data/spec/factories/item.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
1
|
require "hashie"
|
2
2
|
|
3
|
-
Factory.define :item, :class =>
|
3
|
+
Factory.define :item, :class => Fletcher::Item::Base do |o|
|
4
4
|
o.url "http://www.example.com"
|
5
5
|
end
|
6
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
|
+
|
7
14
|
Factory.define :invalid_item, :parent => :item do |o|
|
8
15
|
end
|
9
16
|
|
@@ -14,7 +14,7 @@ describe Fletcher::Data do
|
|
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(
|
17
|
+
# benchmark{ doc = Fletcher::Data.read(Factory(:valid_item).url)}.should_not be_slower_than(5.0)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -8,4 +8,13 @@ describe Fletcher::Item::Base do
|
|
8
8
|
it "should create properly" do
|
9
9
|
end
|
10
10
|
end
|
11
|
+
|
12
|
+
describe "parse_price" do
|
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
|
18
|
+
end
|
19
|
+
end
|
11
20
|
end
|
@@ -5,8 +5,9 @@ describe Fletcher::Item::Ebay do
|
|
5
5
|
context "with valid data" do
|
6
6
|
it "should return correct item info" do
|
7
7
|
item = described_class.new
|
8
|
-
item.parse Fletcher::Data.read(Factory(:ebay_item).url)
|
8
|
+
item.parse Fletcher::Data.read(Factory(:ebay_item).url)
|
9
9
|
item.name.should_not be_nil
|
10
|
+
item.price.should_not be_nil
|
10
11
|
item.image.should_not be_nil
|
11
12
|
end
|
12
13
|
end
|
data/spec/lib/fletcher_spec.rb
CHANGED
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.
|
4
|
+
version: 0.3.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:
|
13
|
+
date: 2012-01-01 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: hashie
|
17
|
-
requirement: &
|
17
|
+
requirement: &71525050 !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: *
|
25
|
+
version_requirements: *71525050
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: nokogiri
|
28
|
-
requirement: &
|
28
|
+
requirement: &71524600 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,10 +33,21 @@ dependencies:
|
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *71524600
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: money
|
39
|
+
requirement: &71524080 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *71524080
|
37
48
|
- !ruby/object:Gem::Dependency
|
38
49
|
name: shoulda
|
39
|
-
requirement: &
|
50
|
+
requirement: &71523400 !ruby/object:Gem::Requirement
|
40
51
|
none: false
|
41
52
|
requirements:
|
42
53
|
- - ! '>='
|
@@ -44,10 +55,10 @@ dependencies:
|
|
44
55
|
version: '0'
|
45
56
|
type: :development
|
46
57
|
prerelease: false
|
47
|
-
version_requirements: *
|
58
|
+
version_requirements: *71523400
|
48
59
|
- !ruby/object:Gem::Dependency
|
49
60
|
name: bundler
|
50
|
-
requirement: &
|
61
|
+
requirement: &71522560 !ruby/object:Gem::Requirement
|
51
62
|
none: false
|
52
63
|
requirements:
|
53
64
|
- - ~>
|
@@ -55,10 +66,10 @@ dependencies:
|
|
55
66
|
version: 1.0.0
|
56
67
|
type: :development
|
57
68
|
prerelease: false
|
58
|
-
version_requirements: *
|
69
|
+
version_requirements: *71522560
|
59
70
|
- !ruby/object:Gem::Dependency
|
60
71
|
name: jeweler
|
61
|
-
requirement: &
|
72
|
+
requirement: &71521590 !ruby/object:Gem::Requirement
|
62
73
|
none: false
|
63
74
|
requirements:
|
64
75
|
- - ~>
|
@@ -66,10 +77,10 @@ dependencies:
|
|
66
77
|
version: 1.6.4
|
67
78
|
type: :development
|
68
79
|
prerelease: false
|
69
|
-
version_requirements: *
|
80
|
+
version_requirements: *71521590
|
70
81
|
- !ruby/object:Gem::Dependency
|
71
82
|
name: rcov
|
72
|
-
requirement: &
|
83
|
+
requirement: &71520830 !ruby/object:Gem::Requirement
|
73
84
|
none: false
|
74
85
|
requirements:
|
75
86
|
- - ! '>='
|
@@ -77,10 +88,10 @@ dependencies:
|
|
77
88
|
version: '0'
|
78
89
|
type: :development
|
79
90
|
prerelease: false
|
80
|
-
version_requirements: *
|
91
|
+
version_requirements: *71520830
|
81
92
|
- !ruby/object:Gem::Dependency
|
82
93
|
name: rspec
|
83
|
-
requirement: &
|
94
|
+
requirement: &71519900 !ruby/object:Gem::Requirement
|
84
95
|
none: false
|
85
96
|
requirements:
|
86
97
|
- - ! '>='
|
@@ -88,10 +99,21 @@ dependencies:
|
|
88
99
|
version: '0'
|
89
100
|
type: :development
|
90
101
|
prerelease: false
|
91
|
-
version_requirements: *
|
102
|
+
version_requirements: *71519900
|
92
103
|
- !ruby/object:Gem::Dependency
|
93
104
|
name: factory_girl
|
94
|
-
requirement: &
|
105
|
+
requirement: &71519240 !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
type: :development
|
112
|
+
prerelease: false
|
113
|
+
version_requirements: *71519240
|
114
|
+
- !ruby/object:Gem::Dependency
|
115
|
+
name: i18n
|
116
|
+
requirement: &71518690 !ruby/object:Gem::Requirement
|
95
117
|
none: false
|
96
118
|
requirements:
|
97
119
|
- - ! '>='
|
@@ -99,7 +121,7 @@ dependencies:
|
|
99
121
|
version: '0'
|
100
122
|
type: :development
|
101
123
|
prerelease: false
|
102
|
-
version_requirements: *
|
124
|
+
version_requirements: *71518690
|
103
125
|
description: Easily fetch product/item information from third party websites such
|
104
126
|
as Amazon, eBay, etc.
|
105
127
|
email: dave@hulihanapplications.com
|
@@ -156,7 +178,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
156
178
|
version: '0'
|
157
179
|
segments:
|
158
180
|
- 0
|
159
|
-
hash:
|
181
|
+
hash: -857180173
|
160
182
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
183
|
none: false
|
162
184
|
requirements:
|