kosher 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/Gemfile +1 -2
- data/LICENSE +13 -22
- data/README.md +2 -4
- data/kosher.gemspec +19 -11
- data/lib/kosher/algorithm.rb +19 -0
- data/lib/kosher/condition.rb +32 -0
- data/lib/kosher/description.rb +59 -0
- data/lib/kosher/item.rb +26 -0
- data/lib/kosher/offer.rb +34 -0
- data/lib/kosher/request.rb +28 -0
- data/lib/kosher/seller.rb +28 -0
- data/lib/kosher/version.rb +1 -1
- data/lib/kosher.rb +10 -5
- data/spec/fabricators/condition_fabricator.rb +7 -0
- data/spec/fabricators/offer_fabricator.rb +8 -0
- data/spec/fabricators/seller_fabricator.rb +15 -0
- data/spec/fixtures/cassette_library/0143105825.yml +112 -0
- data/spec/fixtures/cassette_library/batch-request.yml +22388 -0
- data/spec/kosher/algorithm_spec.rb +38 -0
- data/spec/kosher/condition_spec.rb +31 -0
- data/spec/kosher/{string_spec.rb → description_spec.rb} +8 -4
- data/spec/kosher/item_spec.rb +35 -0
- data/spec/kosher/offer_spec.rb +123 -0
- data/spec/kosher/request_spec.rb +42 -0
- data/spec/kosher/seller_spec.rb +65 -0
- data/spec/spec_helper.rb +5 -4
- data/spec/support/credentials.rb +3 -0
- data/spec/support/faker.rb +19 -0
- data/spec/support/vcr.rb +12 -0
- metadata +114 -32
- data/.rspec +0 -2
- data/.rvmrc +0 -1
- data/lib/kosher/regexps.rb +0 -7
- data/lib/kosher/string.rb +0 -50
- data/spec/kosher_spec.rb +0 -9
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/LICENSE
CHANGED
@@ -1,22 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
2
|
+
Version 2, December 2004
|
3
|
+
|
4
|
+
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
5
|
+
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
7
|
+
copies of this license document, and changing it is allowed as long
|
8
|
+
as the name is changed.
|
9
|
+
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
12
|
+
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
Kosher
|
2
2
|
======
|
3
3
|
|
4
|
-
|
4
|
+
Kosher wraps Amazon in a loving embrace.
|
5
5
|
|
6
|
-
|
7
|
-
description.kosher?
|
8
|
-
=> false
|
6
|
+

