googleajax 0.2.0 → 1.0.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/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
|