fletcher 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +2 -2
- data/Gemfile +0 -1
- data/Gemfile.lock +24 -23
- data/README.md +1 -0
- data/Rakefile +15 -15
- data/VERSION +1 -1
- data/fletcher.gemspec +7 -5
- data/lib/fletcher.rb +28 -39
- data/lib/fletcher/model.rb +23 -0
- data/lib/fletcher/models/base.rb +4 -27
- data/lib/fletcher/models/googleshopping.rb +2 -1
- data/lib/fletcher/models/newegg.rb +31 -0
- data/lib/fletcher/models/thinkgeek.rb +1 -1
- data/lib/fletcher/string.rb +23 -1
- data/spec/factories/models.rb +8 -0
- data/spec/lib/fletcher/data_spec.rb +1 -1
- data/spec/lib/fletcher/model_spec.rb +19 -0
- data/spec/lib/fletcher/models/amazon_spec.rb +2 -2
- data/spec/lib/fletcher/models/base_spec.rb +12 -1
- data/spec/lib/fletcher/models/ebay_spec.rb +2 -2
- data/spec/lib/fletcher/models/etsy_spec.rb +2 -2
- data/spec/lib/fletcher/models/gamecouk_spec.rb +2 -2
- data/spec/lib/fletcher/models/googleshopping_spec.rb +2 -2
- data/spec/lib/fletcher/models/newegg_spec.rb +26 -0
- data/spec/lib/fletcher/models/playcom_spec.rb +2 -2
- data/spec/lib/fletcher/models/steam_spec.rb +2 -3
- data/spec/lib/fletcher/models/thinkgeek_spec.rb +3 -3
- data/spec/lib/fletcher/nokogiri_spec.rb +3 -3
- data/spec/lib/fletcher/string_spec.rb +4 -0
- data/spec/lib/fletcher_spec.rb +8 -12
- metadata +8 -19
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,39 +1,41 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
activesupport (3.2.
|
4
|
+
activesupport (3.2.9)
|
5
5
|
i18n (~> 0.6)
|
6
6
|
multi_json (~> 1.0)
|
7
7
|
diff-lcs (1.1.3)
|
8
|
-
factory_girl (
|
9
|
-
activesupport (>=
|
8
|
+
factory_girl (4.1.0)
|
9
|
+
activesupport (>= 3.0.0)
|
10
10
|
fakeweb (1.3.0)
|
11
11
|
git (1.2.5)
|
12
12
|
hashie (1.2.0)
|
13
|
-
i18n (0.6.
|
13
|
+
i18n (0.6.1)
|
14
14
|
jeweler (1.6.4)
|
15
15
|
bundler (~> 1.0)
|
16
16
|
git (>= 1.2.5)
|
17
17
|
rake
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
rspec-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
shoulda (
|
18
|
+
money (5.1.0)
|
19
|
+
i18n (~> 0.6.0)
|
20
|
+
multi_json (1.3.7)
|
21
|
+
nokogiri (1.5.5)
|
22
|
+
rake (10.0.1)
|
23
|
+
rspec (2.12.0)
|
24
|
+
rspec-core (~> 2.12.0)
|
25
|
+
rspec-expectations (~> 2.12.0)
|
26
|
+
rspec-mocks (~> 2.12.0)
|
27
|
+
rspec-core (2.12.0)
|
28
|
+
rspec-expectations (2.12.0)
|
29
|
+
diff-lcs (~> 1.1.3)
|
30
|
+
rspec-mocks (2.12.0)
|
31
|
+
shoulda (3.3.2)
|
32
|
+
shoulda-context (~> 1.0.1)
|
33
|
+
shoulda-matchers (~> 1.4.1)
|
34
|
+
shoulda-context (1.0.1)
|
35
|
+
shoulda-matchers (1.4.1)
|
36
|
+
activesupport (>= 3.0.0)
|
35
37
|
thor (0.16.0)
|
36
|
-
vcr (2.
|
38
|
+
vcr (2.3.0)
|
37
39
|
|
38
40
|
PLATFORMS
|
39
41
|
ruby
|
@@ -47,7 +49,6 @@ DEPENDENCIES
|
|
47
49
|
jeweler (~> 1.6.4)
|
48
50
|
money
|
49
51
|
nokogiri
|
50
|
-
rcov
|
51
52
|
rspec
|
52
53
|
shoulda
|
53
54
|
thor
|
data/README.md
CHANGED
@@ -16,6 +16,7 @@ Fletcher is a cross-website product information fetcher. Just give fletcher a pr
|
|
16
16
|
* [Etsy](http://www.etsy.com)
|
17
17
|
* [game.co.uk](http://www.game.co.uk)
|
18
18
|
* [Google Shopping](http://www.google.com/products/)
|
19
|
+
* [Newegg](http://www.newegg.com)
|
19
20
|
* [play.com](http://www.play.com)
|
20
21
|
* [Steam](http://store.steampowered.com)
|
21
22
|
* [ThinkGeek](http://www.thinkgeek.com)
|
data/Rakefile
CHANGED
@@ -33,22 +33,22 @@ Rake::TestTask.new(:test) do |test|
|
|
33
33
|
test.verbose = true
|
34
34
|
end
|
35
35
|
|
36
|
-
require 'rcov/rcovtask'
|
37
|
-
Rcov::RcovTask.new do |test|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
36
|
+
# require 'rcov/rcovtask'
|
37
|
+
# Rcov::RcovTask.new do |test|
|
38
|
+
# test.libs << 'test'
|
39
|
+
# test.pattern = 'test/**/test_*.rb'
|
40
|
+
# test.verbose = true
|
41
|
+
# test.rcov_opts << '--exclude "gems/*"'
|
42
|
+
# end
|
43
43
|
|
44
44
|
task :default => :test
|
45
45
|
|
46
|
-
require 'rake/rdoctask'
|
47
|
-
Rake::RDocTask.new do |rdoc|
|
48
|
-
|
46
|
+
# require 'rake/rdoctask'
|
47
|
+
# Rake::RDocTask.new do |rdoc|
|
48
|
+
# version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
50
|
+
# rdoc.rdoc_dir = 'rdoc'
|
51
|
+
# rdoc.title = "fletcher #{version}"
|
52
|
+
# rdoc.rdoc_files.include('README*')
|
53
|
+
# rdoc.rdoc_files.include('lib/**/*.rb')
|
54
|
+
# end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.2
|
data/fletcher.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "fletcher"
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.2"
|
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 = "2012-11-
|
12
|
+
s.date = "2012-11-16"
|
13
13
|
s.description = "Easily fetch product/model information from third party websites such as Amazon, eBay, etc."
|
14
14
|
s.email = "dave@hulihanapplications.com"
|
15
15
|
s.executables = ["fletcher"]
|
@@ -32,12 +32,14 @@ Gem::Specification.new do |s|
|
|
32
32
|
"lib/fletcher.rb",
|
33
33
|
"lib/fletcher/cli/utility.rb",
|
34
34
|
"lib/fletcher/data.rb",
|
35
|
+
"lib/fletcher/model.rb",
|
35
36
|
"lib/fletcher/models/amazon.rb",
|
36
37
|
"lib/fletcher/models/base.rb",
|
37
38
|
"lib/fletcher/models/ebay.rb",
|
38
39
|
"lib/fletcher/models/etsy.rb",
|
39
40
|
"lib/fletcher/models/gamecouk.rb",
|
40
41
|
"lib/fletcher/models/googleshopping.rb",
|
42
|
+
"lib/fletcher/models/newegg.rb",
|
41
43
|
"lib/fletcher/models/playcom.rb",
|
42
44
|
"lib/fletcher/models/steam.rb",
|
43
45
|
"lib/fletcher/models/thinkgeek.rb",
|
@@ -46,16 +48,19 @@ Gem::Specification.new do |s|
|
|
46
48
|
"spec/bin/fletcher_spec.rb",
|
47
49
|
"spec/factories/models.rb",
|
48
50
|
"spec/lib/fletcher/data_spec.rb",
|
51
|
+
"spec/lib/fletcher/model_spec.rb",
|
49
52
|
"spec/lib/fletcher/models/amazon_spec.rb",
|
50
53
|
"spec/lib/fletcher/models/base_spec.rb",
|
51
54
|
"spec/lib/fletcher/models/ebay_spec.rb",
|
52
55
|
"spec/lib/fletcher/models/etsy_spec.rb",
|
53
56
|
"spec/lib/fletcher/models/gamecouk_spec.rb",
|
54
57
|
"spec/lib/fletcher/models/googleshopping_spec.rb",
|
58
|
+
"spec/lib/fletcher/models/newegg_spec.rb",
|
55
59
|
"spec/lib/fletcher/models/playcom_spec.rb",
|
56
60
|
"spec/lib/fletcher/models/steam_spec.rb",
|
57
61
|
"spec/lib/fletcher/models/thinkgeek_spec.rb",
|
58
62
|
"spec/lib/fletcher/nokogiri_spec.rb",
|
63
|
+
"spec/lib/fletcher/string_spec.rb",
|
59
64
|
"spec/lib/fletcher_spec.rb",
|
60
65
|
"spec/spec_helper.rb",
|
61
66
|
"spec/support/benchmark.rb",
|
@@ -82,7 +87,6 @@ Gem::Specification.new do |s|
|
|
82
87
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
83
88
|
s.add_development_dependency(%q<bundler>, [">= 0"])
|
84
89
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
85
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
86
90
|
s.add_development_dependency(%q<rspec>, [">= 0"])
|
87
91
|
s.add_development_dependency(%q<factory_girl>, [">= 0"])
|
88
92
|
s.add_development_dependency(%q<i18n>, [">= 0"])
|
@@ -96,7 +100,6 @@ Gem::Specification.new do |s|
|
|
96
100
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
97
101
|
s.add_dependency(%q<bundler>, [">= 0"])
|
98
102
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
99
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
100
103
|
s.add_dependency(%q<rspec>, [">= 0"])
|
101
104
|
s.add_dependency(%q<factory_girl>, [">= 0"])
|
102
105
|
s.add_dependency(%q<i18n>, [">= 0"])
|
@@ -111,7 +114,6 @@ Gem::Specification.new do |s|
|
|
111
114
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
112
115
|
s.add_dependency(%q<bundler>, [">= 0"])
|
113
116
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
114
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
115
117
|
s.add_dependency(%q<rspec>, [">= 0"])
|
116
118
|
s.add_dependency(%q<factory_girl>, [">= 0"])
|
117
119
|
s.add_dependency(%q<i18n>, [">= 0"])
|
data/lib/fletcher.rb
CHANGED
@@ -3,53 +3,30 @@
|
|
3
3
|
require "uri"
|
4
4
|
|
5
5
|
require File.expand_path("fletcher/data", File.dirname(__FILE__))
|
6
|
+
require File.expand_path("fletcher/model", File.dirname(__FILE__))
|
6
7
|
require File.expand_path("fletcher/string", File.dirname(__FILE__))
|
7
8
|
require File.expand_path("fletcher/nokogiri", File.dirname(__FILE__))
|
8
9
|
|
9
10
|
module Fletcher
|
10
11
|
# Module Methods
|
11
|
-
class << self
|
12
|
-
# Detect model by url
|
13
|
-
# Fletcher.identify_model("http://www.amazon.com/whatever") # => :amazon
|
14
|
-
def identify_model(url)
|
15
|
-
if url =~ ::URI::regexp
|
16
|
-
uri = ::URI::parse(url)
|
17
|
-
host = uri.host
|
18
|
-
if host =~ Fletcher::Model::Amazon.regexp
|
19
|
-
model = :amazon
|
20
|
-
elsif host =~ Fletcher::Model::Ebay.regexp
|
21
|
-
model = :ebay
|
22
|
-
elsif host =~ Fletcher::Model::Etsy.regexp
|
23
|
-
model = :etsy
|
24
|
-
elsif host =~ Fletcher::Model::Gamecouk.regexp
|
25
|
-
model = :gamecouk
|
26
|
-
elsif host =~ Fletcher::Model::Googleshopping.regexp
|
27
|
-
model = :googleshopping
|
28
|
-
elsif host =~ Fletcher::Model::Playcom.regexp
|
29
|
-
model = :playcom
|
30
|
-
elsif host =~ Fletcher::Model::Thinkgeek.regexp
|
31
|
-
model = :thinkgeek
|
32
|
-
elsif host =~ Fletcher::Model::Steam.regexp
|
33
|
-
model = :steam
|
34
|
-
else
|
35
|
-
model = :unknown
|
36
|
-
raise ArgumentError, "Fletcher doesn't support #{host} yet."
|
37
|
-
end
|
38
|
-
else
|
39
|
-
raise ArgumentError, "not a url"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
12
|
+
class << self
|
43
13
|
# Fetch information based on url
|
44
14
|
def fetch(url)
|
45
|
-
model
|
15
|
+
# Look for model based on url
|
16
|
+
model_class = Fletcher::Model.identify(url)
|
17
|
+
|
18
|
+
# Use Base class for fallback
|
19
|
+
model_class = Fletcher::Model::Base unless model_class
|
20
|
+
|
46
21
|
data = Fletcher::Data.read(url)
|
47
|
-
|
48
|
-
|
49
|
-
|
22
|
+
|
23
|
+
product = model_class.new
|
24
|
+
product.parse(data)
|
25
|
+
|
26
|
+
# Save url
|
27
|
+
product.url = url
|
50
28
|
|
51
|
-
|
52
|
-
return model
|
29
|
+
return product
|
53
30
|
end
|
54
31
|
|
55
32
|
# Get gem version
|
@@ -62,6 +39,7 @@ module Fletcher
|
|
62
39
|
File.expand_path("../..", __FILE__)
|
63
40
|
end
|
64
41
|
|
42
|
+
# get array of models syms
|
65
43
|
def models
|
66
44
|
models = Array.new
|
67
45
|
Dir[File.join(File.dirname(__FILE__), "fletcher", "models", "*.rb")].each do |f|
|
@@ -70,6 +48,17 @@ module Fletcher
|
|
70
48
|
end
|
71
49
|
return models
|
72
50
|
end
|
51
|
+
|
52
|
+
# get array of model classes
|
53
|
+
# Fletcher.model_classes = [Amazon, Ebay, ThinkGeek]
|
54
|
+
def model_classes
|
55
|
+
models = Array.new
|
56
|
+
Dir[File.join(File.dirname(__FILE__), "fletcher", "models", "*.rb")].each do |f|
|
57
|
+
filename = File.basename(f, ".rb")
|
58
|
+
models << ["Fletcher", "Model", filename.camelize].join("::").constantize unless filename == "base"
|
59
|
+
end
|
60
|
+
return models
|
61
|
+
end
|
73
62
|
end
|
74
63
|
|
75
64
|
LIBRARY_PATH = File.join(File.dirname(__FILE__), 'fletcher')
|
@@ -85,7 +74,7 @@ module Fletcher
|
|
85
74
|
module Model
|
86
75
|
autoload :Base, File.join(MODEL_PATH, "base")
|
87
76
|
for model in Fletcher.models
|
88
|
-
autoload model.to_s.
|
77
|
+
autoload model.to_s.camelize.to_sym, File.join(MODEL_PATH, model.to_s)
|
89
78
|
end
|
90
79
|
end
|
91
80
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Fletcher
|
2
|
+
module Model
|
3
|
+
class << self
|
4
|
+
# Detect model by url
|
5
|
+
# Fletcher::Model.identify("http://www.amazon.com/whatever") # => Flether::Models::Amazon
|
6
|
+
def identify(url)
|
7
|
+
if url =~ ::URI::regexp
|
8
|
+
uri = ::URI::parse(url)
|
9
|
+
host = uri.host
|
10
|
+
matched_model = nil
|
11
|
+
for model in Fletcher.model_classes
|
12
|
+
#model_class =
|
13
|
+
matched_model = model if host =~ model.regexp
|
14
|
+
end
|
15
|
+
# raise ArgumentError, "Fletcher doesn't support #{host} yet." unless matched_model_class
|
16
|
+
return matched_model
|
17
|
+
else
|
18
|
+
raise ArgumentError, "not a url"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/fletcher/models/base.rb
CHANGED
@@ -4,37 +4,14 @@ require "money"
|
|
4
4
|
module Fletcher
|
5
5
|
module Model
|
6
6
|
class Base < ::Hashie::Mash
|
7
|
-
# Create a product object based on service
|
8
|
-
# Fletcher::Model::Base.generate(:amazon, "<html>...") # => #<Fletcher::Model::Amazon:0x...>
|
9
|
-
def self.generate(service = nil, data = nil)
|
10
|
-
case service
|
11
|
-
when :amazon
|
12
|
-
model = Fletcher::Model::Amazon.new
|
13
|
-
when :ebay
|
14
|
-
model = Fletcher::Model::Ebay.new
|
15
|
-
when :thinkgeek
|
16
|
-
model = Fletcher::Model::Thinkgeek.new
|
17
|
-
when :etsy
|
18
|
-
model = Fletcher::Model::Etsy.new
|
19
|
-
when :googleshopping
|
20
|
-
model = Fletcher::Model::Googleshopping.new
|
21
|
-
when :gamecouk
|
22
|
-
model = Fletcher::Model::Gamecouk.new
|
23
|
-
when :steam
|
24
|
-
model = Fletcher::Model::Steam.new
|
25
|
-
when :playcom
|
26
|
-
model = Fletcher::Model::Playcom.new
|
27
|
-
end
|
28
|
-
|
29
|
-
model.parse(data)
|
30
|
-
return model
|
31
|
-
end
|
32
|
-
|
33
7
|
# Parse data and set object attributes
|
34
8
|
def parse(data)
|
35
9
|
self.doc = data # save data for if user wants to access it later
|
10
|
+
|
11
|
+
# Get page title as name
|
12
|
+
self.name = doc.css("head > title").first_string
|
36
13
|
end
|
37
|
-
|
14
|
+
|
38
15
|
# Parse a raw price string to get usable data
|
39
16
|
# model.parse_price("$5.00") # => #<Money cents:500 currency:USD>
|
40
17
|
# model.price.to_f # => 5.0
|
@@ -12,7 +12,8 @@ module Fletcher
|
|
12
12
|
case doc
|
13
13
|
when Nokogiri::HTML::Document
|
14
14
|
# Get Name
|
15
|
-
|
15
|
+
name = doc.css('h1#product-name span.main-title').first_string
|
16
|
+
self.name = name if name
|
16
17
|
|
17
18
|
# Get Description
|
18
19
|
self.description = doc.css("div.product-desc-cont div.product-desc").first_string
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Fletcher
|
2
|
+
module Model
|
3
|
+
class Newegg < Fletcher::Model::Base
|
4
|
+
# A regular expression for determining if a url comes from a specific service/website
|
5
|
+
def self.regexp
|
6
|
+
/newegg\.com/
|
7
|
+
end
|
8
|
+
|
9
|
+
# Parse data and look for object attributes to give to object
|
10
|
+
def parse(data)
|
11
|
+
super(data)
|
12
|
+
case doc
|
13
|
+
when Nokogiri::HTML::Document
|
14
|
+
# Get Name
|
15
|
+
self.name = doc.css("#synopsis .grpDesc .wrapper h1 > span").first_string
|
16
|
+
#self.name = doc.css("#synopsis .grpDesc .wrapper > .span").first_string
|
17
|
+
|
18
|
+
# Description
|
19
|
+
self.description = doc.css("#fullInfo .itmDesc > p").first_string
|
20
|
+
|
21
|
+
# Get Price (currently disabled because price is displayed after page load)
|
22
|
+
#parse_price doc.css("li.price-current").attribute("content").content
|
23
|
+
|
24
|
+
# # Get Images
|
25
|
+
self.images = [{:src => doc.css('.mainSlide > img').attribute("src").content}]
|
26
|
+
self.image = images.first
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -14,7 +14,7 @@ module Fletcher
|
|
14
14
|
when Nokogiri::HTML::Document
|
15
15
|
# Get Name
|
16
16
|
self.name = doc.xpath("//meta[@property='og:title']/@content").first_string
|
17
|
-
|
17
|
+
|
18
18
|
# Get Description
|
19
19
|
self.description = doc.xpath("//meta[@property='og:description']/@content").first_string
|
20
20
|
|
data/lib/fletcher/string.rb
CHANGED
@@ -1,10 +1,32 @@
|
|
1
|
-
|
2
1
|
module Fletcher
|
3
2
|
# This class extends string functions
|
4
3
|
module String
|
5
4
|
def sanitize
|
6
5
|
self.strip
|
7
6
|
end
|
7
|
+
|
8
|
+
def camelize(first_letter_in_uppercase = true)
|
9
|
+
lower_case_and_underscored_word = self.dup.underscore
|
10
|
+
if first_letter_in_uppercase
|
11
|
+
lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
|
12
|
+
else
|
13
|
+
lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def constantize
|
18
|
+
self.split("::").inject(Module) {|acc, val| acc.const_get(val)}
|
19
|
+
end
|
20
|
+
|
21
|
+
def underscore
|
22
|
+
word = self.dup
|
23
|
+
word.gsub!(/::/, '/')
|
24
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
25
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
26
|
+
word.tr!("-", "_")
|
27
|
+
word.downcase!
|
28
|
+
word
|
29
|
+
end
|
8
30
|
end
|
9
31
|
end
|
10
32
|
|
data/spec/factories/models.rb
CHANGED
@@ -22,6 +22,10 @@ FactoryGirl.define do
|
|
22
22
|
images_xpath "//table[@class='productImageGrid']//img"
|
23
23
|
end
|
24
24
|
|
25
|
+
factory :unsupported, :parent => :base do
|
26
|
+
url "http://www.tigerdirect.com"
|
27
|
+
end
|
28
|
+
|
25
29
|
factory :amazon, :parent => :base do
|
26
30
|
url "http://www.amazon.com/gp/product/B004HZYA6E/"
|
27
31
|
end
|
@@ -31,6 +35,10 @@ FactoryGirl.define do
|
|
31
35
|
url "http://www.ebay.com/itm/Franklin-Library-3V-ESSAYS-MONTAIGNE-Leather-Great-Books-1979-Donald-Frame-/190654183378"
|
32
36
|
end
|
33
37
|
|
38
|
+
factory :newegg, :parent => :base do
|
39
|
+
url "http://www.newegg.com/Product/Product.aspx?Item=9SIA03E0004DP7"
|
40
|
+
end
|
41
|
+
|
34
42
|
factory :thinkgeek, :parent => :base do
|
35
43
|
url "http://www.thinkgeek.com/geektoys/plush/e7f8/"
|
36
44
|
end
|
@@ -9,7 +9,7 @@ describe Fletcher::Data do
|
|
9
9
|
|
10
10
|
describe "read" do
|
11
11
|
it "should return a valid document", :vcr do
|
12
|
-
doc = Fletcher::Data.read(
|
12
|
+
doc = Fletcher::Data.read(FactoryGirl.build(:valid).url)
|
13
13
|
end
|
14
14
|
|
15
15
|
# This is just a rough indicator of how long a data should take to download
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fletcher::Model do
|
4
|
+
describe "identify" do
|
5
|
+
it "should return the model when a valid url is used" do
|
6
|
+
described_class.identify(FactoryGirl.build(:amazon).url).should == Fletcher::Model::Amazon
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return nil when using an unsupported domain" do
|
10
|
+
described_class.identify(FactoryGirl.build(:invalid).url).should be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
# for model in Fletcher.model_classes
|
14
|
+
# it "should return #{model} sym when using a #{model} domain" do
|
15
|
+
# described_class.identify(FactoryGirl.build(model).url).should == model
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
end
|
19
|
+
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should fetch amazon product" do
|
6
|
-
item = described_class.fetch(
|
6
|
+
item = described_class.fetch(FactoryGirl.build(:amazon).url)
|
7
7
|
item.should_not be_nil
|
8
8
|
item.name.should_not be_nil
|
9
9
|
item.description.should_not be_nil
|
@@ -16,7 +16,7 @@ describe Fletcher::Model::Amazon do
|
|
16
16
|
context "with valid data" do
|
17
17
|
it "should return correct model info" do
|
18
18
|
model = described_class.new
|
19
|
-
model.parse Fletcher::Data.read(
|
19
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:amazon).url)
|
20
20
|
model.name.should_not be_nil
|
21
21
|
model.description.should_not be_nil
|
22
22
|
model.price.should_not be_nil
|
@@ -1,5 +1,16 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
+
describe Fletcher, :vcr do
|
4
|
+
describe :fetch, :vcr do
|
5
|
+
context "when using an unsupported website" do
|
6
|
+
it "should return meta title as name" do
|
7
|
+
item = described_class.fetch(FactoryGirl.build(:unsupported).url)
|
8
|
+
item.name.should_not be_nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
3
14
|
describe Fletcher::Model::Base do
|
4
15
|
describe "generate" do
|
5
16
|
end
|
@@ -11,7 +22,7 @@ describe Fletcher::Model::Base do
|
|
11
22
|
|
12
23
|
describe "parse_price", :vcr do
|
13
24
|
it "should return a price float and currency" do
|
14
|
-
model =
|
25
|
+
model = FactoryGirl.build(:sample)
|
15
26
|
model.parse_price(model.raw_price)
|
16
27
|
model.price.is_a?(Money).should == true
|
17
28
|
model.price.currency.should_not be_nil
|
@@ -4,7 +4,7 @@ describe Fletcher, :vcr do
|
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
# Force use of ebay cassette since auctions always end
|
6
6
|
it "should fetch ebay product", :vcr => { :cassette_name => "ebay_fetch" } do
|
7
|
-
item = described_class.fetch(
|
7
|
+
item = described_class.fetch(FactoryGirl.build(:ebay).url)
|
8
8
|
item.should_not be_nil
|
9
9
|
item.name.should_not be_nil
|
10
10
|
end
|
@@ -17,7 +17,7 @@ describe Fletcher::Model::Ebay, :vcr => { :cassette_name => "ebay_model" } do
|
|
17
17
|
# Diable Realtime Test, too inconsistent
|
18
18
|
it "should return correct model info" do
|
19
19
|
model = described_class.new
|
20
|
-
model.parse Fletcher::Data.read(
|
20
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:ebay).url)
|
21
21
|
model.name.should_not be_nil
|
22
22
|
model.price.should_not be_nil
|
23
23
|
model.image.should_not be_nil
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should fetch etsy product" do
|
6
|
-
item = described_class.fetch(
|
6
|
+
item = described_class.fetch(FactoryGirl.build(:etsy).url)
|
7
7
|
item.should_not be_nil
|
8
8
|
item.name.should_not be_nil
|
9
9
|
item.description.should_not be_nil
|
@@ -17,7 +17,7 @@ describe Fletcher::Model::Etsy, :vcr do
|
|
17
17
|
context "with valid data" do
|
18
18
|
it "should return correct model info" do
|
19
19
|
model = described_class.new
|
20
|
-
model.parse Fletcher::Data.read(
|
20
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:etsy).url)
|
21
21
|
model.name.should_not be_nil
|
22
22
|
model.description.should_not be_nil
|
23
23
|
model.price.should_not be_nil
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should fetch gamecouk product" do
|
6
|
-
item = described_class.fetch(
|
6
|
+
item = described_class.fetch(FactoryGirl.build(:gamecouk).url)
|
7
7
|
item.should_not be_nil
|
8
8
|
item.name.should_not be_nil
|
9
9
|
item.description.should_not be_nil
|
@@ -16,7 +16,7 @@ describe Fletcher::Model::Gamecouk, :vcr do
|
|
16
16
|
context "with valid data" do
|
17
17
|
it "should return correct model info" do
|
18
18
|
model = described_class.new
|
19
|
-
model.parse Fletcher::Data.read(
|
19
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:gamecouk).url)
|
20
20
|
model.name.should_not be_nil
|
21
21
|
model.description.should_not be_nil
|
22
22
|
model.price.should_not be_nil
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should fetch googleshopping product" do
|
6
|
-
item = described_class.fetch(
|
6
|
+
item = described_class.fetch(FactoryGirl.build(:googleshopping).url)
|
7
7
|
item.should_not be_nil
|
8
8
|
item.name.should_not be_nil
|
9
9
|
item.description.should_not be_nil
|
@@ -16,7 +16,7 @@ describe Fletcher::Model::Googleshopping, :vcr do
|
|
16
16
|
context "with valid data" do
|
17
17
|
it "should return correct model info" do
|
18
18
|
model = described_class.new
|
19
|
-
model.parse Fletcher::Data.read(
|
19
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:googleshopping).url)
|
20
20
|
model.name.should_not be_nil
|
21
21
|
model.description.should_not be_nil
|
22
22
|
model.price.should_not be_nil
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fletcher, :vcr do
|
4
|
+
describe :fetch, :vcr do
|
5
|
+
it "should return correct product info" do
|
6
|
+
product = Fletcher.fetch FactoryGirl.build(:newegg).url
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe Fletcher::Model::Newegg, :vcr do
|
12
|
+
describe "parse", :vcr do
|
13
|
+
context "with valid data" do
|
14
|
+
it "should return correct product info" do
|
15
|
+
product = described_class.new
|
16
|
+
product.parse Fletcher::Data.read(FactoryGirl.build(:newegg).url)
|
17
|
+
product.name.should_not be_nil
|
18
|
+
product.description.should_not be_nil
|
19
|
+
#product.price.should_not be_nil
|
20
|
+
product.images.should_not be_empty
|
21
|
+
product.image.should_not be_nil
|
22
|
+
product.image.src.should_not be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should fetch playcom product" do
|
6
|
-
item = described_class.fetch(
|
6
|
+
item = described_class.fetch(FactoryGirl.build(:playcom).url)
|
7
7
|
item.should_not be_nil
|
8
8
|
item.name.should_not be_nil
|
9
9
|
item.description.should_not be_nil
|
@@ -16,7 +16,7 @@ describe Fletcher::Model::Playcom, :vcr do
|
|
16
16
|
context "with valid data" do
|
17
17
|
it "should return correct model info" do
|
18
18
|
model = described_class.new
|
19
|
-
model.parse Fletcher::Data.read(
|
19
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:playcom).url)
|
20
20
|
model.doc = nil
|
21
21
|
model.name.should_not be_nil
|
22
22
|
model.description.should_not be_nil
|
@@ -3,8 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Fletcher, :vcr do
|
4
4
|
describe :fetch, :vcr do
|
5
5
|
it "should return correct model info" do
|
6
|
-
product = Fletcher.fetch
|
7
|
-
puts product.image.inspect
|
6
|
+
product = Fletcher.fetch FactoryGirl.build(:steam).url
|
8
7
|
end
|
9
8
|
end
|
10
9
|
end
|
@@ -14,7 +13,7 @@ describe Fletcher::Model::Steam, :vcr do
|
|
14
13
|
context "with valid data" do
|
15
14
|
it "should return correct model info" do
|
16
15
|
model = described_class.new
|
17
|
-
model.parse Fletcher::Data.read(
|
16
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:steam).url)
|
18
17
|
model.doc = nil
|
19
18
|
model.description = ''
|
20
19
|
model.name.should_not be_nil
|
@@ -9,7 +9,7 @@ end
|
|
9
9
|
describe Fletcher, :vcr do
|
10
10
|
describe :fetch, :vcr do
|
11
11
|
it "should fetch a thinkgeek product's information" do
|
12
|
-
item = Fletcher.fetch(
|
12
|
+
item = Fletcher.fetch(FactoryGirl.build(:thinkgeek).url)
|
13
13
|
item.should_not be_nil
|
14
14
|
item.image.should_not be_nil
|
15
15
|
item.name.should_not be_nil
|
@@ -17,7 +17,7 @@ describe Fletcher, :vcr do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should fetch a thinkgeek product with price range" do
|
20
|
-
item = Fletcher.fetch(
|
20
|
+
item = Fletcher.fetch(FactoryGirl.build(:thinkgeek_with_price_range).url)
|
21
21
|
item.should_not be_nil
|
22
22
|
item.image.should_not be_nil
|
23
23
|
item.name.should_not be_nil
|
@@ -31,7 +31,7 @@ describe Fletcher::Model::Thinkgeek, :vcr do
|
|
31
31
|
context "with valid data" do
|
32
32
|
it "should return correct model info" do
|
33
33
|
model = described_class.new
|
34
|
-
model.parse Fletcher::Data.read(
|
34
|
+
model.parse Fletcher::Data.read(FactoryGirl.build(:thinkgeek).url)
|
35
35
|
model.name.should_not be_nil
|
36
36
|
model.price.should_not be_nil
|
37
37
|
model.image.should_not be_nil
|
@@ -6,12 +6,12 @@ end
|
|
6
6
|
|
7
7
|
describe Fletcher::Nokogiri::XML::NodeSet, :vcr do
|
8
8
|
before :each do
|
9
|
-
@doc = Fletcher::Data.read(
|
9
|
+
@doc = Fletcher::Data.read(FactoryGirl.build(:valid).url)
|
10
10
|
end
|
11
11
|
|
12
12
|
describe "first_string", :vcr do
|
13
13
|
it "should return a valid string" do
|
14
|
-
nodeset = @doc.xpath(
|
14
|
+
nodeset = @doc.xpath(FactoryGirl.build(: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, :vcr do
|
|
19
19
|
|
20
20
|
describe "attribute_array", :vcr do
|
21
21
|
it "should return an array of attribute hashes" do
|
22
|
-
nodeset = @doc.xpath(
|
22
|
+
nodeset = @doc.xpath(FactoryGirl.build(:valid).images_xpath)
|
23
23
|
attribute_array = nodeset.attribute_array
|
24
24
|
attribute_array.class.should == Array
|
25
25
|
end
|
data/spec/lib/fletcher_spec.rb
CHANGED
@@ -8,19 +8,15 @@ describe Fletcher, :vcr do
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
it "should return #{model} sym when using a #{model} domain" do
|
19
|
-
described_class.identify_model(Factory(model).url).should == model
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
11
|
+
describe :model_classes do
|
12
|
+
it "should return an array of classes" do
|
13
|
+
models = described_class.model_classes
|
14
|
+
models.is_a?(Array).should == true
|
15
|
+
models.first.class.should == Class
|
16
|
+
end
|
17
|
+
end
|
23
18
|
|
19
|
+
context :models do
|
24
20
|
describe :fetch, :vcr do
|
25
21
|
# for model in Fletcher.models
|
26
22
|
# it "should return valid data for #{model} model" do
|
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.6.
|
4
|
+
version: 0.6.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-11-
|
13
|
+
date: 2012-11-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: hashie
|
@@ -124,22 +124,6 @@ dependencies:
|
|
124
124
|
- - ~>
|
125
125
|
- !ruby/object:Gem::Version
|
126
126
|
version: 1.6.4
|
127
|
-
- !ruby/object:Gem::Dependency
|
128
|
-
name: rcov
|
129
|
-
requirement: !ruby/object:Gem::Requirement
|
130
|
-
none: false
|
131
|
-
requirements:
|
132
|
-
- - ! '>='
|
133
|
-
- !ruby/object:Gem::Version
|
134
|
-
version: '0'
|
135
|
-
type: :development
|
136
|
-
prerelease: false
|
137
|
-
version_requirements: !ruby/object:Gem::Requirement
|
138
|
-
none: false
|
139
|
-
requirements:
|
140
|
-
- - ! '>='
|
141
|
-
- !ruby/object:Gem::Version
|
142
|
-
version: '0'
|
143
127
|
- !ruby/object:Gem::Dependency
|
144
128
|
name: rspec
|
145
129
|
requirement: !ruby/object:Gem::Requirement
|
@@ -244,12 +228,14 @@ files:
|
|
244
228
|
- lib/fletcher.rb
|
245
229
|
- lib/fletcher/cli/utility.rb
|
246
230
|
- lib/fletcher/data.rb
|
231
|
+
- lib/fletcher/model.rb
|
247
232
|
- lib/fletcher/models/amazon.rb
|
248
233
|
- lib/fletcher/models/base.rb
|
249
234
|
- lib/fletcher/models/ebay.rb
|
250
235
|
- lib/fletcher/models/etsy.rb
|
251
236
|
- lib/fletcher/models/gamecouk.rb
|
252
237
|
- lib/fletcher/models/googleshopping.rb
|
238
|
+
- lib/fletcher/models/newegg.rb
|
253
239
|
- lib/fletcher/models/playcom.rb
|
254
240
|
- lib/fletcher/models/steam.rb
|
255
241
|
- lib/fletcher/models/thinkgeek.rb
|
@@ -258,16 +244,19 @@ files:
|
|
258
244
|
- spec/bin/fletcher_spec.rb
|
259
245
|
- spec/factories/models.rb
|
260
246
|
- spec/lib/fletcher/data_spec.rb
|
247
|
+
- spec/lib/fletcher/model_spec.rb
|
261
248
|
- spec/lib/fletcher/models/amazon_spec.rb
|
262
249
|
- spec/lib/fletcher/models/base_spec.rb
|
263
250
|
- spec/lib/fletcher/models/ebay_spec.rb
|
264
251
|
- spec/lib/fletcher/models/etsy_spec.rb
|
265
252
|
- spec/lib/fletcher/models/gamecouk_spec.rb
|
266
253
|
- spec/lib/fletcher/models/googleshopping_spec.rb
|
254
|
+
- spec/lib/fletcher/models/newegg_spec.rb
|
267
255
|
- spec/lib/fletcher/models/playcom_spec.rb
|
268
256
|
- spec/lib/fletcher/models/steam_spec.rb
|
269
257
|
- spec/lib/fletcher/models/thinkgeek_spec.rb
|
270
258
|
- spec/lib/fletcher/nokogiri_spec.rb
|
259
|
+
- spec/lib/fletcher/string_spec.rb
|
271
260
|
- spec/lib/fletcher_spec.rb
|
272
261
|
- spec/spec_helper.rb
|
273
262
|
- spec/support/benchmark.rb
|
@@ -291,7 +280,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
291
280
|
version: '0'
|
292
281
|
segments:
|
293
282
|
- 0
|
294
|
-
hash:
|
283
|
+
hash: -4007123474311124799
|
295
284
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
296
285
|
none: false
|
297
286
|
requirements:
|