google_search 1.0.0 → 1.1.0
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.
- 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
|