|
data/kosher.gemspec
CHANGED
@@ -1,23 +1,31 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
$:.push File.expand_path(
|
3
|
-
require
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'kosher/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
|
-
s.name =
|
6
|
+
s.name = 'kosher'
|
7
7
|
s.version = Kosher::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.authors = [
|
10
|
-
s.email =
|
11
|
-
s.homepage =
|
12
|
-
s.summary = %q{
|
13
|
-
s.description = %q{
|
9
|
+
s.authors = ['Paper Cavalier']
|
10
|
+
s.email = 'code@papercavalier.com'
|
11
|
+
s.homepage = 'https://rubygems.org/gems/kosher'
|
12
|
+
s.summary = %q{Wraps Amazon in a loving embrace.}
|
13
|
+
s.description = %q{Kosher wraps Amazon in a loving embrace.}
|
14
14
|
|
15
|
-
s.rubyforge_project =
|
15
|
+
s.rubyforge_project = 'kosher'
|
16
16
|
|
17
17
|
s.files = `git ls-files`.split("\n")
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
-
s.require_paths = [
|
20
|
+
s.require_paths = ['lib']
|
21
21
|
|
22
|
-
s.
|
22
|
+
s.add_dependency('sucker', '~> 1.3.1')
|
23
|
+
s.add_dependency('throttler', '~> 0.2.4')
|
24
|
+
s.add_development_dependency('fabrication', '~> 0.9.5')
|
25
|
+
s.add_development_dependency('rspec', '~> 2.5.0')
|
26
|
+
if RUBY_VERSION.include? '1.9'
|
27
|
+
s.add_development_dependency('ruby-debug19', '~> 0.11.6')
|
28
|
+
end
|
29
|
+
s.add_development_dependency('vcr', '~> 1.7.0')
|
30
|
+
s.add_development_dependency('webmock', '~> 1.6.2')
|
23
31
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Kosher
|
2
|
+
class Algorithm
|
3
|
+
def initialize(response)
|
4
|
+
@response = response
|
5
|
+
end
|
6
|
+
|
7
|
+
def items
|
8
|
+
@response.map('Item') do |item|
|
9
|
+
Item.build(item)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def errors
|
14
|
+
@response.errors.map do |error|
|
15
|
+
error['Message'].scan(/[0-9A-Z]{10}/).first rescue nil
|
16
|
+
end.compact
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Kosher
|
2
|
+
class Condition < Struct.new(:in_words)
|
3
|
+
def to_i
|
4
|
+
case in_words
|
5
|
+
when 'new'
|
6
|
+
1
|
7
|
+
when 'mint'
|
8
|
+
2
|
9
|
+
when 'verygood'
|
10
|
+
3
|
11
|
+
when 'good'
|
12
|
+
4
|
13
|
+
when 'acceptable'
|
14
|
+
5
|
15
|
+
else
|
16
|
+
6
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def kosher?
|
21
|
+
to_i <= 4
|
22
|
+
end
|
23
|
+
|
24
|
+
def new?
|
25
|
+
in_words == 'new'
|
26
|
+
end
|
27
|
+
|
28
|
+
def used?
|
29
|
+
!new?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Kosher
|
2
|
+
class Description < String
|
3
|
+
DAMAGED = "\\b(?:missing|torn|broken|split|discard|withdrawn|rent|stain|school|damaged|water)"
|
4
|
+
EXLIB = "(?:e?x|discarded|retired|former|has|have)[\\s._-]*lib"
|
5
|
+
MARKED = "(highlight|hilit|underlin)"
|
6
|
+
MISSING_VOL = "(vols?|volume) only"
|
7
|
+
REVIEW_COPY = "\\b(?:uncorrected|advanced?\\sreview|arc)\\b"
|
8
|
+
|
9
|
+
def kosher?
|
10
|
+
!(present? && bad?)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def bad?
|
16
|
+
damaged? ||
|
17
|
+
ex_library? ||
|
18
|
+
marked? ||
|
19
|
+
missing_volume? ||
|
20
|
+
review_copy?
|
21
|
+
end
|
22
|
+
|
23
|
+
def damaged?
|
24
|
+
matches(DAMAGED)
|
25
|
+
end
|
26
|
+
|
27
|
+
def does_not_match(value)
|
28
|
+
!match(Regexp.new(value, true))
|
29
|
+
end
|
30
|
+
|
31
|
+
def ex_library?
|
32
|
+
matches(EXLIB) && does_not_match(negation_of(EXLIB))
|
33
|
+
end
|
34
|
+
|
35
|
+
def marked?
|
36
|
+
matches(MARKED) && does_not_match(negation_of(MARKED))
|
37
|
+
end
|
38
|
+
|
39
|
+
def matches(value)
|
40
|
+
!does_not_match(value)
|
41
|
+
end
|
42
|
+
|
43
|
+
def missing_volume?
|
44
|
+
matches(MISSING_VOL)
|
45
|
+
end
|
46
|
+
|
47
|
+
def negation_of(value)
|
48
|
+
"(?:no|not an?)\\s+#{value}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def present?
|
52
|
+
self != ''
|
53
|
+
end
|
54
|
+
|
55
|
+
def review_copy?
|
56
|
+
matches(REVIEW_COPY)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/kosher/item.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Kosher
|
2
|
+
class Item < Struct.new(:asin, :offers)
|
3
|
+
|
4
|
+
def self.build(doc)
|
5
|
+
asin = doc['ASIN']
|
6
|
+
offers = build_offers(doc['Offers']['Offer'])
|
7
|
+
|
8
|
+
new(asin, offers)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def self.build_offers(offers)
|
14
|
+
[offers].flatten.compact.map do |offer|
|
15
|
+
|
16
|
+
# Senify Yen because Ruby Money says so
|
17
|
+
price = offer['OfferListing']['Price']
|
18
|
+
if price['CurrencyCode'] == 'JPY'
|
19
|
+
price['Amount'] = price['Amount'].to_i * 100
|
20
|
+
end
|
21
|
+
|
22
|
+
Offer.build(offer)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/kosher/offer.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Kosher
|
2
|
+
class Offer < Struct.new(
|
3
|
+
:seller,
|
4
|
+
:condition,
|
5
|
+
:description,
|
6
|
+
:ships_in,
|
7
|
+
:ships_free,
|
8
|
+
:cents)
|
9
|
+
|
10
|
+
def self.build(doc)
|
11
|
+
offer = new
|
12
|
+
offer.seller = Seller.build(doc['Merchant'])
|
13
|
+
|
14
|
+
attributes = doc['OfferAttributes']
|
15
|
+
offer.condition = Condition.new(attributes['SubCondition'])
|
16
|
+
offer.description = Description.new(attributes['ConditionNote'].to_s)
|
17
|
+
|
18
|
+
listing = doc['OfferListing']
|
19
|
+
offer.ships_in = listing['AvailabilityAttributes']['MaximumHours'].to_i
|
20
|
+
offer.ships_free = listing['IsEligibleForSuperSaverShipping'] == '1'
|
21
|
+
offer.cents = listing['Price']['Amount'].to_i
|
22
|
+
|
23
|
+
offer
|
24
|
+
end
|
25
|
+
|
26
|
+
def kosher?
|
27
|
+
condition.kosher? && seller.kosher? && description.kosher? && ships_now?
|
28
|
+
end
|
29
|
+
|
30
|
+
def ships_now?
|
31
|
+
ships_in.to_i <= 48
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Kosher
|
2
|
+
class Request < Sucker::Request
|
3
|
+
def initialize(args={})
|
4
|
+
super
|
5
|
+
add_parameters
|
6
|
+
end
|
7
|
+
|
8
|
+
def batchify(asins)
|
9
|
+
self.<<({ 'ItemLookup.1.ItemId' => asins[0, 10] })
|
10
|
+
self.<<({ 'ItemLookup.2.ItemId' => asins[10, 10] }) if asins.size > 10
|
11
|
+
end
|
12
|
+
|
13
|
+
def get
|
14
|
+
Algorithm.new(super)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def add_parameters
|
20
|
+
self.<<({
|
21
|
+
'Operation' => 'ItemLookup',
|
22
|
+
'ItemLookup.Shared.IdType' => 'ASIN',
|
23
|
+
'ItemLookup.Shared.Condition' => 'All',
|
24
|
+
'ItemLookup.Shared.MerchantId' => 'All',
|
25
|
+
'ItemLookup.Shared.ResponseGroup' => ['OfferFull', 'SalesRank'] })
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Kosher
|
2
|
+
class Seller < Struct.new(:merchant_id, :average_rating)
|
3
|
+
class << self
|
4
|
+
attr_accessor :blacklist
|
5
|
+
|
6
|
+
def build(doc)
|
7
|
+
merchant_id = doc['MerchantId']
|
8
|
+
average_rating = doc['AverageFeedbackRating'].to_f
|
9
|
+
|
10
|
+
new(merchant_id, average_rating)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def blacklist
|
15
|
+
self.class.blacklist
|
16
|
+
end
|
17
|
+
|
18
|
+
def blacklisted?
|
19
|
+
blacklist.include? merchant_id rescue false
|
20
|
+
end
|
21
|
+
|
22
|
+
def kosher?
|
23
|
+
return false if blacklisted?
|
24
|
+
|
25
|
+
average_rating == 0.0 || average_rating > 4.7
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/kosher/version.rb
CHANGED
data/lib/kosher.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'sucker'
|
2
|
+
require 'kosher/algorithm'
|
3
|
+
require 'kosher/condition'
|
4
|
+
require 'kosher/description'
|
5
|
+
require 'kosher/item'
|
6
|
+
require 'kosher/offer'
|
7
|
+
require 'kosher/request'
|
8
|
+
require 'kosher/seller'
|
3
9
|
|
4
10
|
module Kosher
|
5
|
-
def self.new(
|
6
|
-
|
11
|
+
def self.new(args={})
|
12
|
+
Request.new(args)
|
7
13
|
end
|
8
14
|
end
|
9
|
-
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Fabricator(:seller, :class_name => 'kosher/seller') do
|
2
|
+
merchant_id Faker::Amazon.merchant_id
|
3
|
+
end
|
4
|
+
|
5
|
+
Fabricator(:new_seller, :from => :seller) do
|
6
|
+
average_rating 0.0
|
7
|
+
end
|
8
|
+
|
9
|
+
Fabricator(:good_seller, :from => :seller) do
|
10
|
+
average_rating 5.0
|
11
|
+
end
|
12
|
+
|
13
|
+
Fabricator(:bad_seller, :from => :seller) do
|
14
|
+
average_rating 4.5
|
15
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :get
|
5
|
+
uri: http://ecs.amazonaws.com:80/onca/xml?AWSAccessKeyId=0ZVSQ33MDFPQS8H2PM02&AssociateTag=papecava-20&ItemLookup.1.ItemId=0143105825&ItemLookup.Shared.Condition=All&ItemLookup.Shared.IdType=ASIN&ItemLookup.Shared.MerchantId=All&ItemLookup.Shared.ResponseGroup=OfferFull,SalesRank&Operation=ItemLookup&Service=AWSECommerceService&Signature=x3dZXO/H7AvZ7x/bt6P1iTAx13QatyVbMyc1v9yKtzc=&Timestamp=2011-03-02T19:25:56Z&Version=2010-11-01
|
6
|
+
body:
|
7
|
+
headers:
|
8
|
+
accept-encoding:
|
9
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
10
|
+
response: !ruby/struct:VCR::Response
|
11
|
+
status: !ruby/struct:VCR::ResponseStatus
|
12
|
+
code: 200
|
13
|
+
message: OK
|
14
|
+
headers:
|
15
|
+
date:
|
16
|
+
- Wed, 02 Mar 2011 19:25:56 GMT
|
17
|
+
server:
|
18
|
+
- Server
|
19
|
+
content-type:
|
20
|
+
- text/xml;charset=UTF-8
|
21
|
+
vary:
|
22
|
+
- Accept-Encoding,User-Agent
|
23
|
+
content-encoding:
|
24
|
+
- gzip
|
25
|
+
content-length:
|
26
|
+
- "3620"
|
27
|
+
nncoection:
|
28
|
+
- close
|
29
|
+
body: !binary |
|
30
|
+
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
|
110
|
+
tnT+E+jS5/89Q+XfeGWzi8lBAAA=
|
111
|
+
|
112
|
+
http_version: "1.1"
|