googleajax 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +11 -0
- data/README.txt +35 -1
- data/VERSION +1 -1
- data/lib/googleajax/api.rb +57 -0
- data/lib/googleajax/as_hash.rb +2 -15
- data/lib/googleajax/as_open_struct.rb +20 -0
- data/lib/googleajax/base.rb +4 -23
- data/lib/googleajax/basic.rb +9 -0
- data/lib/googleajax/extensions/hash.rb +21 -0
- data/lib/googleajax/extensions/kernel.rb +9 -0
- data/lib/googleajax/extensions/string.rb +15 -0
- data/lib/googleajax/feed.rb +13 -24
- data/lib/googleajax/filters.rb +70 -0
- data/lib/googleajax/hash.rb +10 -0
- data/lib/googleajax/language.rb +68 -64
- data/lib/googleajax/request.rb +21 -0
- data/lib/googleajax/results.rb +14 -0
- data/lib/googleajax/search.rb +34 -50
- data/lib/googleajax.rb +16 -24
- data/spec/{googleajax_as_hash_spec.rb → googleajax_as_open_struct_spec.rb} +5 -5
- data/spec/googleajax_basic_spec.rb +13 -0
- data/spec/googleajax_common.rb +15 -9
- data/spec/googleajax_spec.rb +3 -3
- data/spec/spec_helper.rb +1 -0
- metadata +16 -5
- data/lib/googleajax/parser.rb +0 -38
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
=== 1.0.0 / 2009-12-17
|
2
|
+
|
3
|
+
* Incompatible changes:
|
4
|
+
* Returns Hashes instead of OpenStruct by default (require googleajax/as_open_struct if you need OpenStruct)
|
5
|
+
* Indices are symbols with underscores instead of camelcased string, (e.g. :estimated_count instead of "estimatedCount")
|
6
|
+
* Values are converted automatically for Floats, Integers and true and false.
|
7
|
+
|
8
|
+
* translate accepts :english, :french, etc... as source or destination languages in addition to the language codes
|
9
|
+
|
10
|
+
* Much more flexible structure.
|
11
|
+
|
1
12
|
=== 0.2.0 / 2009-11-17
|
2
13
|
|
3
14
|
* New features:
|
data/README.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= GoogleAjax
|
2
2
|
|
3
3
|
* Docs: http://googleajax.rubyforge.org
|
4
|
-
* Code: http://github.com/
|
4
|
+
* Code: http://github.com/geemus/googleajax
|
5
5
|
|
6
6
|
== DESCRIPTION:
|
7
7
|
|
@@ -9,6 +9,8 @@ Ruby wrapper for Google AJAX API REST interfaces(Feeds, Language and Search).
|
|
9
9
|
|
10
10
|
== SYNOPSIS:
|
11
11
|
|
12
|
+
require "googleajax"
|
13
|
+
|
12
14
|
# First, setup referer:
|
13
15
|
GoogleAjax.referer = [your domain name here]
|
14
16
|
|
@@ -53,6 +55,37 @@ Ruby wrapper for Google AJAX API REST interfaces(Feeds, Language and Search).
|
|
53
55
|
# Find top 4 web page results for 'Hello world'
|
54
56
|
GoogleAjax::Search.web('Hello world')
|
55
57
|
|
58
|
+
# Find top 10 feeds for 'ruby'
|
59
|
+
GoogleAjax::Feed.find('ruby')
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
=== Results
|
64
|
+
|
65
|
+
Results from the methods are hashes, automatically converted from the response from Google.
|
66
|
+
|
67
|
+
For example:
|
68
|
+
|
69
|
+
# Find top 4 web page results for 'Hello world'
|
70
|
+
GoogleAjax::Search.web('Hello world')
|
71
|
+
# => { :results=>[
|
72
|
+
# { :title=>"<b>Hello world</b> program - Wikipedia, the free encyclopedia",
|
73
|
+
# # ... more data ...
|
74
|
+
# :url=>"http://en.wikipedia.org/wiki/Hello_world_program"
|
75
|
+
# },
|
76
|
+
# # ... more results
|
77
|
+
# ],
|
78
|
+
# :cursor=>{
|
79
|
+
# :current_page_index=>0,
|
80
|
+
# # ... more data ...
|
81
|
+
# :estimated_result_count=>57800000
|
82
|
+
# }
|
83
|
+
# }
|
84
|
+
|
85
|
+
When possible, the result is simplified:
|
86
|
+
* Feed.find will return an array instead of {:entries => array}
|
87
|
+
* Feed.load will return the feed instead of {:feed => feed}
|
88
|
+
|
56
89
|
== REQUIREMENTS:
|
57
90
|
|
58
91
|
* JSON gem to parse responses, or rails
|
@@ -66,6 +99,7 @@ Ruby wrapper for Google AJAX API REST interfaces(Feeds, Language and Search).
|
|
66
99
|
(The MIT License)
|
67
100
|
|
68
101
|
Copyright (c) 2009 {geemus (Wesley Beary)}[http://github.com/geemus]
|
102
|
+
and {Marc-Andre Lafortune}[http://github.com/marcandre]
|
69
103
|
|
70
104
|
Permission is hereby granted, free of charge, to any person obtaining
|
71
105
|
a copy of this software and associated documentation files (the
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module GoogleAjax
|
2
|
+
# The API module provides generic methods to call the Google API
|
3
|
+
# These are specialized in the different APIs (Language, Search & Feed)
|
4
|
+
module API
|
5
|
+
|
6
|
+
# All APIs have a default version of 1.0 (override otherwise)
|
7
|
+
def version
|
8
|
+
1.0
|
9
|
+
end
|
10
|
+
|
11
|
+
# All APIs have, by default version a kind corresponding to their name (e.g. "language")
|
12
|
+
def kind
|
13
|
+
@kind ||= name.demodulize.downcase.to_sym
|
14
|
+
end
|
15
|
+
|
16
|
+
# Sends the request to google and converts it to Ruby
|
17
|
+
# A block can be passed to alter the received hash
|
18
|
+
def get(method, query, args = {})
|
19
|
+
args = { :v => version }.merge(args)
|
20
|
+
response = GoogleAjax::get(kind, method, query, args)
|
21
|
+
data = extract_data(
|
22
|
+
parse(response)
|
23
|
+
)
|
24
|
+
data = yield data if block_given?
|
25
|
+
# Convert hashes to an instance of ourself from this data:
|
26
|
+
Filters::Recursive.remap(data, self)
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse(data)
|
30
|
+
if defined? Rails
|
31
|
+
ActiveSupport::JSON::decode(data)
|
32
|
+
else
|
33
|
+
JSON.parse(data)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# verifies the responses' status and either raises an error
|
38
|
+
# or else returns the response data.
|
39
|
+
def extract_data(hash)
|
40
|
+
status = hash['responseStatus']
|
41
|
+
unless (200..206).include? status
|
42
|
+
raise StandardError, hash['responseDetails'] || "Wrong status code (#{status.inspect})"
|
43
|
+
end
|
44
|
+
hash['responseData']
|
45
|
+
end
|
46
|
+
|
47
|
+
# Since most api have the same form, this helper can create these calls easily.
|
48
|
+
# If a block is given, it will be passed to #get
|
49
|
+
def standard_api(*methods, &block)
|
50
|
+
methods.each do |method|
|
51
|
+
define_singleton_method(method) do |*args|
|
52
|
+
get(method, *args, &block)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/googleajax/as_hash.rb
CHANGED
@@ -1,15 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module GoogleAjax
|
4
|
-
class Base < Hash
|
5
|
-
def initialize(h)
|
6
|
-
super()
|
7
|
-
replace(h)
|
8
|
-
end
|
9
|
-
|
10
|
-
def self.remap(h)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
require 'googleajax'
|
1
|
+
warn "requiring 'googleajax/as_hash' is deprecated. Require 'googleajax' instead"
|
2
|
+
require 'googleajax'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# If you prefer getting back OpenStructs instead of Hashes,
|
2
|
+
# then require 'googleajax/as_open_struct' *instead* of 'googleajax'
|
3
|
+
|
4
|
+
# These OpenStruct will also have the [] and []= operators defined
|
5
|
+
require 'ostruct'
|
6
|
+
require 'googleajax/filters'
|
7
|
+
module GoogleAjax
|
8
|
+
class Base < ::OpenStruct
|
9
|
+
include Filters::Default
|
10
|
+
|
11
|
+
def [](key)
|
12
|
+
send(key)
|
13
|
+
end
|
14
|
+
|
15
|
+
def []=(key, value)
|
16
|
+
send("#{key}=", value)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
require 'googleajax'
|
data/lib/googleajax/base.rb
CHANGED
@@ -1,25 +1,6 @@
|
|
1
1
|
module GoogleAjax
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
def []=(key, value)
|
8
|
-
send("#{key}=", value)
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.remap(h)
|
12
|
-
define_method(:initialize) do |arg|
|
13
|
-
super(arg)
|
14
|
-
h.each do |key, klass|
|
15
|
-
case self[key]
|
16
|
-
when Array
|
17
|
-
self[key] = self[key].map(&klass.method(:new))
|
18
|
-
when Hash
|
19
|
-
self[key] = klass.new(self[key])
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
2
|
+
# See Results
|
3
|
+
class Base < Hash
|
4
|
+
include Filters::Default
|
24
5
|
end
|
25
|
-
end
|
6
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Hash
|
2
|
+
# From the 'backports' gem
|
3
|
+
# New Ruby 1.8.7+ constructor -- not documented, see redmine # 1385
|
4
|
+
# <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt>
|
5
|
+
unless (Hash[[[:test, :test]]] rescue false)
|
6
|
+
class << self
|
7
|
+
alias_method :constructor_without_key_value_pair_form, :[]
|
8
|
+
def [](*args)
|
9
|
+
return constructor_without_key_value_pair_form(*args) unless args.length == 1 && args.first.is_a?(Array)
|
10
|
+
h = {}
|
11
|
+
args.first.each do |arr|
|
12
|
+
next unless arr.respond_to? :to_ary
|
13
|
+
arr = arr.to_ary
|
14
|
+
next unless (1..2).include? arr.size
|
15
|
+
h[arr.at(0)] = arr.at(1)
|
16
|
+
end
|
17
|
+
h
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Kernel
|
2
|
+
# From the backports gem
|
3
|
+
# Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Object.html]
|
4
|
+
def define_singleton_method(*args, &block)
|
5
|
+
class << self
|
6
|
+
self
|
7
|
+
end.send(:define_method, *args, &block)
|
8
|
+
end unless method_defined? :define_singleton_method
|
9
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class String
|
2
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
|
3
|
+
def underscore
|
4
|
+
gsub(/::/, '/').
|
5
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
6
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
7
|
+
tr("-", "_").
|
8
|
+
downcase
|
9
|
+
end unless method_defined? :underscore
|
10
|
+
|
11
|
+
# Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html]
|
12
|
+
def demodulize
|
13
|
+
gsub(/^.*::/, '')
|
14
|
+
end unless method_defined? :demodulize
|
15
|
+
end
|
data/lib/googleajax/feed.rb
CHANGED
@@ -1,35 +1,24 @@
|
|
1
1
|
module GoogleAjax
|
2
|
-
|
3
|
-
|
4
|
-
#
|
5
|
-
|
6
|
-
args = { :v => FEED_VERSION }.merge(args)
|
7
|
-
GoogleAjax::get(:feed, method, query, args)
|
8
|
-
end
|
9
|
-
|
2
|
+
class Feed < Results
|
3
|
+
##
|
4
|
+
# :call-seq:
|
5
|
+
# find(query, args = {})
|
10
6
|
# will return a list of feeds that match the given query
|
11
7
|
# Arguments: http://code.google.com/apis/ajaxfeeds/documentation/reference.html#_fonje_find
|
12
|
-
|
13
|
-
self.get(:find, query, args)
|
14
|
-
end
|
8
|
+
standard_api(:find){|h| h['entries']}
|
15
9
|
|
10
|
+
##
|
11
|
+
# :call-seq:
|
12
|
+
# load(url, args = {})
|
16
13
|
# downloads this feed from Google's servers
|
17
14
|
# Arguments: http://code.google.com/apis/ajaxfeeds/documentation/reference.html#_fonje_load
|
18
|
-
|
19
|
-
self.get(:load, url, args)
|
20
|
-
end
|
15
|
+
standard_api(:load){|h| h['feed']}
|
21
16
|
|
17
|
+
##
|
18
|
+
# :call-seq:
|
19
|
+
# lookup(url, args = {})
|
22
20
|
# will return the associated feed if it exists for a given url
|
23
21
|
# Arguments: http://code.google.com/apis/ajaxfeeds/documentation/reference.html#_intro_fonje
|
24
|
-
|
25
|
-
self.get(:lookup, url, args)
|
26
|
-
end
|
27
|
-
|
28
|
-
class Entry < Base
|
29
|
-
end
|
30
|
-
|
31
|
-
class Feed < Base
|
32
|
-
remap :entries => Entry
|
33
|
-
end
|
22
|
+
standard_api :lookup
|
34
23
|
end
|
35
24
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module GoogleAjax
|
2
|
+
# The Result classes are initialized with a hash.
|
3
|
+
# Filters can be included to modify this hash.
|
4
|
+
module Filters
|
5
|
+
|
6
|
+
# The Recursive filter converts all Hash values to GoogleAjax::Base (recursively)
|
7
|
+
# This will also make any other filters included in GoogleAjax::Base be called
|
8
|
+
module Recursive
|
9
|
+
|
10
|
+
# A utility method to inspect value and convert Hash to base_klass, even when inside arrays
|
11
|
+
def self.remap(value, base_klass = Base)
|
12
|
+
case value
|
13
|
+
when ::Hash
|
14
|
+
base_klass.new(value)
|
15
|
+
when Array
|
16
|
+
value.map{|e| remap(e)}
|
17
|
+
else
|
18
|
+
value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(h)
|
23
|
+
h.each{|key, value| h[key] = Recursive.remap(value)}
|
24
|
+
super(h)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# The SymbolizeKeys filter converts the Javascript style keys ("someKey")
|
29
|
+
# to ruby-style keys (:some_key)
|
30
|
+
module SymbolizeKeys
|
31
|
+
def initialize(h)
|
32
|
+
h= ::Hash[
|
33
|
+
h.map do |key, value|
|
34
|
+
[key.underscore.to_sym, value]
|
35
|
+
end
|
36
|
+
]
|
37
|
+
super(h)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# The ConvertValues filter converts the string values
|
42
|
+
# to ruby-style values (e.g. Integers, Floats, true, false or Strings)
|
43
|
+
module ConvertValues
|
44
|
+
TRUE_OR_FALSE = /^true|(false)$/i
|
45
|
+
INTEGER = /^\d+$/
|
46
|
+
FLOAT = /^\d+\.\d+$/
|
47
|
+
def initialize(h)
|
48
|
+
h.each do |key, value|
|
49
|
+
# Won't use Integer.try_convert for 1.8.6 & 7 compatibility
|
50
|
+
case value
|
51
|
+
when INTEGER
|
52
|
+
h[key] = value.to_i
|
53
|
+
when FLOAT
|
54
|
+
h[key] = value.to_f
|
55
|
+
when TRUE_OR_FALSE
|
56
|
+
h[key] = Regexp.last_match[1].nil?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
super(h)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# By default, all filters are applied
|
64
|
+
module Default
|
65
|
+
include ConvertValues
|
66
|
+
include SymbolizeKeys
|
67
|
+
include Recursive
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/googleajax/language.rb
CHANGED
@@ -1,75 +1,79 @@
|
|
1
1
|
module GoogleAjax
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
args = { :v => LANGUAGE_VERSION }.merge(args)
|
6
|
-
GoogleAjax::get(:language, method, query, args)
|
2
|
+
class Language < Results
|
3
|
+
def name
|
4
|
+
LANGUAGE_NAME[self[:language]].to_s
|
7
5
|
end
|
8
|
-
|
6
|
+
|
7
|
+
##
|
8
|
+
# :call-seq:
|
9
|
+
# detect(query, args = {})
|
9
10
|
# will return the language code that describes the language of the given text
|
10
|
-
|
11
|
-
self.get(:detect, query, args)
|
12
|
-
end
|
11
|
+
standard_api :detect
|
13
12
|
|
14
|
-
#
|
13
|
+
# Translates the supplied text, matching the destination language.
|
14
|
+
# source and destination can be the language code ("en") or a symbol (:english).
|
15
|
+
# source can also be an empty string, in which case Google does an auto-detection and
|
16
|
+
# will set :detected_source_language to the language it used as a source.
|
15
17
|
def self.translate(query, source, destination, args = {})
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
class Language < Base
|
21
|
-
def name
|
22
|
-
(@@lang_cache ||= LANGUAGES.invert)[self.language]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class Translation < Base
|
18
|
+
langpair = [source, destination].map{|l| LANGUAGE_CODE[l] || l.to_s}.join("%7C")
|
19
|
+
args = { :langpair => langpair }.merge(args)
|
20
|
+
get(:translate, query, args)
|
27
21
|
end
|
28
22
|
|
29
|
-
|
23
|
+
LANGUAGE_CODE =
|
30
24
|
{
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
25
|
+
:afrikaans => "af",
|
26
|
+
:albanian => "sq",
|
27
|
+
:arabic => "ar",
|
28
|
+
:belarusian => "be",
|
29
|
+
:bulgarian => "bg",
|
30
|
+
:catalan => "ca",
|
31
|
+
:chinese => "zh-CN",
|
32
|
+
:croatian => "hr",
|
33
|
+
:czech => "cs",
|
34
|
+
:danish => "da",
|
35
|
+
:dutch => "nl",
|
36
|
+
:english => "en",
|
37
|
+
:estonian => "et",
|
38
|
+
:filipino => "tl",
|
39
|
+
:finnish => "fi",
|
40
|
+
:french => "fr",
|
41
|
+
:galician => "gl",
|
42
|
+
:german => "de",
|
43
|
+
:greek => "el",
|
44
|
+
:hebrew => "iw",
|
45
|
+
:hindi => "hi",
|
46
|
+
:hungarian => "hu",
|
47
|
+
:icelandic => "is",
|
48
|
+
:indonesian => "id",
|
49
|
+
:irish => "ga",
|
50
|
+
:italian => "it",
|
51
|
+
:japanese => "ja",
|
52
|
+
:korean => "ko",
|
53
|
+
:latvian => "lv",
|
54
|
+
:lithuanian => "lt",
|
55
|
+
:macedonian => "mk",
|
56
|
+
:malay => "ms",
|
57
|
+
:maltese => "mt",
|
58
|
+
:norwegian => "no",
|
59
|
+
:persian => "fa",
|
60
|
+
:polish => "pl",
|
61
|
+
:portuguese => "pt",
|
62
|
+
:romanian => "ro",
|
63
|
+
:russian => "ru",
|
64
|
+
:serbian => "sr",
|
65
|
+
:slovak => "sk",
|
66
|
+
:slovenian => "sl",
|
67
|
+
:spanish => "es",
|
68
|
+
:swahili => "sw",
|
69
|
+
:swedish => "sv",
|
70
|
+
:thai => "th",
|
71
|
+
:turkish => "tr",
|
72
|
+
:ukrainian => "uk",
|
73
|
+
:vietnamese => "vi",
|
74
|
+
:welsh => "cy",
|
75
|
+
:yiddish => "yi"
|
73
76
|
}
|
77
|
+
LANGUAGE_NAME = LANGUAGE_CODE.invert
|
74
78
|
end
|
75
79
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GoogleAjax
|
2
|
+
module Request
|
3
|
+
API_BASE = 'http://ajax.googleapis.com/ajax/services/'
|
4
|
+
|
5
|
+
attr_accessor :api_key
|
6
|
+
attr_accessor :referer
|
7
|
+
alias_method :referrer, :referer # See mispelling section in http://en.wikipedia.org/wiki/HTTP_referrer
|
8
|
+
alias_method :referrer=, :referer=
|
9
|
+
|
10
|
+
# Api doc is at http://code.google.com/apis/ajaxsearch/documentation/reference.html#_intro_fonje
|
11
|
+
def get(api, method, query, args = nil)
|
12
|
+
raise "You must assign a value to GoogleAjax.referer" unless referer
|
13
|
+
url = "#{API_BASE}#{api}/"
|
14
|
+
url += "#{method}?"
|
15
|
+
url += "&q=#{CGI::escape(query)}"
|
16
|
+
url += "&key=#{api_key}" if api_key
|
17
|
+
url += "&" + args.collect {|key, value| "#{key}=#{value}"}.join('&') unless args.nil? || args.empty?
|
18
|
+
open(url, "Referer" => referer).read
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module GoogleAjax
|
2
|
+
# The Results class is the superclass for the results of API calls and acts as a Hash.
|
3
|
+
# Instance methods can be added to add functionalities (e.g. Search#count)
|
4
|
+
# Class methods are the actual api calls.
|
5
|
+
#
|
6
|
+
# For example the Search api inherits from Results.
|
7
|
+
# GoogleAjax::Search.web will return an instance of GoogleAjax::Search
|
8
|
+
# Some of the values within this GoogleAjax::Search instance will also
|
9
|
+
# act as hashes. They will be instances of GoogleAjax::Base and so will
|
10
|
+
# be their values that act as hashes.
|
11
|
+
class Results < Base
|
12
|
+
extend API
|
13
|
+
end
|
14
|
+
end
|
data/lib/googleajax/search.rb
CHANGED
@@ -1,66 +1,50 @@
|
|
1
1
|
module GoogleAjax
|
2
|
-
|
3
|
-
|
4
|
-
#
|
5
|
-
def
|
6
|
-
|
7
|
-
GoogleAjax::get(:search, method, query, args)
|
8
|
-
end
|
9
|
-
|
10
|
-
# Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_blog
|
11
|
-
def self.blogs(query, args = {})
|
12
|
-
self.get(:blogs, query, args)
|
13
|
-
end
|
14
|
-
|
15
|
-
# Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_book
|
16
|
-
def self.books(query, args = {})
|
17
|
-
self.get(:books, query, args)
|
18
|
-
end
|
19
|
-
|
20
|
-
# Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_image
|
21
|
-
def self.images(query, args = {})
|
22
|
-
self.get(:images, query, args)
|
2
|
+
class Search < Results
|
3
|
+
# A shortcut to the estimated result count
|
4
|
+
# e.g. GoogleAjax.books("Iliad").count # => 60000
|
5
|
+
def count
|
6
|
+
self[:cursor][:estimated_result_count]
|
23
7
|
end
|
24
8
|
|
9
|
+
##
|
10
|
+
# :call-seq:
|
11
|
+
# local(query, args = {})
|
25
12
|
# Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_local
|
26
13
|
def self.local(query, latitude, longitude, args = {})
|
27
14
|
args = { :sll => "#{latitude},#{longitude}" }.merge(args)
|
28
|
-
|
15
|
+
get(:local, query, args)
|
29
16
|
end
|
30
17
|
|
18
|
+
##
|
19
|
+
# :call-seq:
|
20
|
+
# blogs(query, args = {})
|
21
|
+
# Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_blog
|
22
|
+
|
23
|
+
##
|
24
|
+
# :call-seq:
|
25
|
+
# books(query, args = {})
|
26
|
+
# Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_book
|
27
|
+
|
28
|
+
##
|
29
|
+
# :call-seq:
|
30
|
+
# images(query, args = {})
|
31
|
+
# Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_image
|
32
|
+
|
33
|
+
##
|
34
|
+
# :call-seq:
|
35
|
+
# news(query, args = {})
|
31
36
|
# Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_news
|
32
|
-
def self.news(query, args = {})
|
33
|
-
self.get(:news, query, args)
|
34
|
-
end
|
35
37
|
|
38
|
+
##
|
39
|
+
# :call-seq:
|
40
|
+
# video(query, args = {})
|
36
41
|
# Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_video
|
37
|
-
def self.video(query, args = {})
|
38
|
-
self.get(:video, query, args)
|
39
|
-
end
|
40
42
|
|
43
|
+
##
|
44
|
+
# :call-seq:
|
45
|
+
# web(query, args = {})
|
41
46
|
# http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_web
|
42
|
-
def self.web(query, args = {})
|
43
|
-
self.get(:web, query, args)
|
44
|
-
end
|
45
|
-
|
46
|
-
class Result < Base
|
47
|
-
end
|
48
|
-
|
49
|
-
class Page < Base
|
50
|
-
end
|
51
|
-
|
52
|
-
class Cursor < Base
|
53
|
-
remap :pages => Page
|
54
|
-
end
|
55
|
-
|
56
|
-
class Results < Base
|
57
|
-
remap :results => Result,
|
58
|
-
:cursor => Cursor
|
59
|
-
|
60
|
-
def count
|
61
|
-
self['cursor']['estimatedResultCount'].to_i
|
62
|
-
end
|
63
|
-
end
|
64
47
|
|
48
|
+
standard_api :blogs, :books, :images, :news, :video, :web
|
65
49
|
end
|
66
50
|
end
|
data/lib/googleajax.rb
CHANGED
@@ -1,31 +1,23 @@
|
|
1
1
|
require 'cgi'
|
2
2
|
require 'open-uri'
|
3
|
-
require 'ostruct'
|
4
3
|
require 'rubygems'
|
5
4
|
require 'json' unless defined?(Rails)
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
require 'googleajax/search'
|
12
|
-
require 'googleajax/parser'
|
6
|
+
# The following extensions are standard in either Ruby 1.8.7, 1.9 or rails:
|
7
|
+
require 'googleajax/extensions/kernel'
|
8
|
+
require 'googleajax/extensions/string'
|
9
|
+
require 'googleajax/extensions/hash'
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
# GoogleAjax lib:
|
12
|
+
require 'googleajax/hash'
|
13
|
+
require 'googleajax/filters'
|
14
|
+
require 'googleajax/api'
|
15
|
+
require 'googleajax/request'
|
16
|
+
require 'googleajax/base' unless GoogleAjax.const_defined?("Base")
|
17
|
+
require 'googleajax/results'
|
18
|
+
require 'googleajax/feed'
|
19
|
+
require 'googleajax/language'
|
20
|
+
require 'googleajax/search'
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
raise "You must assign a value to GoogleAjax.referer" unless referer
|
22
|
-
url = "#{API_BASE}#{api}/"
|
23
|
-
url += "#{method}?"
|
24
|
-
url += "&q=#{CGI::escape(query)}"
|
25
|
-
url += "&key=#{api_key}" if api_key
|
26
|
-
url += "&" + args.collect {|key, value| "#{key}=#{value}"}.join('&') if args && !args.empty?
|
27
|
-
data = open(url, "Referer" => referer).read
|
28
|
-
Parser.parse(api, method, data)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
22
|
+
# Final touch
|
23
|
+
GoogleAjax.extend GoogleAjax::Request
|
@@ -1,15 +1,15 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/googleajax_common')
|
3
3
|
|
4
|
-
require 'googleajax/
|
4
|
+
require 'googleajax/as_open_struct'
|
5
5
|
|
6
|
-
describe "GoogleAjax/
|
6
|
+
describe "GoogleAjax/as_open_struct" do
|
7
7
|
it_should_behave_like "GoogleAjax"
|
8
8
|
|
9
|
-
it "returns results as
|
9
|
+
it "returns results as an OpenStuct" do
|
10
10
|
GoogleAjax.referer = "http://example.com"
|
11
11
|
response = GoogleAjax::Search.web("apple", :rsz => :large)
|
12
|
-
response.is_a?
|
13
|
-
response
|
12
|
+
response.is_a? OpenStruct
|
13
|
+
response.cursor.is_a? OpenStruct
|
14
14
|
end
|
15
15
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/googleajax_common')
|
3
|
+
|
4
|
+
require 'googleajax/basic'
|
5
|
+
|
6
|
+
describe "GoogleAjax (basic)" do
|
7
|
+
it "returns results as an unaltered hash" do
|
8
|
+
GoogleAjax.referer = "http://example.com"
|
9
|
+
response = GoogleAjax::Search.web("apple", :rsz => :large)
|
10
|
+
response.should be_kind_of(Hash)
|
11
|
+
response['cursor'].should be_an_instance_of(Hash)
|
12
|
+
end
|
13
|
+
end
|
data/spec/googleajax_common.rb
CHANGED
@@ -13,7 +13,7 @@ shared_examples_for "GoogleAjax" do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "returns the expected results" do
|
16
|
-
@response[
|
16
|
+
@response[:results].select{|result| result[:url] =~ /http:(.*).apple.com/}.size.should >= 4
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -33,7 +33,7 @@ shared_examples_for "GoogleAjax" do
|
|
33
33
|
|
34
34
|
it "takes options into account" do
|
35
35
|
@response_large = GoogleAjax::Search.send(method, "ruby", *(args+[{:rsz => :large}]))
|
36
|
-
@response_large[
|
36
|
+
@response_large[:results].size.should > @response_small[:results].size
|
37
37
|
end unless method == :blogs # Google doesn't seem to support this option for blogs???
|
38
38
|
|
39
39
|
it "returns an approximate count of hits" do
|
@@ -50,14 +50,20 @@ shared_examples_for "GoogleAjax" do
|
|
50
50
|
|
51
51
|
describe ".detect" do
|
52
52
|
it "returns the right language" do
|
53
|
-
GoogleAjax::Language.detect("What's up folks")[
|
54
|
-
GoogleAjax::Language.detect("Montréal est une ville incroyable")[
|
53
|
+
GoogleAjax::Language.detect("What's up folks")[:language].should == "en"
|
54
|
+
GoogleAjax::Language.detect("Montréal est une ville incroyable")[:language].should == "fr"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "converts nicely the return types" do
|
58
|
+
result = GoogleAjax::Language.detect("Sandwich")
|
59
|
+
result[:is_reliable].should == false
|
60
|
+
result[:confidence].should be_a(Numeric)
|
55
61
|
end
|
56
62
|
end
|
57
63
|
|
58
64
|
describe ".translate" do
|
59
65
|
it "does an approximate translation" do
|
60
|
-
GoogleAjax::Language.translate("Ruby rocks", "en", "fr")[
|
66
|
+
GoogleAjax::Language.translate("Ruby rocks", "en", "fr")[:translated_text].should == "Ruby roches"
|
61
67
|
end
|
62
68
|
end
|
63
69
|
end
|
@@ -71,22 +77,22 @@ shared_examples_for "GoogleAjax" do
|
|
71
77
|
it "returns the right feeds" do
|
72
78
|
feeds = GoogleAjax::Feed.find("Ruby")
|
73
79
|
feeds.size.should == 10
|
74
|
-
feeds.any?{|result| result[
|
80
|
+
feeds.any?{|result| result[:url] == "http://ruby-lang.org/en/feeds/news.rss"}.should be_true
|
75
81
|
end
|
76
82
|
end
|
77
83
|
|
78
84
|
describe ".load" do
|
79
85
|
it "loads entries of a feed" do
|
80
86
|
feed = GoogleAjax::Feed.load('http://digg.com/rss/index.xml')
|
81
|
-
feed[
|
82
|
-
feed[
|
87
|
+
feed[:title].should == "digg.com: Stories / Popular"
|
88
|
+
feed[:entries].size.should == 4
|
83
89
|
end
|
84
90
|
end
|
85
91
|
|
86
92
|
describe ".lookup" do
|
87
93
|
it "returns the feed associated with a URL" do
|
88
94
|
feed = GoogleAjax::Feed.lookup("http://digg.com/")
|
89
|
-
feed[
|
95
|
+
feed[:url].should == "http://feeds.digg.com/digg/popular.rss"
|
90
96
|
end
|
91
97
|
end
|
92
98
|
end
|
data/spec/googleajax_spec.rb
CHANGED
@@ -6,10 +6,10 @@ require 'googleajax'
|
|
6
6
|
describe "GoogleAjax (standard)" do
|
7
7
|
it_should_behave_like "GoogleAjax"
|
8
8
|
|
9
|
-
it "returns results as
|
9
|
+
it "returns results as a hash" do
|
10
10
|
GoogleAjax.referer = "http://example.com"
|
11
11
|
response = GoogleAjax::Search.web("apple", :rsz => :large)
|
12
|
-
response.is_a?
|
13
|
-
response
|
12
|
+
response.is_a? Hash
|
13
|
+
response[:cursor].is_a? Hash
|
14
14
|
end
|
15
15
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: googleajax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- geemus(Wesley Beary)
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-
|
13
|
+
date: 2009-12-24 00:00:00 -08:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -47,13 +47,23 @@ files:
|
|
47
47
|
- Rakefile
|
48
48
|
- VERSION
|
49
49
|
- lib/googleajax.rb
|
50
|
+
- lib/googleajax/api.rb
|
50
51
|
- lib/googleajax/as_hash.rb
|
52
|
+
- lib/googleajax/as_open_struct.rb
|
51
53
|
- lib/googleajax/base.rb
|
54
|
+
- lib/googleajax/basic.rb
|
55
|
+
- lib/googleajax/extensions/hash.rb
|
56
|
+
- lib/googleajax/extensions/kernel.rb
|
57
|
+
- lib/googleajax/extensions/string.rb
|
52
58
|
- lib/googleajax/feed.rb
|
59
|
+
- lib/googleajax/filters.rb
|
60
|
+
- lib/googleajax/hash.rb
|
53
61
|
- lib/googleajax/language.rb
|
54
|
-
- lib/googleajax/
|
62
|
+
- lib/googleajax/request.rb
|
63
|
+
- lib/googleajax/results.rb
|
55
64
|
- lib/googleajax/search.rb
|
56
|
-
- spec/
|
65
|
+
- spec/googleajax_as_open_struct_spec.rb
|
66
|
+
- spec/googleajax_basic_spec.rb
|
57
67
|
- spec/googleajax_common.rb
|
58
68
|
- spec/googleajax_spec.rb
|
59
69
|
- spec/spec.opts
|
@@ -87,7 +97,8 @@ signing_key:
|
|
87
97
|
specification_version: 3
|
88
98
|
summary: Ruby wrapper to the Google AJAX API REST interfaces(Feeds, Language and Search).
|
89
99
|
test_files:
|
90
|
-
- spec/
|
100
|
+
- spec/googleajax_as_open_struct_spec.rb
|
101
|
+
- spec/googleajax_basic_spec.rb
|
91
102
|
- spec/googleajax_common.rb
|
92
103
|
- spec/googleajax_spec.rb
|
93
104
|
- spec/spec_helper.rb
|
data/lib/googleajax/parser.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
module GoogleAjax
|
2
|
-
module Parser
|
3
|
-
def self.parse(api, method, data)
|
4
|
-
data = if defined? Rails
|
5
|
-
ActiveSupport::JSON::decode(data)
|
6
|
-
else
|
7
|
-
JSON.parse(data)
|
8
|
-
end
|
9
|
-
process_errors(data)
|
10
|
-
parser = PARSERS[api][method]
|
11
|
-
response = data['responseData']
|
12
|
-
parser.is_a?(Symbol) ? send(parser, response) : parser.new(response) if response
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.process_errors(data)
|
16
|
-
status = data['responseStatus']
|
17
|
-
unless (200..206).include? status
|
18
|
-
raise StandardError, data['responseDetails']
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.parse_feed_list(data)
|
23
|
-
data['entries'].map(&Feed::Feed.method(:new))
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.parse_one_feed(data)
|
27
|
-
Feed::Feed.new(data['feed'])
|
28
|
-
end
|
29
|
-
|
30
|
-
PARSERS = {
|
31
|
-
:feed => { :find => :parse_feed_list, :load => :parse_one_feed, :lookup => Feed::Feed },
|
32
|
-
:language => { :detect => Language::Language, :translate => Language::Translation },
|
33
|
-
:search => { :blogs => Search::Results, :books => Search::Results, :images => Search::Results, :local => Search::Results,
|
34
|
-
:news => Search::Results, :video => Search::Results, :web => Search::Results }
|
35
|
-
}
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|