meta_hari 0.0.3 → 0.0.4
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.
- checksums.yaml +4 -4
- data/README.md +12 -7
- data/lib/meta_hari/helpers/open_graph.rb +41 -0
- data/lib/meta_hari/helpers.rb +1 -0
- data/lib/meta_hari/product.rb +24 -0
- data/lib/meta_hari/spyglass/amazon_de.rb +8 -4
- data/lib/meta_hari/spyglass/base.rb +15 -4
- data/lib/meta_hari/version.rb +1 -1
- data/lib/meta_hari.rb +1 -0
- data/spec/lib/meta_hari/helpers/open_graph_spec.rb +56 -0
- data/spec/lib/meta_hari/spyglass/amazon_de_spec.rb +1 -1
- data/spec/lib/meta_hari/spyglass/base_spec.rb +38 -2
- data/spec/resources/arzberg_porzellan.html +4079 -0
- metadata +7 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bf357320156f76fbf4f7a8b2f685732560b89f3
|
4
|
+
data.tar.gz: ebe62d8cc103cb7630a7d2cf5c970140c57ea691
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9656b5d8333933c4288c7cf16940594f2806e19b471ddaef9b1d62017431146b54b26009840721e1330a2037adcf710c59db0e685d6dbc15ed4cb12fdbb51908
|
7
|
+
data.tar.gz: 4f59956d9d64177f16da24637b0237e06b38f258b1c147c9d1e706f6f4b666a271843304bfaae6280134483442410ff29cfc0bf8238ef5f9de4df3dec3c7d27e
|
data/README.md
CHANGED
@@ -30,7 +30,7 @@ thous informations to the method `MetaHari.spy`.
|
|
30
30
|
|
31
31
|
```ruby
|
32
32
|
product = MetaHari.spy('http://www.amazon.de/Gastroback-42429-Design-Wasserkocher-Advanced/dp/B000LQXC2Q/ref=sr_1_1')
|
33
|
-
product.inspect # => #<
|
33
|
+
product.inspect # => #<MetaHari::Product:0x007fd9dba99158 @name="Gastroback 42429 Design Wasserkocher Advanced Pro", @image="http://ecx.images-amazon.com/images/I/814Yl6mxLsL._SL1500_.jpg", @description="">
|
34
34
|
```
|
35
35
|
|
36
36
|
## Implemented spyglasses
|
@@ -41,8 +41,9 @@ custom shops which can not be spyed by the generic spyglass
|
|
41
41
|
|
42
42
|
* Amazon DE
|
43
43
|
* Generic
|
44
|
-
*
|
45
|
-
*
|
44
|
+
* [JSON-LD](https://developers.google.com/structured-data/rich-snippets/products)
|
45
|
+
* [Microdata](https://developers.google.com/structured-data/rich-snippets/products)
|
46
|
+
* [Open Graph](http://ogp.me/)
|
46
47
|
|
47
48
|
### Creating a spyglass
|
48
49
|
|
@@ -58,12 +59,12 @@ module MetaHari
|
|
58
59
|
%w(amazon.de www.amazon.de).include? uri.host.downcase
|
59
60
|
end
|
60
61
|
|
61
|
-
def spy
|
62
|
-
OpenStruct.new(name: title, image: image, description: '')
|
63
|
-
end
|
64
|
-
|
65
62
|
protected
|
66
63
|
|
64
|
+
def spy_list
|
65
|
+
[:spy_amazon]
|
66
|
+
end
|
67
|
+
|
67
68
|
def title
|
68
69
|
document.css('#productTitle').text
|
69
70
|
end
|
@@ -73,6 +74,10 @@ module MetaHari
|
|
73
74
|
data &&= data.attr 'data-old-hires'
|
74
75
|
data && data.value
|
75
76
|
end
|
77
|
+
|
78
|
+
def spy_amazon
|
79
|
+
{ 'name' => title, 'image' => image, 'description' => '' }
|
80
|
+
end
|
76
81
|
end
|
77
82
|
end
|
78
83
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module MetaHari
|
2
|
+
module Helpers
|
3
|
+
class OpenGraph
|
4
|
+
attr_reader :document
|
5
|
+
|
6
|
+
def initialize(document)
|
7
|
+
@document = document
|
8
|
+
end
|
9
|
+
|
10
|
+
def data
|
11
|
+
hash
|
12
|
+
end
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def selector
|
17
|
+
'meta[property^="og:"]'
|
18
|
+
end
|
19
|
+
|
20
|
+
def hash
|
21
|
+
@hash ||= begin
|
22
|
+
result = {}
|
23
|
+
document.css(selector).each do |meta|
|
24
|
+
key = meta.attr('property').to_s.gsub(/^og:/i, '')
|
25
|
+
value = meta.attr('content')
|
26
|
+
result[key_map(key)] = value
|
27
|
+
end
|
28
|
+
result
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def key_map(key)
|
33
|
+
case key.downcase
|
34
|
+
when 'title' then 'name'
|
35
|
+
else
|
36
|
+
key.downcase
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/meta_hari/helpers.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
module MetaHari
|
2
|
+
class Product
|
3
|
+
attr_reader :name
|
4
|
+
attr_reader :image
|
5
|
+
attr_reader :description
|
6
|
+
|
7
|
+
def initialize(attributes = {})
|
8
|
+
apply attributes
|
9
|
+
end
|
10
|
+
|
11
|
+
def apply(attributes)
|
12
|
+
@name = attributes['name'] if blank? name
|
13
|
+
@image = attributes['image'] if blank? image
|
14
|
+
@description = attributes['description'] if blank? description
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def blank?(value)
|
21
|
+
value.nil? || value.empty?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -5,12 +5,12 @@ module MetaHari
|
|
5
5
|
%w(amazon.de www.amazon.de).include? uri.host.downcase
|
6
6
|
end
|
7
7
|
|
8
|
-
def spy
|
9
|
-
OpenStruct.new(name: title, image: image, description: '')
|
10
|
-
end
|
11
|
-
|
12
8
|
protected
|
13
9
|
|
10
|
+
def spy_list
|
11
|
+
[:spy_amazon]
|
12
|
+
end
|
13
|
+
|
14
14
|
def title
|
15
15
|
document.css('#productTitle').text
|
16
16
|
end
|
@@ -20,6 +20,10 @@ module MetaHari
|
|
20
20
|
data &&= data.attr 'data-old-hires'
|
21
21
|
data && data.value
|
22
22
|
end
|
23
|
+
|
24
|
+
def spy_amazon
|
25
|
+
{ 'name' => title, 'image' => image, 'description' => '' }
|
26
|
+
end
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|
@@ -14,14 +14,20 @@ module MetaHari
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def spy
|
17
|
-
|
18
|
-
|
19
|
-
spy_microdata
|
20
|
-
].inject({}) { |a, e| a.merge e }
|
17
|
+
spy_list.map { |method| send method }
|
18
|
+
.inject(MetaHari::Product.new) { |a, e| a.apply e }
|
21
19
|
end
|
22
20
|
|
23
21
|
protected
|
24
22
|
|
23
|
+
def spy_list
|
24
|
+
[
|
25
|
+
:spy_json_ld,
|
26
|
+
:spy_microdata,
|
27
|
+
:spy_open_graph
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
25
31
|
def user_agent
|
26
32
|
[
|
27
33
|
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5)',
|
@@ -64,6 +70,11 @@ module MetaHari
|
|
64
70
|
microdata = MetaHari::Helpers::Microdata.new(document, uri.to_s)
|
65
71
|
microdata.data
|
66
72
|
end
|
73
|
+
|
74
|
+
def spy_open_graph
|
75
|
+
open_graph = MetaHari::Helpers::OpenGraph.new(document)
|
76
|
+
open_graph.data
|
77
|
+
end
|
67
78
|
end
|
68
79
|
end
|
69
80
|
end
|
data/lib/meta_hari/version.rb
CHANGED
data/lib/meta_hari.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MetaHari::Helpers::OpenGraph do
|
4
|
+
let(:url) do
|
5
|
+
[
|
6
|
+
'http://www.arzberg-porzellan.com/en/shop/products/bowls/sauce-boats',
|
7
|
+
'sauceboat-0-35-l-form-1382-blaubluten/'
|
8
|
+
].join('/')
|
9
|
+
end
|
10
|
+
let(:html) { resource_content('arzberg_porzellan.html') }
|
11
|
+
let(:document) { Nokogiri::HTML html }
|
12
|
+
let(:instance) { described_class.new document }
|
13
|
+
subject { instance }
|
14
|
+
|
15
|
+
describe '#initialize' do
|
16
|
+
it 'assigns the document to the reader' do
|
17
|
+
expect(subject.document).to be document
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when containing Open Graph data' do
|
22
|
+
describe '#hash' do
|
23
|
+
subject { instance.send :hash }
|
24
|
+
|
25
|
+
it { should be_an Hash }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#data' do
|
29
|
+
subject { instance.data }
|
30
|
+
|
31
|
+
it 'uses #hash' do
|
32
|
+
expect(instance).to receive(:hash).and_return([])
|
33
|
+
subject
|
34
|
+
end
|
35
|
+
|
36
|
+
it { should be_a Hash }
|
37
|
+
it { should have_key 'name' }
|
38
|
+
it { should have_key 'image' }
|
39
|
+
it { should have_key 'description' }
|
40
|
+
|
41
|
+
it 'has matching name' do
|
42
|
+
expect(subject['name']).to eql 'Sauceboat 0.35 l FORM 1382 | BLAUBLÜTEN'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when not containing Open Graph data' do
|
48
|
+
let(:html) { '' }
|
49
|
+
|
50
|
+
describe '#hash' do
|
51
|
+
subject { instance.send :hash }
|
52
|
+
|
53
|
+
it { should be_an Hash }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -39,7 +39,7 @@ describe MetaHari::Spyglass::AmazonDe do
|
|
39
39
|
let(:html) { resource_content 'amazon_de.html' }
|
40
40
|
subject { instance.spy }
|
41
41
|
|
42
|
-
it { should be_an
|
42
|
+
it { should be_an MetaHari::Product }
|
43
43
|
it { should respond_to :name }
|
44
44
|
it { should respond_to :image }
|
45
45
|
it { should respond_to :description }
|
@@ -54,7 +54,7 @@ describe MetaHari::Spyglass::Base do
|
|
54
54
|
allow(instance).to receive(:fetch_data).and_return(html)
|
55
55
|
end
|
56
56
|
|
57
|
-
it { should be_an
|
57
|
+
it { should be_an MetaHari::Product }
|
58
58
|
it { should respond_to :name }
|
59
59
|
it { should respond_to :image }
|
60
60
|
it { should respond_to :description }
|
@@ -88,7 +88,7 @@ describe MetaHari::Spyglass::Base do
|
|
88
88
|
allow(instance).to receive(:fetch_data).and_return(html)
|
89
89
|
end
|
90
90
|
|
91
|
-
it { should be_an
|
91
|
+
it { should be_an MetaHari::Product }
|
92
92
|
it { should respond_to :name }
|
93
93
|
it { should respond_to :image }
|
94
94
|
it { should respond_to :description }
|
@@ -116,5 +116,41 @@ describe MetaHari::Spyglass::Base do
|
|
116
116
|
expect(subject.description).to eql expected_value
|
117
117
|
end
|
118
118
|
end
|
119
|
+
|
120
|
+
context 'with Open Graph document' do
|
121
|
+
let(:html) { resource_content 'arzberg_porzellan.html' }
|
122
|
+
let(:instance) { described_class.new(uri) }
|
123
|
+
subject { instance.spy }
|
124
|
+
|
125
|
+
before :each do
|
126
|
+
allow(instance).to receive(:fetch_data).and_return(html)
|
127
|
+
end
|
128
|
+
|
129
|
+
it { should be_an MetaHari::Product }
|
130
|
+
it { should respond_to :name }
|
131
|
+
it { should respond_to :image }
|
132
|
+
it { should respond_to :description }
|
133
|
+
|
134
|
+
it 'has the correct name' do
|
135
|
+
expect(subject.name).to eql 'Sauceboat 0.35 l FORM 1382 | BLAUBLÜTEN'
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'has the correct image url' do
|
139
|
+
expected_value = [
|
140
|
+
'http://arzberg-c00.kxcdn.com/cache/dc/db',
|
141
|
+
'dcdbb5956e1f9fb60de351fbd21a9c4d.jpg'
|
142
|
+
].join('/')
|
143
|
+
expect(subject.image).to eql expected_value
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'has the correct description' do
|
147
|
+
expected_value = [
|
148
|
+
'Order online our Sauceboat 0.35 l FORM 1382 | BLAUBLÜTEN. ✓ Large',
|
149
|
+
'Range ✓ Best Quality ✓ Directly from the Manufacturer ▻',
|
150
|
+
'Arzberg-Porzellan.com'
|
151
|
+
].join(' ')
|
152
|
+
expect(subject.description).to eql expected_value
|
153
|
+
end
|
154
|
+
end
|
119
155
|
end
|
120
156
|
end
|