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 +7 -0
- data/CHANGELOG.rdoc +2 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +52 -0
- data/LICENSE +20 -0
- data/README.md +276 -0
- data/Rakefile +19 -0
- data/init.rb +2 -0
- data/lib/google_custom_search_api.rb +178 -0
- data/lib/version.rb +3 -0
- metadata +138 -0
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
data/Gemfile
ADDED
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,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
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: []
|