polipus-elasticsearch 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,35 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /vendor/bundle
26
+ /lib/bundler/man/
27
+
28
+ # for a library or gem, you might want to ignore these files since the code is
29
+ # intended to run in multiple environments; otherwise, check them in:
30
+ Gemfile.lock
31
+ # .ruby-version
32
+ # .ruby-gemset
33
+
34
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Stefano Fontanelli
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
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
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Polipus: addons for ElasticSearch
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'polipus-elasticsearch'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install polipus-elasticsearch
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it ( http://github.com/<my-github-username>/polipus-elasticsearch/fork )
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ # coding: utf-8
2
+ require 'bundler/gem_tasks'
@@ -0,0 +1,168 @@
1
+ require 'elasticsearch/model'
2
+
3
+ ENV['POLIPUS_ELASTICSEACH_INDEX_SHARDS'] ||= '1'
4
+ ENV['POLIPUS_ELASTICSEACH_INDEX_REPLICAS'] ||= '0'
5
+
6
+ module Polipus
7
+ module ElasticSearch
8
+ class Page
9
+ include Elasticsearch::Model
10
+
11
+ DEFAULT_INDEX_NAME = 'polipus-pages'
12
+ document_type 'polipus_page'
13
+ index_name DEFAULT_INDEX_NAME
14
+
15
+ settings(
16
+ index: {
17
+ number_of_shards: ENV['POLIPUS_ELASTICSEACH_INDEX_SHARDS'].to_i,
18
+ number_of_replicas: ENV['POLIPUS_ELASTICSEACH_INDEX_REPLICAS'].to_i
19
+ }
20
+ )
21
+ mapping(_all: { enabled: false }) do
22
+ indexes(
23
+ :id,
24
+ index: :not_analyzed
25
+ )
26
+ indexes(
27
+ :body,
28
+ type: :string
29
+ )
30
+ indexes(
31
+ :code,
32
+ type: :integer
33
+ )
34
+ indexes(
35
+ :depth,
36
+ type: :integer
37
+ )
38
+ indexes(
39
+ :error,
40
+ type: :string
41
+ )
42
+ indexes(
43
+ :fetched,
44
+ type: :boolean
45
+ )
46
+ indexes(
47
+ :fetched_at,
48
+ type: :integer
49
+ )
50
+ indexes(
51
+ :headers,
52
+ type: :string
53
+ )
54
+ indexes(
55
+ :links,
56
+ type: :string
57
+ )
58
+ indexes(
59
+ :redirect_to,
60
+ type: :string
61
+ )
62
+ indexes(
63
+ :referer,
64
+ type: :string
65
+ )
66
+ indexes(
67
+ :response_time,
68
+ type: :integer
69
+ )
70
+ indexes(
71
+ :url,
72
+ type: :string
73
+ )
74
+ indexes(
75
+ :user_data,
76
+ type: :string
77
+ )
78
+ end
79
+
80
+ def self.client
81
+ __elasticsearch__.client
82
+ end
83
+
84
+ def self.count
85
+ client.count(index: index_name, type: document_type)['count'].to_i
86
+ end
87
+
88
+ def self.create_index!(name)
89
+ index_name(name) unless name.nil?
90
+ __elasticsearch__.create_index!(index: index_name)
91
+ end
92
+
93
+ def self.clear_index!
94
+ client.delete_by_query(
95
+ index: index_name,
96
+ body: { query: { match_all: {} } }
97
+ )
98
+ end
99
+
100
+ def self.delete_index!
101
+ client.indices.delete(index: index_name)
102
+ end
103
+
104
+ def self.exists?(id)
105
+ client.exists?(
106
+ index: index_name,
107
+ type: document_type,
108
+ id: id
109
+ )
110
+ end
111
+
112
+ def self.get(id)
113
+ return unless exists?(id)
114
+ client.get_source(
115
+ index: index_name,
116
+ type: document_type,
117
+ id: id
118
+ )
119
+ end
120
+
121
+ def self.index_exists?
122
+ client.indices.exists?(index: index_name)
123
+ end
124
+
125
+ def self.process_document(obj)
126
+ doc = { '_type' => document_type }
127
+ properties.each do |p|
128
+ doc[p.to_s] = obj.respond_to?(p.to_s) ? obj.send(p.to_s) : obj[p.to_s]
129
+ end
130
+ doc.reject { |_, value| value.nil? }
131
+ end
132
+
133
+ def self.properties
134
+ mapping.to_hash[document_type.to_sym][:properties].keys.map { |k| k.to_s }
135
+ end
136
+
137
+ def self.remove(id, refresh = false)
138
+ return unless exists?(id)
139
+ client.delete(
140
+ index: index_name,
141
+ type: document_type,
142
+ id: id,
143
+ refresh: refresh,
144
+ version: Time.now.to_i,
145
+ version_type: :external
146
+ )
147
+ end
148
+
149
+ def self.setup(client_)
150
+ __elasticsearch__.client = client_
151
+ end
152
+
153
+ def self.store(document, refresh = false)
154
+ document = process_document(document)
155
+ client.index(
156
+ index: index_name,
157
+ type: document_type,
158
+ id: document['id'],
159
+ body: document,
160
+ refresh: refresh,
161
+ version: document['fetched_at'].to_i,
162
+ version_type: :external
163
+ )
164
+ document['id']
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,100 @@
1
+ # encoding: UTF-8
2
+ require 'base64'
3
+ require 'multi_json'
4
+ require 'polipus'
5
+ require 'polipus-elasticsearch'
6
+
7
+ module Polipus
8
+ module Storage
9
+ class ElasticSearchStore < Base
10
+ BINARY_FIELDS = %w(body headers user_data)
11
+ DEFAULT_INDEX = Polipus::ElasticSearch::Page
12
+
13
+ attr_accessor :index, :index_name, :except, :compress, :semaphore, :refresh
14
+
15
+ def initialize(client, options = {})
16
+ @index = options[:index] || options['index'] || DEFAULT_INDEX
17
+ @index_name = options[:index_name] || options['index_name']
18
+ @except = options[:except] || options['except'] || []
19
+ @compress = options[:compress] || options['compress']
20
+ @semaphore = Mutex.new
21
+ @refresh = options[:refresh] || options['refresh'] || true
22
+ index.setup(client)
23
+ index.create_index!(index_name) unless index.index_exists?
24
+ end
25
+
26
+ def add(page)
27
+ semaphore.synchronize do
28
+ obj = page.to_hash
29
+ Array(except).each { |field| obj.delete(field.to_s) }
30
+ BINARY_FIELDS.each do |field|
31
+ next if obj[field.to_s].nil? || obj[field.to_s].empty?
32
+ obj[field.to_s] = MultiJson.encode(obj[field.to_s]) if field.to_s == 'user_data'
33
+ obj[field.to_s] = Base64.encode64(obj[field.to_s])
34
+ end
35
+ obj['id'] = uuid(page)
36
+ obj['fetched_at'] = obj['fetched_at'].to_i
37
+ index.store(obj, refresh)
38
+ end
39
+ end
40
+
41
+ def clear
42
+ index.clear_index! if index.index_exists?
43
+ end
44
+
45
+ def count
46
+ index.count
47
+ end
48
+
49
+ def drop
50
+ index.delete_index! if index.index_exists?
51
+ end
52
+
53
+ def each
54
+ # This method is implemented only for testing purposes
55
+ response = index.client.search(
56
+ index: index_name,
57
+ body: {
58
+ query: { match_all: {} },
59
+ from: 0,
60
+ size: 25
61
+ }
62
+ )
63
+ response['hits']['hits'].each do |data|
64
+ page = load_page(data['_source'])
65
+ yield uuid(page), page
66
+ end
67
+ end
68
+
69
+ def exists?(page)
70
+ @semaphore.synchronize do
71
+ index.exists?(uuid(page))
72
+ end
73
+ end
74
+
75
+ def get(page)
76
+ @semaphore.synchronize do
77
+ load_page(index.get(uuid(page)))
78
+ end
79
+ end
80
+
81
+ def remove(page)
82
+ @semaphore.synchronize do
83
+ index.remove(uuid(page), refresh)
84
+ end
85
+ end
86
+
87
+ def load_page(data)
88
+ return nil if data.nil?
89
+ BINARY_FIELDS.each do |field|
90
+ next if data[field.to_s].nil? || data[field.to_s].empty?
91
+ data[field.to_s] = Base64.decode64(data[field.to_s])
92
+ data[field.to_s] = MultiJson.decode(data[field.to_s]) if field.to_s == 'user_data'
93
+ end
94
+ page = Page.from_hash(data)
95
+ page.fetched_at ||= 0
96
+ page
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,3 @@
1
+ # encoding: UTF-8
2
+ require 'polipus-elasticsearch/index/page'
3
+ require 'polipus-elasticsearch/storage/elasticsearch_store'
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'polipus-elasticsearch'
7
+ spec.version = '0.0.1'
8
+ spec.authors = ['Stefano Fontanelli']
9
+ spec.email = ['s.fontanelli@gmail.com']
10
+ spec.summary = 'Add support for ElasticSearch in Polipus crawler'
11
+ spec.description = 'Add support for ElasticSearch in Polipus crawler'
12
+ spec.homepage = 'https://github.com/stefanofontanelli/polipus-elasticsearch'
13
+ spec.license = 'MIT'
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
17
+ spec.require_paths = ['lib']
18
+ spec.add_runtime_dependency 'elasticsearch', '~> 1.0.4'
19
+ spec.add_runtime_dependency 'elasticsearch-model', '~> 0.1.4'
20
+ spec.add_runtime_dependency 'polipus', '~> 0.3', '>= 0.3.0'
21
+ spec.add_development_dependency 'rake', '~> 10.3'
22
+ spec.add_development_dependency 'rspec', '~> 3.1.0'
23
+ spec.add_development_dependency 'flexmock', '~> 1.3'
24
+ spec.add_development_dependency 'vcr', '~> 2.9.0'
25
+ spec.add_development_dependency 'webmock', '~> 1.20.0'
26
+ spec.add_development_dependency 'coveralls'
27
+ end
@@ -0,0 +1,175 @@
1
+ # encoding: UTF-8
2
+ require 'logger'
3
+ require 'polipus-elasticsearch'
4
+ require 'spec_helper'
5
+
6
+ describe Polipus::Storage::ElasticSearchStore do
7
+ before(:each)do
8
+ @logger = Logger.new(STDOUT)
9
+ @client = Elasticsearch::Client.new(host: '127.0.0.1', logger: @logger)
10
+ @client.transport.logger.level = Logger::INFO
11
+ @index_name = 'polipus_elasticsearch_test'
12
+ @storage = Polipus::Storage::ElasticSearchStore.new(
13
+ @client,
14
+ index_name: @index_name,
15
+ refresh: true
16
+ )
17
+ @storage_without_code_and_body = Polipus::Storage::ElasticSearchStore.new(
18
+ @client,
19
+ index_name: @index_name,
20
+ except: ['code', 'body'],
21
+ refresh: true
22
+ )
23
+ end
24
+
25
+ after(:each) do
26
+ @storage.drop
27
+ end
28
+
29
+ it 'should store a page' do
30
+ p = page_factory 'http://www.google.com'
31
+ uuid = @storage.add(p)
32
+ expect(uuid).to eq('ed646a3334ca891fd3467db131372140')
33
+ p = @storage.get(p)
34
+ expect(p).not_to be_nil
35
+ expect(p.url.to_s).to eq('http://www.google.com')
36
+ expect(p.body).to eq('<html></html>')
37
+ @storage.remove(p)
38
+ p = @storage.get(p)
39
+ expect(p).to be_nil
40
+ end
41
+
42
+ it 'should store all the relevant data from the page' do
43
+ url = "http://www.duckduckgo.com"
44
+ referer = "http://www.actually.nowhere.com"
45
+ redirectto = "#{url}/your_super_awesome_results?page=42"
46
+ now = Time.now.to_i
47
+ p = page_factory(
48
+ url,
49
+ {
50
+ referer: referer,
51
+ redirect_to: redirectto,
52
+ fetched_at: now
53
+ })
54
+ uuid = @storage.add p
55
+ expect(uuid).to eq('3cd657f53c74f22c1a21b420ce3863fd')
56
+ p = @storage.get p
57
+
58
+ expect(p.url.to_s).to eq(url)
59
+ expect(p.referer.to_s).to eq(referer)
60
+ expect(p.redirect_to.to_s).to eq(redirectto)
61
+ expect(p.fetched_at).to eq(now)
62
+ expect(p.body).to eq('<html></html>')
63
+
64
+ # for the sake of the other tests...
65
+ expect(@storage.remove(p)).to be_truthy
66
+ end
67
+
68
+ it 'should update a page' do
69
+ p = page_factory 'http://www.google.com', code: 301
70
+ @storage.add p
71
+ p = @storage.get p
72
+ expect(p.code).to eq(301)
73
+ end
74
+
75
+ it 'should iterate over stored pages' do
76
+ p = page_factory('http://www.google.com')
77
+ @storage.add(p)
78
+ @storage.each do |k, page|
79
+ expect(k).to eq('ed646a3334ca891fd3467db131372140')
80
+ expect(page.url.to_s).to eq('http://www.google.com')
81
+ end
82
+ end
83
+
84
+ it 'should delete a page' do
85
+ p = page_factory 'http://www.google.com', code: 301
86
+ @storage.remove p
87
+ expect(@storage.get(p)).to be_nil
88
+ end
89
+
90
+ it 'should store a page removing a query string from the uuid generation' do
91
+ p = page_factory 'http://www.asd.com/?asd=lol'
92
+ p_no_query = page_factory 'http://www.asd.com/?asdas=dasda&adsda=1'
93
+ @storage.include_query_string_in_uuid = false
94
+ @storage.add p
95
+ expect(@storage.exists?(p_no_query)).to be_truthy
96
+ @storage.remove p
97
+ end
98
+
99
+ it 'should store a page removing a query string from the uuid generation no ending slash' do
100
+ p = page_factory 'http://www.asd.com?asd=lol'
101
+ p_no_query = page_factory 'http://www.asd.com'
102
+ @storage.include_query_string_in_uuid = false
103
+ @storage.add p
104
+ expect(@storage.exists?(p_no_query)).to be_truthy
105
+ @storage.remove p
106
+ end
107
+
108
+ it 'should store a page with user data associated' do
109
+ p = page_factory 'http://www.user.com'
110
+ p.user_data.name = 'Test User Data'
111
+ @storage.add p
112
+ expect(@storage.exists?(p)).to be_truthy
113
+ p = @storage.get(p)
114
+ expect(p.user_data.name).to eq('Test User Data')
115
+ @storage.remove p
116
+ end
117
+
118
+ it 'should honor the except parameters' do
119
+ pag = page_factory 'http://www.user-doo.com'
120
+ expect(pag.code).to eq(200)
121
+ expect(pag.body).to eq('<html></html>')
122
+
123
+ @storage_without_code_and_body.add(pag)
124
+ pag = @storage_without_code_and_body.get(pag)
125
+
126
+ expect(pag.body).to be_nil
127
+ expect(pag.code).to eq(0)
128
+ @storage_without_code_and_body.remove(pag)
129
+ end
130
+
131
+ it 'should return false if a doc not exists' do
132
+ @storage.include_query_string_in_uuid = false
133
+ p_other = page_factory 'http://www.asdrrrr.com'
134
+ expect(@storage.exists?(p_other)).to be_falsey
135
+ @storage.add p_other
136
+ expect(@storage.exists?(p_other)).to be_truthy
137
+ p_other = page_factory 'http://www.asdrrrr.com?trk=asd-lol'
138
+ expect(@storage.exists?(p_other)).to be_truthy
139
+ @storage.include_query_string_in_uuid = true
140
+ expect(@storage.exists?(p_other)).to be_falsey
141
+ @storage.include_query_string_in_uuid = false
142
+ @storage.remove p_other
143
+ end
144
+
145
+ it 'should set page.fetched_at based on the id creation' do
146
+ p = page_factory 'http://www.user-doojo.com'
147
+ @storage.add p
148
+ expect(p.fetched_at).not_to be_nil
149
+ p = @storage.get p
150
+ expect(p.fetched_at).not_to be_nil
151
+ @storage.remove p
152
+ end
153
+
154
+ it 'should NOT set page.fetched_at if already present' do
155
+ p = page_factory 'http://www.user-doojooo.com'
156
+ p.fetched_at = 10
157
+ @storage.add p
158
+ p = @storage.get p
159
+ expect(p.fetched_at).to be 10
160
+ @storage.remove p
161
+ end
162
+
163
+ it 'should store two pages and the count will be two' do
164
+ pages = ['http://www.google.com', 'http://www.duckduckgo.com'].map do |url|
165
+ page_factory(url).tap do |page|
166
+ @storage.add(page)
167
+ end
168
+ end
169
+ expect(@storage.count).to be 2
170
+ pages.each do |page|
171
+ @storage.remove(page)
172
+ end
173
+ expect(@storage.count).to be 0
174
+ end
175
+ end
@@ -0,0 +1,51 @@
1
+ # Require this file using `require "spec_helper"`
2
+ # to ensure that it is only loaded once.
3
+ #
4
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
5
+ require 'digest/md5'
6
+ require 'coveralls'
7
+ require 'vcr'
8
+ require 'webmock/rspec'
9
+
10
+ Coveralls.wear!
11
+
12
+ require 'polipus'
13
+
14
+ VCR.configure do |c|
15
+ c.cassette_library_dir = "#{File.dirname(__FILE__)}/cassettes"
16
+ c.hook_into :webmock
17
+ c.allow_http_connections_when_no_cassette = true
18
+ c.ignore_localhost = true
19
+ end
20
+
21
+ RSpec.configure do |config|
22
+ config.run_all_when_everything_filtered = true
23
+ config.filter_run :focus
24
+
25
+ # Run specs in random order to surface order dependencies. If you find an
26
+ # order dependency and want to debug it, you can fix the order by providing
27
+ # the seed, which is printed after each run.
28
+ # --seed 1234
29
+ config.order = 'random'
30
+ config.mock_with :flexmock
31
+ config.around(:each) do |example|
32
+ t = Time.now
33
+ print example.metadata[:full_description]
34
+ VCR.use_cassette(
35
+ Digest::MD5.hexdigest(example.metadata[:full_description]),
36
+ record: :all
37
+ ) do
38
+ example.run
39
+ end
40
+ puts " [#{Time.now - t}s]"
41
+ end
42
+ config.before(:each) { Polipus::SignalHandler.disable }
43
+ end
44
+
45
+ def page_factory(url, params = {})
46
+ params[:code] ||= 200 unless params.has_key?(:code)
47
+ params[:body] = '<html></html>' unless params.has_key?(:body)
48
+ params[:fetched_at] = Time.now.to_i
49
+ sleep(1)
50
+ Polipus::Page.new(url, params)
51
+ end
metadata ADDED
@@ -0,0 +1,215 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: polipus-elasticsearch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Stefano Fontanelli
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-07-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: elasticsearch
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.4
30
+ - !ruby/object:Gem::Dependency
31
+ name: elasticsearch-model
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.1.4
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.1.4
46
+ - !ruby/object:Gem::Dependency
47
+ name: polipus
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '0.3'
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: 0.3.0
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ~>
63
+ - !ruby/object:Gem::Version
64
+ version: '0.3'
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: 0.3.0
68
+ - !ruby/object:Gem::Dependency
69
+ name: rake
70
+ requirement: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '10.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ version: '10.3'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rspec
86
+ requirement: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ~>
90
+ - !ruby/object:Gem::Version
91
+ version: 3.1.0
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ~>
98
+ - !ruby/object:Gem::Version
99
+ version: 3.1.0
100
+ - !ruby/object:Gem::Dependency
101
+ name: flexmock
102
+ requirement: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ~>
106
+ - !ruby/object:Gem::Version
107
+ version: '1.3'
108
+ type: :development
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ~>
114
+ - !ruby/object:Gem::Version
115
+ version: '1.3'
116
+ - !ruby/object:Gem::Dependency
117
+ name: vcr
118
+ requirement: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ~>
122
+ - !ruby/object:Gem::Version
123
+ version: 2.9.0
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: 2.9.0
132
+ - !ruby/object:Gem::Dependency
133
+ name: webmock
134
+ requirement: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ~>
138
+ - !ruby/object:Gem::Version
139
+ version: 1.20.0
140
+ type: :development
141
+ prerelease: false
142
+ version_requirements: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ~>
146
+ - !ruby/object:Gem::Version
147
+ version: 1.20.0
148
+ - !ruby/object:Gem::Dependency
149
+ name: coveralls
150
+ requirement: !ruby/object:Gem::Requirement
151
+ none: false
152
+ requirements:
153
+ - - ! '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ type: :development
157
+ prerelease: false
158
+ version_requirements: !ruby/object:Gem::Requirement
159
+ none: false
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ description: Add support for ElasticSearch in Polipus crawler
165
+ email:
166
+ - s.fontanelli@gmail.com
167
+ executables: []
168
+ extensions: []
169
+ extra_rdoc_files: []
170
+ files:
171
+ - .gitignore
172
+ - Gemfile
173
+ - LICENSE.txt
174
+ - README.md
175
+ - Rakefile
176
+ - lib/polipus-elasticsearch.rb
177
+ - lib/polipus-elasticsearch/index/page.rb
178
+ - lib/polipus-elasticsearch/storage/elasticsearch_store.rb
179
+ - polipus-elasticsearch.gemspec
180
+ - spec/polipus-elasticsearch/storage/elasticsearch_store_spec.rb
181
+ - spec/spec_helper.rb
182
+ homepage: https://github.com/stefanofontanelli/polipus-elasticsearch
183
+ licenses:
184
+ - MIT
185
+ post_install_message:
186
+ rdoc_options: []
187
+ require_paths:
188
+ - lib
189
+ required_ruby_version: !ruby/object:Gem::Requirement
190
+ none: false
191
+ requirements:
192
+ - - ! '>='
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ segments:
196
+ - 0
197
+ hash: -3053519168912849089
198
+ required_rubygems_version: !ruby/object:Gem::Requirement
199
+ none: false
200
+ requirements:
201
+ - - ! '>='
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ segments:
205
+ - 0
206
+ hash: -3053519168912849089
207
+ requirements: []
208
+ rubyforge_project:
209
+ rubygems_version: 1.8.23.2
210
+ signing_key:
211
+ specification_version: 3
212
+ summary: Add support for ElasticSearch in Polipus crawler
213
+ test_files:
214
+ - spec/polipus-elasticsearch/storage/elasticsearch_store_spec.rb
215
+ - spec/spec_helper.rb