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 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/monki/google_ajax/tree/master
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.2.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
@@ -1,15 +1,2 @@
1
- # Include this file instead of googleajax so that results are simply hashes
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'
@@ -1,25 +1,6 @@
1
1
  module GoogleAjax
2
- class Base < OpenStruct
3
- def [](key)
4
- send(key)
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,9 @@
1
+ # If you prefer getting unfiltered Hashes,
2
+ # then require 'googleajax/basic' *instead* of 'googleajax'
3
+ # (not recommended)
4
+ require 'googleajax/hash'
5
+ module GoogleAjax
6
+ class Base < Hash
7
+ end
8
+ end
9
+ require 'googleajax'
@@ -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
@@ -1,35 +1,24 @@
1
1
  module GoogleAjax
2
- module Feed
3
- FEED_VERSION = 1.0
4
- # Arguments: http://code.google.com/apis/ajaxfeeds/documentation/reference.html#_intro_fonje
5
- def self.get(method, query, args)
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
- def self.find(query, args = {})
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
- def self.load(url, args = {})
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
- def self.lookup(url, args = {})
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
@@ -0,0 +1,10 @@
1
+ module GoogleAjax
2
+ # Out very own Hash class, with the only difference being the constructor
3
+ # which takes a hash for its initial values
4
+ class Hash < ::Hash
5
+ def initialize(h)
6
+ replace(h)
7
+ super()
8
+ end
9
+ end
10
+ end
@@ -1,75 +1,79 @@
1
1
  module GoogleAjax
2
- module Language
3
- LANGUAGE_VERSION = 1.0
4
- def self.get(method, query, args)
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
- def self.detect(query, args = {})
11
- self.get(:detect, query, args)
12
- end
11
+ standard_api :detect
13
12
 
14
- # will return translated text for the given text supplied, matching the destination language.
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
- args = { :langpair => "#{source}%7C#{destination}"}.merge(args)
17
- self.get(:translate, query, args)
18
- end
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
- LANGUAGES =
23
+ LANGUAGE_CODE =
30
24
  {
31
- 'ARABIC' => 'ar',
32
- 'BULGARIAN' => 'bg',
33
- 'CATALAN' => 'ca',
34
- 'CHINESE' => 'zh',
35
- 'CHINESE_SIMPLIFIED' => 'zh-CN',
36
- 'CHINESE_TRADITIONAL' => 'zh-TW',
37
- 'CROATIAN' => 'hr',
38
- 'CZECH' => 'cs',
39
- 'DANISH' => 'da',
40
- 'DUTCH'=> 'nl',
41
- 'ENGLISH' => 'en',
42
- 'ESTONIAN' => 'et',
43
- 'FILIPINO' => 'tl',
44
- 'FINISH' => 'fi',
45
- 'FRENCH' => 'fr',
46
- 'GERMAN' => 'de',
47
- 'GREK' => 'el',
48
- 'HEBREW' => 'iw',
49
- 'HINDI' => 'hi',
50
- 'HUNGARIAN' => 'hu',
51
- 'INDONESIAN' => 'id',
52
- 'ITALIAN' => 'it',
53
- 'JAPANESE' => 'ja',
54
- 'KOREAN' => 'ko',
55
- 'LATVIAN' => 'lv',
56
- 'LITHUANIAN' => 'lt',
57
- 'NORWEGIAN' => 'no',
58
- 'PERSIAN' => 'fa',
59
- 'POLISH' => 'pl',
60
- 'PORTUGUESE' => 'pt-PT',
61
- 'ROMANIAN' => 'ro',
62
- 'RUSIAN' => 'ru',
63
- 'SERBIAN' => 'sr',
64
- 'SLOVAK' => 'sk',
65
- 'SLOVENIAN' => 'sl',
66
- 'SPANISH' => 'es',
67
- 'SWEDISH' => 'sv',
68
- 'THAI' => 'th',
69
- 'TURKISH' => 'tr',
70
- 'UKRAINIAN' => 'uk',
71
- 'VIETNAMESE' => 'vi',
72
- 'UNKNOWN' => ''
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
@@ -1,66 +1,50 @@
1
1
  module GoogleAjax
2
- module Search
3
- SEARCH_VERSION = 1.0
4
- # Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_web
5
- def self.get(method, query, args)
6
- args = { :v => SEARCH_VERSION }.merge(args)
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
- self.get(:local, query, args)
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
- module GoogleAjax
8
- require 'googleajax/base' unless const_defined?("Base")
9
- require 'googleajax/feed'
10
- require 'googleajax/language'
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
- API_BASE = 'http://ajax.googleapis.com/ajax/services/'
15
- class << self
16
- attr_accessor :api_key
17
- attr_accessor :referer
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
- # Api doc is at http://code.google.com/apis/ajaxsearch/documentation/reference.html#_intro_fonje
20
- def get(api, method, query, args = nil)
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/as_hash'
4
+ require 'googleajax/as_open_struct'
5
5
 
6
- describe "GoogleAjax/as_hash" do
6
+ describe "GoogleAjax/as_open_struct" do
7
7
  it_should_behave_like "GoogleAjax"
8
8
 
9
- it "returns results as a hash" do
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? Hash
13
- response['cursor'].is_a? Hash
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
@@ -13,7 +13,7 @@ shared_examples_for "GoogleAjax" do
13
13
  end
14
14
 
15
15
  it "returns the expected results" do
16
- @response['results'].select{|result| result['url'] =~ /http:(.*).apple.com/}.size.should >= 4
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['results'].size.should > @response_small['results'].size
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")['language'].should == "en"
54
- GoogleAjax::Language.detect("Montréal est une ville incroyable")['language'].should == "fr"
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")['translatedText'].should == "Ruby roches"
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['url'] == "http://www.ruby-lang.org/en/feeds/news.rss"}.should be_true
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['title'].should == "digg.com: Stories / Popular"
82
- feed['entries'].size.should == 4
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['url'].should == "http://feeds.digg.com/digg/popular.rss"
95
+ feed[:url].should == "http://feeds.digg.com/digg/popular.rss"
90
96
  end
91
97
  end
92
98
  end
@@ -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 an OpenStuct" do
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? OpenStruct
13
- response.cursor.is_a? OpenStruct
12
+ response.is_a? Hash
13
+ response[:cursor].is_a? Hash
14
14
  end
15
15
  end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
3
4
  require 'spec'
4
5
  require 'spec/autorun'
5
6
 
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.2.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-11-17 00:00:00 -08:00
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/parser.rb
62
+ - lib/googleajax/request.rb
63
+ - lib/googleajax/results.rb
55
64
  - lib/googleajax/search.rb
56
- - spec/googleajax_as_hash_spec.rb
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/googleajax_as_hash_spec.rb
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
@@ -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