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 CHANGED
@@ -17,5 +17,6 @@ tmtags
17
17
  coverage
18
18
  rdoc
19
19
  pkg
20
+ tmp
20
21
 
21
22
  ## PROJECT::SPECIFIC
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.0.0
1
+ 1.1.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{google_search}
8
- s.version = "1.0.0"
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-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 'addressable/uri'
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
- private
18
- def self.query(type, options)
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,2 @@
1
+ class GoogleSearchError < RuntimeError
2
+ 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
@@ -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 expected values" do
17
- @result.should have_key "responseData"
18
- @result["responseData"].should have_key "results"
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.0.0
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-02 00:00:00 +01:00
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