sk_google_custom_search_api 2.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7242a2df55757ecf17e6e68e6176b2ed7d248727
4
+ data.tar.gz: f69674749f4670b55fa094862e36ea9d1bd05475
5
+ SHA512:
6
+ metadata.gz: 8e05b306d9ddceb3cbb50fef1f829818b8a4b4e7ff4e441cdb5ae73aaa0b2c50cb62c21b13129fb31078bb6630b3ad201fcc348000df1a7bf4e8eded02dc2f46
7
+ data.tar.gz: 66de2254b6b00cb4cef34cf76aa872a80130c1e31dd9023cd260ecb3dd0a5cf2839d0420aa54202ce8b0e6a8c6a31ba6f42b3cbcb823d0cc5c3875b84edafb9a
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,2 @@
1
+ = Changelog
2
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in importers.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,52 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ google_custom_search_api (2.0.0)
5
+ addressable
6
+ httparty
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ addressable (2.3.8)
12
+ crack (0.4.3)
13
+ safe_yaml (~> 1.0.0)
14
+ diff-lcs (1.2.5)
15
+ hashdiff (0.2.3)
16
+ httparty (0.13.7)
17
+ json (~> 1.8)
18
+ multi_xml (>= 0.5.2)
19
+ json (1.8.3)
20
+ multi_xml (0.5.5)
21
+ rspec (3.4.0)
22
+ rspec-core (~> 3.4.0)
23
+ rspec-expectations (~> 3.4.0)
24
+ rspec-mocks (~> 3.4.0)
25
+ rspec-core (3.4.1)
26
+ rspec-support (~> 3.4.0)
27
+ rspec-expectations (3.4.0)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.4.0)
30
+ rspec-mocks (3.4.0)
31
+ diff-lcs (>= 1.2.0, < 2.0)
32
+ rspec-support (~> 3.4.0)
33
+ rspec-support (3.4.1)
34
+ safe_yaml (1.0.4)
35
+ vcr (3.0.1)
36
+ webmock (1.22.5)
37
+ addressable (< 2.4.0)
38
+ crack (>= 0.3.2)
39
+ hashdiff
40
+
41
+ PLATFORMS
42
+ ruby
43
+
44
+ DEPENDENCIES
45
+ google_custom_search_api!
46
+ json
47
+ rspec
48
+ vcr
49
+ webmock
50
+
51
+ BUNDLED WITH
52
+ 1.10.6
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Ben Wiseley
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,276 @@
1
+ # Google Custom Search
2
+
3
+ This project is a Ruby lib for Google's Custom Search ENgine API (http://www.google.com/cse). There seem to be quite a few cse libs out there that don't work so I rolled this up quickly.
4
+
5
+ Questions/comments, etc: wiseleyb@gmail.com
6
+
7
+ ## Install
8
+
9
+ Add to your Gemfile:
10
+
11
+ gem "sk_google_custom_search_api"
12
+
13
+ then
14
+
15
+ bundle install
16
+
17
+ Google's API management is confusing at best. At the time of this writing you codes like so:
18
+
19
+ ### GOOGLE_API_KEY
20
+
21
+ * Go to [Google Projects](https://console.developers.google.com/project)
22
+ * Create a project, open it
23
+ * Under `Explore other services` choose `Enable APIs and get credentials like keys`
24
+ * Search for `custom search` and click on it
25
+ * In the left column click on `Credentials`
26
+ * Under `API keys` grab your key. This is your `GOOGLE_API_KEY`
27
+
28
+ ### GOOGLE_SEARCH_CX
29
+
30
+ * Go to [Google CSE](https://cse.google.com/cse)
31
+ * Create a search engine and click on it
32
+ * Under `Setup > Tabs > Basic` find `Details` and click `Search engine ID`
33
+ * This is your GOOGLE_SEARCH_CX
34
+ * Make sure to add a site under `Sites to search`
35
+
36
+ ## Use
37
+
38
+ ### Search
39
+
40
+ To perform a search:
41
+
42
+ ```
43
+ results = GoogleCustomSearchApi.search("poker", {api_key: API_KEY, cx_key: CX_KEY})
44
+ ```
45
+ Results now contains a raw version and a class'ed version of the data show in ```Sample results``` below.
46
+
47
+ This means you can do:
48
+
49
+ ```
50
+ results["items"].each do |item|
51
+ puts item["title"], item["link"]
52
+ end
53
+ ```
54
+
55
+ or
56
+
57
+ ```
58
+ results.items.each do |item|
59
+ puts item.title, item.link
60
+ end
61
+ ```
62
+
63
+ ### Paging
64
+
65
+ Google only returns 10 results at a time and a maximum of 100 results. The easiest way to page through results if to use `:page`. Paging is 1 based (1-10). The default page is 1
66
+
67
+ ```
68
+ results = GoogleCustomerSearchApi.search("poker", page: 2)
69
+ results.pages == 10
70
+ results.current_page == 2
71
+ results.next_page == 3
72
+ results.previous_page == 1
73
+
74
+ results = GoogleCustomerSearchApi.search("poker", page: 1)
75
+ results.pages == 10
76
+ results.current_page == 1
77
+ results.next_page == 2
78
+ results.previous_page == nil
79
+
80
+ results = GoogleCustomerSearchApi.search("poker", page: 10)
81
+ results.pages == 10
82
+ results.current_page == 10
83
+ results.next_page == nil
84
+ results.previous_page == 9
85
+ ```
86
+
87
+ You can also use `:start` - which can be any number between 1 and 99. The `:page` helpers won't be accurate with `:start`
88
+
89
+ Example: get results 13-23
90
+
91
+ ```
92
+ results = GoogleCustomerSearchApi.search('poker', start: 13)
93
+ ```
94
+
95
+ See [Custom Search](http://code.google.com/apis/customsearch/v1/using_rest.html) documentation for an explanation of all fields available.
96
+
97
+ ### Search and return all results
98
+
99
+ This method isn't so useful because it's pretty slow (do to fetching up to 10 pages from Google). Helpful for testing sometimes.
100
+
101
+ ```
102
+ results = search_and_return_all_results('poker')
103
+ results.first.items.size # == 10
104
+
105
+ search_and_resturn_all_results('poker') do |results|
106
+ results.items.size # == 10 10 times
107
+ end
108
+
109
+ search_and_return_all_results(
110
+ '"California cult winery known for its Rhône"') do |results|
111
+ results.items.size # == 3 1 time
112
+ end
113
+ ```
114
+
115
+ ### Errors
116
+
117
+ Custom Search only returns a maximum of 100 results so - if you try something like
118
+
119
+ ```
120
+ results = GoogleCustomSearchApi.search('poker', start: 101)
121
+ ```
122
+ You get error and empty items.
123
+
124
+ ```
125
+ {
126
+ "error"=> {
127
+ "errors"=> [
128
+ {
129
+ "domain"=>"global",
130
+ "reason"=>"invalid",
131
+ "message"=>"Invalid Value"
132
+ }
133
+ ],
134
+ "code"=>400,
135
+ "message"=>"Invalid Value"
136
+ },
137
+ "items"=>[]
138
+ }
139
+ ```
140
+
141
+ So check for:
142
+
143
+ ```
144
+ if results.try(:error) || results.items.empty?
145
+ ```
146
+ ### Rails example
147
+
148
+ In **Gemfile**
149
+
150
+ ```
151
+ gem "google_custom_search_api"
152
+ ```
153
+
154
+ In **config/initializers/google_search.rb**
155
+
156
+ ```
157
+ GOOGLE_API_KEY = '...'
158
+ GOOGLE_SEARCH_CX = '...'
159
+ ```
160
+
161
+ In **config/routes.rb**
162
+
163
+ ```
164
+ get '/search' => 'search#index'
165
+ ```
166
+
167
+ In **app/controllers/search_controller.rb** you'd have something like this:
168
+
169
+ ```
170
+ class SearchController < ApplicationController
171
+ def index
172
+ if params[:q]
173
+ page = params[:page] || 1
174
+ @results = GoogleCustomSearchApi.search(params[:q],
175
+ page: page)
176
+ end
177
+ end
178
+ end
179
+ ```
180
+
181
+ And a simple view might look like this **app/search/index.html.erb** (this is using bootstrap styling)
182
+
183
+ ```
184
+ <section class='search-section'>
185
+ <div class='text-center titles-with-yellow'>
186
+ <h1>Search/h1>
187
+ </div>
188
+ <div class='container'>
189
+ <div class='text-center search-bar'>
190
+ <%= form_tag search_path, method: :get do %>
191
+ <div class="inner-addon right-addon">
192
+ <i class="glyphicon glyphicon-search"></i>
193
+ <%= text_field_tag :q, params[:q], class: 'form-control' %>
194
+ </div>
195
+ <% end %>
196
+ </div>
197
+ </div>
198
+
199
+ <% if @results && !@results.items.empty? %>
200
+ <div class='container'>
201
+ <% @results.items.each do |item| %>
202
+ <div class='row'>
203
+ <h4><%= link_to item.htmlTitle.html_safe, item.link %></h4>
204
+ <div>
205
+ <% if item['pagemap'] &&
206
+ item['pagemap']['cse_thumbnail'] &&
207
+ img = item.pagemap.cse_thumbnail.first %>
208
+ <div class='col-sm-2'>
209
+ <%= image_tag(img.src, width: '200px') %>
210
+ </div>
211
+ <div class='col-sm-10'>
212
+ <%= item.htmlSnippet.html_safe %>
213
+ </div>
214
+ <% else %>
215
+ <%= item.htmlSnippet.html_safe %>
216
+ <% end %>
217
+ </div>
218
+ </div>
219
+ <% end %>
220
+ </div>
221
+ <div class='container search-prev-next'>
222
+ <div class='row text-center'>
223
+ <% if @results.previous_page %>
224
+ <%= link_to '<< Previous',
225
+ search_path(q: params[:q], page: @results.previous_page),
226
+ class: 'btn' %>
227
+ <% end %>
228
+ <% @results.pages.times do |i| %>
229
+ <%= link_to i + 1,
230
+ search_path(q: params[:q], page: i+1),
231
+ class: 'btn btn-page' %>
232
+ <% end %>
233
+ <% if @results.next_page %>
234
+ <%= link_to 'Next >>',
235
+ search_path(q: params[:q],
236
+ page: @results.next_page),
237
+ class: 'btn' %>
238
+ <% end %>
239
+ </div>
240
+ </div>
241
+ <% else %>
242
+ <h4>No results</h4>
243
+ <% end %>
244
+ </section>
245
+ ```
246
+
247
+ ### Encoding issues
248
+
249
+ TODO - this section needs work
250
+
251
+ CSE will return non utf-8 results which can be problematic. I might add in a config value that you can explicitly set encoding. Until then a work around is doing stuff like:
252
+
253
+ ```
254
+ results.items.first.title.force_encoding(Encoding::UTF_8)
255
+ ```
256
+
257
+ More on this here: http://code.google.com/apis/customsearch/docs/ref_encoding.html
258
+
259
+ ## Contributing - Running tests
260
+
261
+ Pull requests welcome.
262
+
263
+ To run tests
264
+ ```
265
+ git clone git@github.com:wiseleyb/google_custom_search_api.git
266
+ cd google_custom_search_api
267
+ bundle install
268
+ bundle exec rspec spec
269
+ ```
270
+
271
+ ## Credits
272
+ * Based largely on the gem https://github.com/alexreisner/google_custom_search
273
+ * Awesome ResponseData class from https://github.com/mikedemers/rbing
274
+ * Work done while working on a project for the company http://reInteractive.net in sunny Sydney. A great ruby shop should you need help with something.
275
+
276
+ Copyright (c) 2012 Ben Wiseley, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/*_test.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => :test
12
+
13
+ require 'rake/rdoctask'
14
+ Rake::RDocTask.new do |rdoc|
15
+ rdoc.rdoc_dir = 'rdoc'
16
+ rdoc.title = "Google Custom Search API #{GoogleCustomSearch::VERSION}"
17
+ rdoc.rdoc_files.include('*.rdoc')
18
+ rdoc.rdoc_files.include('lib/**/*.rb')
19
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "addressable/uri"
2
+ require 'google_custom_search_api'
@@ -0,0 +1,178 @@
1
+ ##
2
+ # Add search functionality (via Google Custom Search). Protocol reference at:
3
+ # http://www.google.com/coop/docs/cse/resultsxml.html
4
+ #
5
+
6
+ require 'httparty'
7
+ require 'addressable/uri'
8
+
9
+ module GoogleCustomSearchApi
10
+ extend self
11
+
12
+ ##
13
+ # Search the site.
14
+ #
15
+ # opts
16
+ # see list here for valid options
17
+ # http://code.google.com/apis/customsearch/v1/using_rest.html#query-params
18
+ def search(query, opts = {})
19
+ opts[:start] ||= 1
20
+
21
+ if (page = opts.delete(:page))
22
+ page = page.to_i
23
+ opts[:start] = (page - 1).abs * 10 + 1
24
+ else
25
+ page = (opts[:start].to_i / 10) + 1
26
+ end
27
+ page = 10 if page > 10
28
+
29
+ # Get and parse results.
30
+ url = url(query, opts)
31
+ return nil unless results = fetch(url)
32
+
33
+ results['items'] ||= []
34
+
35
+ # paging
36
+ if results.keys.include?('queries')
37
+ data = results['queries']['request'].first
38
+ results['pages'] = data['totalResults'].to_i / 10
39
+ results['pages'] = 10 if results['pages'] > 10
40
+ results['current_page'] = page.to_i
41
+
42
+ results['next_page'] = nil
43
+ results['previous_page'] = nil
44
+
45
+ if results['queries'].include?('nextPage') && page < 10
46
+ results['next_page'] = results['current_page'] + 1
47
+ end
48
+
49
+ if page > 1
50
+ results['previous_page'] = page - 1
51
+ end
52
+ end
53
+
54
+ ResponseData.new(results)
55
+ end
56
+
57
+ ##
58
+ # Search the site for all available results (max 100)
59
+ #
60
+ # This isn't so useful because it's quite slow
61
+ #
62
+ # Returns an array of up to 10 search(query) results
63
+ #
64
+ # examples:
65
+ #
66
+ # results = search_and_return_all_results('poker')
67
+ # results.first.items.size # == 10
68
+ #
69
+ # search_and_resturn_all_results('poker') do |results|
70
+ # results.items.size # == 10 10 times
71
+ # end
72
+ #
73
+ # search_and_return_all_results(
74
+ # '"California cult winery known for its Rhône"') do |results|
75
+ # results.items.size # == 3 1 time
76
+ # end
77
+ #
78
+ # opts
79
+ # see list here for valid options
80
+ # http://code.google.com/apis/customsearch/v1/using_rest.html#query-params
81
+ def search_and_return_all_results(query, opts = {})
82
+ res = []
83
+ opts[:start] ||= 1
84
+ begin
85
+ results = GoogleCustomSearchApi.search(query, opts)
86
+ return res unless results.keys.include?('queries')
87
+ yield results if block_given?
88
+ res << results
89
+ if results.queries.keys.include?("nextPage")
90
+ opts[:start] = results.queries.nextPage.first.startIndex
91
+ else
92
+ opts[:start] = nil
93
+ end
94
+ end while opts[:start].nil? == false
95
+ return res
96
+ end
97
+
98
+ # Convenience wrapper for the response Hash.
99
+ # Converts keys to Strings. Crawls through all
100
+ # member data and converts any other Hashes it
101
+ # finds. Provides access to values through
102
+ # method calls, which will convert underscored
103
+ # to camel case.
104
+ #
105
+ # Usage:
106
+ #
107
+ # rd = ResponseData.new("AlphaBeta" => 1,
108
+ # "Results" => {
109
+ # "Gamma" => 2,
110
+ # "delta" => [3, 4]})
111
+ # puts rd.alpha_beta
112
+ # => 1
113
+ # puts rd.alpha_beta.results.gamma
114
+ # => 2
115
+ # puts rd.alpha_beta.results.delta
116
+ # => [3, 4]
117
+ #
118
+ class ResponseData < Hash
119
+ private
120
+ def initialize(data={})
121
+ data.each_pair {|k,v| self[k.to_s] = deep_parse(v) }
122
+ end
123
+
124
+ def deep_parse(data)
125
+ case data
126
+ when Hash
127
+ self.class.new(data)
128
+ when Array
129
+ data.map {|v| deep_parse(v) }
130
+ else
131
+ data
132
+ end
133
+ end
134
+
135
+ def method_missing(*args)
136
+ name = args[0].to_s
137
+ return self[name] if has_key? name
138
+
139
+ camelname = name.split('_').map do |w|
140
+ "#{w[0,1].upcase}#{w[1..-1]}"
141
+ end.join("")
142
+
143
+ if has_key? camelname
144
+ self[camelname]
145
+ else
146
+ super *args
147
+ end
148
+ end
149
+ end
150
+
151
+
152
+ private
153
+
154
+ ##
155
+ # Build search request URL.
156
+ #
157
+ # see list here for valid options
158
+ # http://code.google.com/apis/customsearch/v1/using_rest.html#query-params
159
+ def url(query, opts = {})
160
+ opts[:q] = query
161
+ opts[:alt] ||= "json"
162
+ uri = Addressable::URI.new
163
+ uri.query_values = opts
164
+ begin
165
+ params.merge!(GOOGLE_SEARCH_PARAMS)
166
+ rescue NameError
167
+ end
168
+ "https://www.googleapis.com/customsearch/v1?" \
169
+ "key=#{opts[:api_key]}&cx=#{opts[:cx_key]}&#{uri.query}"
170
+ end
171
+
172
+ ##
173
+ # Query Google, and make sure it responds.
174
+ #
175
+ def fetch(url)
176
+ return HTTParty.get(url)
177
+ end
178
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module GoogleCustomSearchApi
2
+ VERSION = "2.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sk_google_custom_search_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrey Skuratovsky
8
+ - Ben Wiseley
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-02-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: addressable
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: vcr
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: webmock
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: json
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ description: Ruby lib for Google's Custom Search Api.
99
+ email:
100
+ - skuratowsky@gmail.com
101
+ - wiseleyb@gmail.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - CHANGELOG.rdoc
107
+ - Gemfile
108
+ - Gemfile.lock
109
+ - LICENSE
110
+ - README.md
111
+ - Rakefile
112
+ - init.rb
113
+ - lib/google_custom_search_api.rb
114
+ - lib/version.rb
115
+ homepage: http://github.com/askuratovsky/google_custom_search_api
116
+ licenses: []
117
+ metadata: {}
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 2.4.3
135
+ signing_key:
136
+ specification_version: 4
137
+ summary: Ruby lib for Google's Custom Search Api.
138
+ test_files: []