googleajax 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +19 -3
- data/README.txt +47 -20
- data/Rakefile +42 -13
- data/VERSION +1 -0
- data/lib/googleajax.rb +31 -0
- data/lib/googleajax/as_hash.rb +15 -0
- data/lib/googleajax/base.rb +25 -0
- data/lib/googleajax/feed.rb +35 -0
- data/lib/{google_ajax → googleajax}/language.rb +10 -17
- data/lib/googleajax/parser.rb +38 -0
- data/lib/googleajax/search.rb +66 -0
- data/spec/googleajax_as_hash_spec.rb +15 -0
- data/spec/googleajax_common.rb +93 -0
- data/spec/googleajax_spec.rb +15 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +8 -0
- metadata +36 -27
- data/Manifest.txt +0 -11
- data/lib/google_ajax.rb +0 -41
- data/lib/google_ajax/feed.rb +0 -38
- data/lib/google_ajax/parser.rb +0 -90
- data/lib/google_ajax/search.rb +0 -69
- data/lib/google_ajax/version.rb +0 -8
- data/test/test_google_ajax.rb +0 -0
data/History.txt
CHANGED
@@ -1,6 +1,22 @@
|
|
1
|
-
===
|
1
|
+
=== 0.2.0 / 2009-11-17
|
2
2
|
|
3
|
-
*
|
3
|
+
* New features:
|
4
|
+
* results can use [] and []= for lookup and seting
|
5
|
+
* allows results to be open structs (default) or hash (by requiring 'googleajax/as_hash' instead)
|
4
6
|
|
5
|
-
|
7
|
+
* bug fixes:
|
8
|
+
* Search.web(...).count now returns an int, not a string
|
9
|
+
* many calls were not passing the args argument to #get
|
10
|
+
* Feed.load used to return an open struct with only one method called 'feed' that was a hash. It now returns the feed correctly.
|
6
11
|
|
12
|
+
* Behind the scene changes:
|
13
|
+
* specs
|
14
|
+
* shorter, cleaner code
|
15
|
+
* links to google api doc in rdoc
|
16
|
+
* most classes are now modules
|
17
|
+
* small optimizations
|
18
|
+
* All #get now requires arg (see bug fix)
|
19
|
+
|
20
|
+
=== 0.1.0 / 2008-05-19
|
21
|
+
|
22
|
+
* Initial Release
|
data/README.txt
CHANGED
@@ -5,40 +5,67 @@
|
|
5
5
|
|
6
6
|
== DESCRIPTION:
|
7
7
|
|
8
|
-
Ruby wrapper
|
8
|
+
Ruby wrapper for Google AJAX API REST interfaces(Feeds, Language and Search).
|
9
9
|
|
10
10
|
== SYNOPSIS:
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
12
|
+
# First, setup referer:
|
13
|
+
GoogleAjax.referer = [your domain name here]
|
14
|
+
|
15
|
+
# Optionally, you can set an api_key:
|
16
|
+
GoogleAjax.api_key = [your api key here]
|
17
|
+
|
18
|
+
=== Now you are set to go, so here are a few examples:
|
19
|
+
|
20
|
+
# Find top 10 feeds for 'ruby'
|
21
|
+
GoogleAjax::Feed.find('ruby')
|
22
|
+
|
23
|
+
# Load 4 most recent entries from 'http://monki.geemus.com/feed/atom.xml'
|
24
|
+
GoogleAjax::Feed.load('http://monki.geemus.com/feed/atom.xml')
|
25
|
+
|
26
|
+
# Find feed for 'http://monki.geemus.com'
|
27
|
+
GoogleAjax::Feed.lookup('http://monki.geemus.com')
|
28
|
+
|
29
|
+
# Find the language of the string 'Ciao mondo'
|
30
|
+
GoogleAjax::Language.detect('Ciao mondo')
|
31
|
+
|
32
|
+
# Translate 'Hello world' to italian
|
33
|
+
GoogleAjax::Language.translate('Hello world', 'en', 'it')
|
34
|
+
|
35
|
+
# Find top 4 blogs for 'ruby'
|
36
|
+
GoogleAjax::Search.blogs('ruby')
|
37
|
+
|
38
|
+
# Find top 4 books for 'ruby'
|
39
|
+
GoogleAjax::Search.books('ruby')
|
40
|
+
|
41
|
+
# Find top 4 images for 'ruby'
|
42
|
+
GoogleAjax::Search.images('ruby')
|
43
|
+
|
44
|
+
# Find top 4 local results for 'ruby' at latitude 48.8565, longitude 2.3509
|
45
|
+
GoogleAjax::Search.local('ruby', 48.8565, 2.3509)
|
46
|
+
|
47
|
+
# Find top 4 news results for 'ruby'
|
48
|
+
GoogleAjax::Search.news('ruby')
|
49
|
+
|
50
|
+
# Find top 4 video results for 'ruby'
|
51
|
+
GoogleAjax::Search.video('ruby')
|
52
|
+
|
53
|
+
# Find top 4 web page results for 'Hello world'
|
54
|
+
GoogleAjax::Search.web('Hello world')
|
28
55
|
|
29
56
|
== REQUIREMENTS:
|
30
57
|
|
31
|
-
* JSON gem to parse
|
58
|
+
* JSON gem to parse responses, or rails
|
32
59
|
|
33
60
|
== INSTALL:
|
34
61
|
|
35
|
-
|
62
|
+
sudo gem install googleajax
|
36
63
|
|
37
64
|
== LICENSE:
|
38
65
|
|
39
66
|
(The MIT License)
|
40
67
|
|
41
|
-
Copyright (c)
|
68
|
+
Copyright (c) 2009 {geemus (Wesley Beary)}[http://github.com/geemus]
|
42
69
|
|
43
70
|
Permission is hereby granted, free of charge, to any person obtaining
|
44
71
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -1,17 +1,46 @@
|
|
1
|
-
# -*- ruby -*-
|
2
|
-
|
3
1
|
require 'rubygems'
|
4
|
-
require '
|
5
|
-
|
6
|
-
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "googleajax"
|
8
|
+
gem.summary = %Q{Ruby wrapper to the Google AJAX API REST interfaces(Feeds, Language and Search).}
|
9
|
+
#gem.description = %Q{TODO: longer description of your gem}
|
10
|
+
gem.email = "me@geemus.com"
|
11
|
+
gem.homepage = "http://github.com/geemus/googleajax"
|
12
|
+
gem.authors = ["geemus(Wesley Beary)", "Marc-Andre Lafortune"]
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
gem.add_dependency 'json', '>= 1.0.0'
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
+
end
|
7
27
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
p.url = 'http://googleajax.rubyforge.com'
|
13
|
-
p.remote_rdoc_dir = ''
|
14
|
-
p.extra_deps << ['json', '>= 1.0.0']
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
+
spec.rcov = true
|
15
32
|
end
|
16
33
|
|
17
|
-
|
34
|
+
task :spec => :check_dependencies
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "googleajax #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.0
|
data/lib/googleajax.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'json' unless defined?(Rails)
|
6
|
+
|
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'
|
13
|
+
|
14
|
+
API_BASE = 'http://ajax.googleapis.com/ajax/services/'
|
15
|
+
class << self
|
16
|
+
attr_accessor :api_key
|
17
|
+
attr_accessor :referer
|
18
|
+
|
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
|
@@ -0,0 +1,25 @@
|
|
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
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
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
|
+
|
10
|
+
# will return a list of feeds that match the given query
|
11
|
+
# 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
|
15
|
+
|
16
|
+
# downloads this feed from Google's servers
|
17
|
+
# 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
|
21
|
+
|
22
|
+
# will return the associated feed if it exists for a given url
|
23
|
+
# 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
|
34
|
+
end
|
35
|
+
end
|
@@ -1,36 +1,29 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module GoogleAjax
|
2
|
+
module Language
|
3
3
|
LANGUAGE_VERSION = 1.0
|
4
|
-
def self.get(method, query, args
|
5
|
-
args = { :v => LANGUAGE_VERSION }.merge
|
4
|
+
def self.get(method, query, args)
|
5
|
+
args = { :v => LANGUAGE_VERSION }.merge(args)
|
6
6
|
GoogleAjax::get(:language, method, query, args)
|
7
7
|
end
|
8
8
|
|
9
9
|
# will return the language code that describes the language of the given text
|
10
10
|
def self.detect(query, args = {})
|
11
|
-
self.get(:detect, query)
|
11
|
+
self.get(:detect, query, args)
|
12
12
|
end
|
13
13
|
|
14
14
|
# will return translated text for the given text supplied, matching the destination language.
|
15
15
|
def self.translate(query, source, destination, args = {})
|
16
|
-
args = { :langpair => "#{source}%7C#{destination}"}.merge
|
16
|
+
args = { :langpair => "#{source}%7C#{destination}"}.merge(args)
|
17
17
|
self.get(:translate, query, args)
|
18
18
|
end
|
19
19
|
|
20
|
-
class Language <
|
21
|
-
def initialize(data)
|
22
|
-
super(data)
|
23
|
-
end
|
24
|
-
|
20
|
+
class Language < Base
|
25
21
|
def name
|
26
|
-
LANGUAGES.invert[self.language]
|
22
|
+
(@@lang_cache ||= LANGUAGES.invert)[self.language]
|
27
23
|
end
|
28
24
|
end
|
29
25
|
|
30
|
-
class Translation <
|
31
|
-
def initialize(data)
|
32
|
-
super(data)
|
33
|
-
end
|
26
|
+
class Translation < Base
|
34
27
|
end
|
35
28
|
|
36
29
|
LANGUAGES =
|
@@ -77,6 +70,6 @@ class GoogleAjax
|
|
77
70
|
'UKRAINIAN' => 'uk',
|
78
71
|
'VIETNAMESE' => 'vi',
|
79
72
|
'UNKNOWN' => ''
|
80
|
-
}
|
73
|
+
}
|
81
74
|
end
|
82
75
|
end
|
@@ -0,0 +1,38 @@
|
|
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
|
@@ -0,0 +1,66 @@
|
|
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)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Arguments: http://code.google.com/apis/ajaxsearch/documentation/reference.html#_fonje_local
|
26
|
+
def self.local(query, latitude, longitude, args = {})
|
27
|
+
args = { :sll => "#{latitude},#{longitude}" }.merge(args)
|
28
|
+
self.get(:local, query, args)
|
29
|
+
end
|
30
|
+
|
31
|
+
# 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
|
+
|
36
|
+
# 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
|
+
|
41
|
+
# 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
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/googleajax_common')
|
3
|
+
|
4
|
+
require 'googleajax/as_hash'
|
5
|
+
|
6
|
+
describe "GoogleAjax/as_hash" do
|
7
|
+
it_should_behave_like "GoogleAjax"
|
8
|
+
|
9
|
+
it "returns results as a hash" do
|
10
|
+
GoogleAjax.referer = "http://example.com"
|
11
|
+
response = GoogleAjax::Search.web("apple", :rsz => :large)
|
12
|
+
response.is_a? Hash
|
13
|
+
response['cursor'].is_a? Hash
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# encoding:utf-8
|
2
|
+
shared_examples_for "GoogleAjax" do
|
3
|
+
it "requires a referer" do
|
4
|
+
GoogleAjax.referer = nil
|
5
|
+
lambda{GoogleAjax::Search.web("testing")}.should raise_error
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "::Search" do
|
9
|
+
describe ".web" do
|
10
|
+
before :each do
|
11
|
+
GoogleAjax.referer = "http://example.com"
|
12
|
+
@response = GoogleAjax::Search.web("apple", :rsz => :large)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns the expected results" do
|
16
|
+
@response['results'].select{|result| result['url'] =~ /http:(.*).apple.com/}.size.should >= 4
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
{
|
21
|
+
:blogs => 100_000,
|
22
|
+
:books => 10_000,
|
23
|
+
:images => 10_000,
|
24
|
+
:video => 10_000,
|
25
|
+
:web => 1_000_000,
|
26
|
+
:local => [100, 48.8565, 2.3509]
|
27
|
+
}.each do |method, (min, *args)|
|
28
|
+
describe ".#{method}" do
|
29
|
+
before :each do
|
30
|
+
GoogleAjax.referer = "http://example.com"
|
31
|
+
@response_small = GoogleAjax::Search.send(method, "ruby", *args)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "takes options into account" do
|
35
|
+
@response_large = GoogleAjax::Search.send(method, "ruby", *(args+[{:rsz => :large}]))
|
36
|
+
@response_large['results'].size.should > @response_small['results'].size
|
37
|
+
end unless method == :blogs # Google doesn't seem to support this option for blogs???
|
38
|
+
|
39
|
+
it "returns an approximate count of hits" do
|
40
|
+
@response_small.count.should > min
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "::Language" do
|
47
|
+
before :each do
|
48
|
+
GoogleAjax.referer = "http://example.com"
|
49
|
+
end
|
50
|
+
|
51
|
+
describe ".detect" do
|
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"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe ".translate" do
|
59
|
+
it "does an approximate translation" do
|
60
|
+
GoogleAjax::Language.translate("Ruby rocks", "en", "fr")['translatedText'].should == "Ruby roches"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "::Feed" do
|
66
|
+
before :each do
|
67
|
+
GoogleAjax.referer = "http://example.com"
|
68
|
+
end
|
69
|
+
|
70
|
+
describe ".find" do
|
71
|
+
it "returns the right feeds" do
|
72
|
+
feeds = GoogleAjax::Feed.find("Ruby")
|
73
|
+
feeds.size.should == 10
|
74
|
+
feeds.any?{|result| result['url'] == "http://www.ruby-lang.org/en/feeds/news.rss"}.should be_true
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe ".load" do
|
79
|
+
it "loads entries of a feed" do
|
80
|
+
feed = GoogleAjax::Feed.load('http://digg.com/rss/index.xml')
|
81
|
+
feed['title'].should == "digg.com: Stories / Popular"
|
82
|
+
feed['entries'].size.should == 4
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe ".lookup" do
|
87
|
+
it "returns the feed associated with a URL" do
|
88
|
+
feed = GoogleAjax::Feed.lookup("http://digg.com/")
|
89
|
+
feed['url'].should == "http://feeds.digg.com/digg/popular.rss"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/googleajax_common')
|
3
|
+
|
4
|
+
require 'googleajax'
|
5
|
+
|
6
|
+
describe "GoogleAjax (standard)" do
|
7
|
+
it_should_behave_like "GoogleAjax"
|
8
|
+
|
9
|
+
it "returns results as an OpenStuct" do
|
10
|
+
GoogleAjax.referer = "http://example.com"
|
11
|
+
response = GoogleAjax::Search.web("apple", :rsz => :large)
|
12
|
+
response.is_a? OpenStruct
|
13
|
+
response.cursor.is_a? OpenStruct
|
14
|
+
end
|
15
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,64 +1,70 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: googleajax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- geemus(Wesley Beary)
|
8
|
+
- Marc-Andre Lafortune
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
12
|
|
12
|
-
date:
|
13
|
+
date: 2009-11-17 00:00:00 -08:00
|
13
14
|
default_executable:
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
17
|
+
name: rspec
|
18
|
+
type: :development
|
17
19
|
version_requirement:
|
18
20
|
version_requirements: !ruby/object:Gem::Requirement
|
19
21
|
requirements:
|
20
22
|
- - ">="
|
21
23
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.
|
24
|
+
version: 1.2.9
|
23
25
|
version:
|
24
26
|
- !ruby/object:Gem::Dependency
|
25
|
-
name:
|
27
|
+
name: json
|
28
|
+
type: :runtime
|
26
29
|
version_requirement:
|
27
30
|
version_requirements: !ruby/object:Gem::Requirement
|
28
31
|
requirements:
|
29
32
|
- - ">="
|
30
33
|
- !ruby/object:Gem::Version
|
31
|
-
version: 1.
|
34
|
+
version: 1.0.0
|
32
35
|
version:
|
33
|
-
description:
|
34
|
-
email:
|
35
|
-
- monki@geemus.com
|
36
|
+
description:
|
37
|
+
email: me@geemus.com
|
36
38
|
executables: []
|
37
39
|
|
38
40
|
extensions: []
|
39
41
|
|
40
42
|
extra_rdoc_files:
|
41
|
-
- History.txt
|
42
|
-
- Manifest.txt
|
43
43
|
- README.txt
|
44
44
|
files:
|
45
45
|
- History.txt
|
46
|
-
- Manifest.txt
|
47
46
|
- README.txt
|
48
47
|
- Rakefile
|
49
|
-
-
|
50
|
-
- lib/
|
51
|
-
- lib/
|
52
|
-
- lib/
|
53
|
-
- lib/
|
54
|
-
- lib/
|
55
|
-
-
|
48
|
+
- VERSION
|
49
|
+
- lib/googleajax.rb
|
50
|
+
- lib/googleajax/as_hash.rb
|
51
|
+
- lib/googleajax/base.rb
|
52
|
+
- lib/googleajax/feed.rb
|
53
|
+
- lib/googleajax/language.rb
|
54
|
+
- lib/googleajax/parser.rb
|
55
|
+
- lib/googleajax/search.rb
|
56
|
+
- spec/googleajax_as_hash_spec.rb
|
57
|
+
- spec/googleajax_common.rb
|
58
|
+
- spec/googleajax_spec.rb
|
59
|
+
- spec/spec.opts
|
60
|
+
- spec/spec_helper.rb
|
56
61
|
has_rdoc: true
|
57
|
-
homepage: http://
|
62
|
+
homepage: http://github.com/geemus/googleajax
|
63
|
+
licenses: []
|
64
|
+
|
58
65
|
post_install_message:
|
59
66
|
rdoc_options:
|
60
|
-
- --
|
61
|
-
- README.txt
|
67
|
+
- --charset=UTF-8
|
62
68
|
require_paths:
|
63
69
|
- lib
|
64
70
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -75,10 +81,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
81
|
version:
|
76
82
|
requirements: []
|
77
83
|
|
78
|
-
rubyforge_project:
|
79
|
-
rubygems_version: 1.
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.3.5
|
80
86
|
signing_key:
|
81
|
-
specification_version:
|
87
|
+
specification_version: 3
|
82
88
|
summary: Ruby wrapper to the Google AJAX API REST interfaces(Feeds, Language and Search).
|
83
89
|
test_files:
|
84
|
-
-
|
90
|
+
- spec/googleajax_as_hash_spec.rb
|
91
|
+
- spec/googleajax_common.rb
|
92
|
+
- spec/googleajax_spec.rb
|
93
|
+
- spec/spec_helper.rb
|
data/Manifest.txt
DELETED
data/lib/google_ajax.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'cgi'
|
2
|
-
require 'open-uri'
|
3
|
-
require 'ostruct'
|
4
|
-
require 'rubygems'
|
5
|
-
require 'json'
|
6
|
-
|
7
|
-
require 'google_ajax/feed'
|
8
|
-
require 'google_ajax/language'
|
9
|
-
require 'google_ajax/parser'
|
10
|
-
require 'google_ajax/search'
|
11
|
-
require 'google_ajax/version'
|
12
|
-
|
13
|
-
class GoogleAjax
|
14
|
-
API_BASE = 'http://ajax.googleapis.com/ajax/services/'
|
15
|
-
@@api_key = @@referer = nil
|
16
|
-
|
17
|
-
def self.api_key
|
18
|
-
@@api_key
|
19
|
-
end
|
20
|
-
def self.api_key=(key)
|
21
|
-
@@api_key = key
|
22
|
-
end
|
23
|
-
def self.referer
|
24
|
-
@@referer
|
25
|
-
end
|
26
|
-
def self.referer=(referer)
|
27
|
-
@@referer = referer
|
28
|
-
end
|
29
|
-
|
30
|
-
# TODO: Pass query to parser, so it knows where it came from. Needed for search paging and useful in general.
|
31
|
-
def self.get(api, method, query, args = nil)
|
32
|
-
raise "You must assign a value to GoogleAjax.referer" unless @@referer
|
33
|
-
url = "#{API_BASE}#{api}/"
|
34
|
-
url += "#{method}?"
|
35
|
-
url += "&q=#{CGI::escape(query)}"
|
36
|
-
url += "&key=" if @@api_key
|
37
|
-
url += "&" + args.collect {|key, value| "#{key}=#{value}"}.join('&') if args && !args.empty?
|
38
|
-
data = open(url, "Referer" => @@referer).read
|
39
|
-
Parser.parse(api, method, data)
|
40
|
-
end
|
41
|
-
end
|
data/lib/google_ajax/feed.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
class GoogleAjax
|
2
|
-
class Feed
|
3
|
-
FEED_VERSION = 1.0
|
4
|
-
def self.get(method, query, args = {})
|
5
|
-
args = { :v => FEED_VERSION }.merge!(args)
|
6
|
-
GoogleAjax::get(:feed, method, query, args)
|
7
|
-
end
|
8
|
-
|
9
|
-
# will return a list of feeds that match the given query
|
10
|
-
def self.find(query, args = {})
|
11
|
-
self.get(:find, query)
|
12
|
-
end
|
13
|
-
|
14
|
-
# downloads this feed from Google's servers
|
15
|
-
# Optional: args { :num => number of entries to download(default is 4, maximum is 100) }
|
16
|
-
def self.load(query, args = {})
|
17
|
-
self.get(:load, query, args)
|
18
|
-
end
|
19
|
-
|
20
|
-
# will return the associated feed if it exists for a given url
|
21
|
-
def self.lookup(query, args = {})
|
22
|
-
self.get(:lookup, query)
|
23
|
-
end
|
24
|
-
|
25
|
-
class Entry < OpenStruct
|
26
|
-
def initialize(data)
|
27
|
-
super(data)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class Feed < OpenStruct
|
32
|
-
def initialize(data)
|
33
|
-
super(data)
|
34
|
-
self.entries = entries.collect {|data| Entry.new(data)} if entries
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
data/lib/google_ajax/parser.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
class GoogleAjax
|
2
|
-
class Parser
|
3
|
-
def self.parse(api, method, data)
|
4
|
-
data = JSON.parse(data)
|
5
|
-
Errors.process(data)
|
6
|
-
parser = Parser::PARSERS[api][method]
|
7
|
-
parser.process(data['responseData'])
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
class FeedFind < Parser#:nodoc:
|
12
|
-
def self.process(data)
|
13
|
-
data['entries'].collect {|data| GoogleAjax::Feed::Feed.new(data)} if data
|
14
|
-
end
|
15
|
-
end
|
16
|
-
class FeedLoad < Parser#:nodoc:
|
17
|
-
def self.process(data)
|
18
|
-
GoogleAjax::Feed::Feed.new(data['feed']) if data
|
19
|
-
end
|
20
|
-
end
|
21
|
-
class FeedLookup < Parser#:nodoc:
|
22
|
-
def self.process(data)
|
23
|
-
GoogleAjax::Feed::Feed.new(data) if data
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class LanguageDetect < Parser#:nodoc
|
28
|
-
def self.process(data)
|
29
|
-
GoogleAjax::Language::Language.new(data) if data
|
30
|
-
end
|
31
|
-
end
|
32
|
-
class LanguageTranslate < Parser#:nodoc
|
33
|
-
def self.process(data)
|
34
|
-
GoogleAjax::Language::Translation.new(data) if data
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class SearchBlogs < Parser#:nodoc
|
39
|
-
def self.process(data)
|
40
|
-
GoogleAjax::Search::Results.new(data) if data
|
41
|
-
end
|
42
|
-
end
|
43
|
-
class SearchBooks < Parser#:nodoc
|
44
|
-
def self.process(data)
|
45
|
-
GoogleAjax::Search::Results.new(data) if data
|
46
|
-
end
|
47
|
-
end
|
48
|
-
class SearchImages < Parser#:nodoc
|
49
|
-
def self.process(data)
|
50
|
-
GoogleAjax::Search::Results.new(data) if data
|
51
|
-
end
|
52
|
-
end
|
53
|
-
class SearchLocal < Parser#:nodoc
|
54
|
-
def self.process(data)
|
55
|
-
GoogleAjax::Search::Results.new(data) if data
|
56
|
-
end
|
57
|
-
end
|
58
|
-
class SearchNews < Parser#:nodoc
|
59
|
-
def self.process(data)
|
60
|
-
GoogleAjax::Search::Results.new(data) if data
|
61
|
-
end
|
62
|
-
end
|
63
|
-
class SearchVideo < Parser#:nodoc
|
64
|
-
def self.process(data)
|
65
|
-
GoogleAjax::Search::Results.new(data) if data
|
66
|
-
end
|
67
|
-
end
|
68
|
-
class SearchWeb < Parser#:nodoc
|
69
|
-
def self.process(data)
|
70
|
-
GoogleAjax::Search::Results.new(data) if data
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
class Parser
|
75
|
-
PARSERS = {
|
76
|
-
:feed => { :find => FeedFind, :load => FeedLoad, :lookup => FeedLookup },
|
77
|
-
:language => { :detect => LanguageDetect, :translate => LanguageTranslate, },
|
78
|
-
:search => { :blogs => SearchBlogs, :books => SearchBooks, :images => SearchImages, :local => SearchLocal, :news => SearchNews, :video => SearchVideo, :web => SearchWeb }
|
79
|
-
}
|
80
|
-
end
|
81
|
-
|
82
|
-
class Errors
|
83
|
-
def self.process(data)
|
84
|
-
status = data['responseStatus']
|
85
|
-
unless [200, 201, 202, 203, 204, 205, 206].include? status
|
86
|
-
raise StandardError.new(data['responseDetails'])
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
data/lib/google_ajax/search.rb
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
class GoogleAjax
|
2
|
-
class Search
|
3
|
-
SEARCH_VERSION = 1.0
|
4
|
-
def self.get(method, query, args = {})
|
5
|
-
args = { :v => SEARCH_VERSION }.merge!(args)
|
6
|
-
GoogleAjax::get(:search, method, query, args)
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.blogs(query, args = {})
|
10
|
-
self.get(:blogs, query, args)
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.books(query, args = {})
|
14
|
-
self.get(:books, query, args)
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.images(query, args = {})
|
18
|
-
self.get(:images, query, args)
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.local(query, latitude, longitude, args = {})
|
22
|
-
args = { :sll => "#{latitude},#{longitude}" }.merge!(args)
|
23
|
-
self.get(:local, query, args)
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.news(query, args = {})
|
27
|
-
self.get(:news, query, args)
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.video(query, args = {})
|
31
|
-
self.get(:video, query, args)
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.web(query, args = {})
|
35
|
-
self.get(:web, query, args)
|
36
|
-
end
|
37
|
-
|
38
|
-
class Results < OpenStruct
|
39
|
-
def initialize(data)
|
40
|
-
super(data)
|
41
|
-
self.results = results.collect {|data| Result.new(data)}
|
42
|
-
self.cursor = Cursor.new(cursor) if self.cursor
|
43
|
-
end
|
44
|
-
|
45
|
-
def count
|
46
|
-
self.cursor.estimatedResultCount
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
class Result < OpenStruct
|
51
|
-
def initialize(data)
|
52
|
-
super(data)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
class Cursor < OpenStruct
|
57
|
-
def initialize(data)
|
58
|
-
super(data)
|
59
|
-
self.pages = pages.collect {|data| Page.new(data)}
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
class Page < OpenStruct
|
64
|
-
def initialize(data)
|
65
|
-
super(data)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
data/lib/google_ajax/version.rb
DELETED
data/test/test_google_ajax.rb
DELETED
File without changes
|