google_search 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.rdoc +18 -0
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/google_search.gemspec +6 -5
- data/lib/google_search.rb +4 -22
- data/lib/google_search/google_search.rb +59 -0
- data/lib/google_search/google_search_error.rb +2 -0
- data/spec/google_search_paginated_spec.rb +27 -0
- data/spec/google_search_spec.rb +19 -9
- data/spec/spec_helper.rb +23 -0
- metadata +6 -12
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -16,6 +16,24 @@ You can also search videos, images, books etc. by calling <tt>GoogleSearch.[SEAR
|
|
16
16
|
|
17
17
|
For documention on options and response formats see http://code.google.com/intl/hr/apis/ajaxsearch/documentation/reference.html#_intro_fonje
|
18
18
|
|
19
|
+
=== Default options
|
20
|
+
|
21
|
+
You may specify default options that go into every request. Usually you'll put your API key here.
|
22
|
+
|
23
|
+
GoogleSearch.default_options = { :key => "my-key", :hl => "hr" }
|
24
|
+
|
25
|
+
=== Paginated search
|
26
|
+
|
27
|
+
GoogleSearch.with_pages(1..5) do |search|
|
28
|
+
search.images(:q => "moon")
|
29
|
+
end
|
30
|
+
|
31
|
+
This will do search 5 times, each time given a different page (1..5). Useful for getting more results at once.
|
32
|
+
|
33
|
+
=== Handling errors
|
34
|
+
|
35
|
+
On invalid response a GoogleSearchError is raised, describing the error.
|
36
|
+
|
19
37
|
== Copyright
|
20
38
|
|
21
39
|
Copyright (c) 2010 Sasa Brankovic. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -12,7 +12,6 @@ begin
|
|
12
12
|
gem.authors = ["Sasa Brankovic"]
|
13
13
|
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
14
|
gem.add_dependency "activesupport"
|
15
|
-
gem.add_dependency "addressable"
|
16
15
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
16
|
end
|
18
17
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.1.0
|
data/google_search.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{google_search}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Sasa Brankovic"]
|
12
|
-
s.date = %q{2010-02-
|
12
|
+
s.date = %q{2010-02-03}
|
13
13
|
s.email = %q{sasa@hakeraj.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE",
|
@@ -24,6 +24,9 @@ Gem::Specification.new do |s|
|
|
24
24
|
"VERSION",
|
25
25
|
"google_search.gemspec",
|
26
26
|
"lib/google_search.rb",
|
27
|
+
"lib/google_search/google_search.rb",
|
28
|
+
"lib/google_search/google_search_error.rb",
|
29
|
+
"spec/google_search_paginated_spec.rb",
|
27
30
|
"spec/google_search_spec.rb",
|
28
31
|
"spec/spec.opts",
|
29
32
|
"spec/spec_helper.rb"
|
@@ -35,6 +38,7 @@ Gem::Specification.new do |s|
|
|
35
38
|
s.summary = %q{Tiny wrapper for Google Search API}
|
36
39
|
s.test_files = [
|
37
40
|
"spec/google_search_spec.rb",
|
41
|
+
"spec/google_search_paginated_spec.rb",
|
38
42
|
"spec/spec_helper.rb"
|
39
43
|
]
|
40
44
|
|
@@ -45,16 +49,13 @@ Gem::Specification.new do |s|
|
|
45
49
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
46
50
|
s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
|
47
51
|
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
48
|
-
s.add_runtime_dependency(%q<addressable>, [">= 0"])
|
49
52
|
else
|
50
53
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
51
54
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
52
|
-
s.add_dependency(%q<addressable>, [">= 0"])
|
53
55
|
end
|
54
56
|
else
|
55
57
|
s.add_dependency(%q<rspec>, [">= 1.2.9"])
|
56
58
|
s.add_dependency(%q<activesupport>, [">= 0"])
|
57
|
-
s.add_dependency(%q<addressable>, [">= 0"])
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
data/lib/google_search.rb
CHANGED
@@ -1,24 +1,6 @@
|
|
1
|
-
require 'active_support'
|
2
1
|
require 'open-uri'
|
3
|
-
require '
|
4
|
-
|
5
|
-
module GoogleSearch
|
6
|
-
@@default_options = {}
|
7
|
-
|
8
|
-
def self.default_options(options = {})
|
9
|
-
@@default_options = options
|
10
|
-
end
|
11
|
-
|
12
|
-
def self.method_missing(method, args)
|
13
|
-
raise unless [:web, :local, :video, :blogs, :news, :books, :images, :patent].include?(method)
|
14
|
-
self.query(method, args)
|
15
|
-
end
|
2
|
+
require 'active_support'
|
3
|
+
require 'cgi'
|
16
4
|
|
17
|
-
|
18
|
-
|
19
|
-
uri = Addressable::URI.parse("http://ajax.googleapis.com/ajax/services/search/#{type}")
|
20
|
-
options[:v] = "1.0"
|
21
|
-
uri.query_values = @@default_options.merge(options)
|
22
|
-
ActiveSupport::JSON.decode(open(uri).read)
|
23
|
-
end
|
24
|
-
end
|
5
|
+
require 'google_search/google_search'
|
6
|
+
require 'google_search/google_search_error'
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class GoogleSearch
|
2
|
+
##
|
3
|
+
# :singleton-method:
|
4
|
+
# Sets up default options that should be present in every request
|
5
|
+
cattr_accessor :default_options
|
6
|
+
|
7
|
+
##
|
8
|
+
# :singleton-method: web(options)
|
9
|
+
|
10
|
+
##
|
11
|
+
# :singleton-method: video(options)
|
12
|
+
|
13
|
+
##
|
14
|
+
# :singleton-method: blogs(options)
|
15
|
+
|
16
|
+
##
|
17
|
+
# :singleton-method: news(options)
|
18
|
+
|
19
|
+
##
|
20
|
+
# :singleton-method: books(options)
|
21
|
+
|
22
|
+
##
|
23
|
+
# :singleton-method: images(options)
|
24
|
+
|
25
|
+
##
|
26
|
+
# :singleton-method: patent(options)
|
27
|
+
|
28
|
+
def self.method_missing(method, args) # :nodoc:
|
29
|
+
raise "Unknown search type '#{method}'" unless self.supported_search_types.include?(method)
|
30
|
+
self.query(method, args)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Yields the search object for number +pages+ specified.
|
34
|
+
# Each page will contain 8 results, +pages+ must be something enumerable
|
35
|
+
def self.with_pages(pages)
|
36
|
+
pages.each do |page|
|
37
|
+
GoogleSearch.with_options :rsz => "large", :start => (page - 1) * 8 do |search|
|
38
|
+
yield search
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def self.supported_search_types
|
45
|
+
[:web, :local, :video, :blogs, :news, :books, :images, :patent]
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.query(type, options)
|
49
|
+
options = (self.default_options || {}).merge(options)
|
50
|
+
options[:v] = "1.0"
|
51
|
+
|
52
|
+
query_string = options.collect { |key, value| "#{key}=#{CGI::escape(value.to_s)}" }.join("&")
|
53
|
+
uri = "http://ajax.googleapis.com/ajax/services/search/#{type}?#{query_string}"
|
54
|
+
|
55
|
+
result = ActiveSupport::JSON.decode(open(uri).read)
|
56
|
+
raise GoogleSearchError, "#{result['responseStatus']} - #{result['responseDetails']}" unless result["responseStatus"] == 200
|
57
|
+
result
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "Doing a paginated search" do
|
4
|
+
context "Searching 3 pages" do
|
5
|
+
before do
|
6
|
+
@results = []
|
7
|
+
GoogleSearch.with_pages(1..3) do |search|
|
8
|
+
@results << search.images(:q => "moon")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it "page should be called 3 times" do
|
13
|
+
@results.size.should == 3
|
14
|
+
end
|
15
|
+
|
16
|
+
it "each page results should originate from its page" do
|
17
|
+
page = 0
|
18
|
+
|
19
|
+
puts @results.each do
|
20
|
+
|result|
|
21
|
+
page.should == result["responseData"]["cursor"]["currentPageIndex"].to_i
|
22
|
+
page += 1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/spec/google_search_spec.rb
CHANGED
@@ -1,22 +1,32 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
2
2
|
|
3
3
|
describe "Google search" do
|
4
|
-
context "Doing a query" do
|
5
|
-
require 'google_search'
|
6
|
-
|
4
|
+
context "Doing a valid query" do
|
7
5
|
before :all do
|
8
|
-
GoogleSearch.default_options :hl => "hr"
|
9
|
-
@result = GoogleSearch.web :q => "Michael Jackson"
|
6
|
+
GoogleSearch.default_options = { :hl => "hr" }
|
7
|
+
@result = GoogleSearch.web :q => "Michael Jackson", :start => 10
|
10
8
|
end
|
11
9
|
|
12
|
-
it do
|
10
|
+
it "result should be a hash" do
|
13
11
|
@result.should be_a_kind_of Hash
|
14
12
|
end
|
15
13
|
|
16
|
-
it "should have
|
17
|
-
@result.should
|
18
|
-
|
14
|
+
it "should be have status OK" do
|
15
|
+
@result["responseStatus"].should == 200
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should have results" do
|
19
19
|
@result["responseData"]["results"].should_not be_empty
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
context "Doing an invalid query" do
|
24
|
+
before :all do
|
25
|
+
@query = lambda { GoogleSearch.web :this_wont_work => true }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should raise an exception" do
|
29
|
+
@query.should raise_error GoogleSearchError
|
30
|
+
end
|
31
|
+
end
|
22
32
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,32 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
3
4
|
require 'google_search'
|
4
5
|
require 'spec'
|
5
6
|
require 'spec/autorun'
|
6
7
|
|
7
8
|
Spec::Runner.configure do |config|
|
9
|
+
config.before :all do
|
10
|
+
# The open method, used by GoogleSearch, will get cached so we
|
11
|
+
# don't bombard Google each time we do testing. Cache is stored
|
12
|
+
# in tmp/cached_open.
|
13
|
+
GoogleSearch.should_receive(:open).any_number_of_times.and_return { |url| cached_open(url) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'digest/md5'
|
18
|
+
require 'fileutils'
|
19
|
+
|
20
|
+
def cached_open(url)
|
21
|
+
dir = "tmp/cached_open"
|
22
|
+
FileUtils::mkdir_p(dir) unless File.exists?(dir)
|
23
|
+
|
24
|
+
path = File.join(dir, Digest::MD5.hexdigest(url))
|
25
|
+
|
26
|
+
unless File.exists?(path)
|
27
|
+
content = open(url).read
|
28
|
+
File.open(path, "w") { |f| f.puts(content) }
|
29
|
+
end
|
8
30
|
|
31
|
+
open(path)
|
9
32
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: google_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sasa Brankovic
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-03 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -32,16 +32,6 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: "0"
|
34
34
|
version:
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: addressable
|
37
|
-
type: :runtime
|
38
|
-
version_requirement:
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
requirements:
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: "0"
|
44
|
-
version:
|
45
35
|
description:
|
46
36
|
email: sasa@hakeraj.com
|
47
37
|
executables: []
|
@@ -60,6 +50,9 @@ files:
|
|
60
50
|
- VERSION
|
61
51
|
- google_search.gemspec
|
62
52
|
- lib/google_search.rb
|
53
|
+
- lib/google_search/google_search.rb
|
54
|
+
- lib/google_search/google_search_error.rb
|
55
|
+
- spec/google_search_paginated_spec.rb
|
63
56
|
- spec/google_search_spec.rb
|
64
57
|
- spec/spec.opts
|
65
58
|
- spec/spec_helper.rb
|
@@ -93,4 +86,5 @@ specification_version: 3
|
|
93
86
|
summary: Tiny wrapper for Google Search API
|
94
87
|
test_files:
|
95
88
|
- spec/google_search_spec.rb
|
89
|
+
- spec/google_search_paginated_spec.rb
|
96
90
|
- spec/spec_helper.rb
|