gnib 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.rvmrc +71 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +28 -0
- data/README.md +63 -0
- data/Rakefile +20 -0
- data/gnib.gemspec +24 -0
- data/lib/gnib.rb +19 -0
- data/lib/gnib/configurations.rb +18 -0
- data/lib/gnib/response.rb +44 -0
- data/lib/gnib/search.rb +95 -0
- data/lib/gnib/search_helper.rb +8 -0
- data/lib/gnib/search_request.rb +22 -0
- data/lib/gnib/search_result.rb +21 -0
- data/lib/gnib/version.rb +3 -0
- data/spec/sample_image_response +1 -0
- data/spec/sample_web_response +1 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/unit/configurations_spec.rb +46 -0
- data/spec/unit/response_spec.rb +31 -0
- data/spec/unit/search_result_spec.rb +58 -0
- data/spec/unit/search_spec.rb +34 -0
- metadata +96 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
4
|
+
# development environment upon cd'ing into the directory
|
5
|
+
|
6
|
+
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
|
7
|
+
environment_id="ruby-1.9.3-p0@gnib"
|
8
|
+
|
9
|
+
#
|
10
|
+
# Uncomment following line if you want options to be set only for given project.
|
11
|
+
#
|
12
|
+
# PROJECT_JRUBY_OPTS=( --1.9 )
|
13
|
+
#
|
14
|
+
# The variable PROJECT_JRUBY_OPTS requires the following to be run in shell:
|
15
|
+
#
|
16
|
+
# chmod +x ${rvm_path}/hooks/after_use_jruby_opts
|
17
|
+
#
|
18
|
+
|
19
|
+
#
|
20
|
+
# First we attempt to load the desired environment directly from the environment
|
21
|
+
# file. This is very fast and efficient compared to running through the entire
|
22
|
+
# CLI and selector. If you want feedback on which environment was used then
|
23
|
+
# insert the word 'use' after --create as this triggers verbose mode.
|
24
|
+
#
|
25
|
+
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
|
26
|
+
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
27
|
+
then
|
28
|
+
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
29
|
+
|
30
|
+
if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
|
31
|
+
then
|
32
|
+
. "${rvm_path:-$HOME/.rvm}/hooks/after_use"
|
33
|
+
fi
|
34
|
+
else
|
35
|
+
# If the environment file has not yet been created, use the RVM CLI to select.
|
36
|
+
if ! rvm --create use "$environment_id"
|
37
|
+
then
|
38
|
+
echo "Failed to create RVM environment '${environment_id}'."
|
39
|
+
return 1
|
40
|
+
fi
|
41
|
+
fi
|
42
|
+
|
43
|
+
#
|
44
|
+
# If you use an RVM gemset file to install a list of gems (*.gems), you can have
|
45
|
+
# it be automatically loaded. Uncomment the following and adjust the filename if
|
46
|
+
# necessary.
|
47
|
+
#
|
48
|
+
# filename=".gems"
|
49
|
+
# if [[ -s "$filename" ]]
|
50
|
+
# then
|
51
|
+
# rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
|
52
|
+
# fi
|
53
|
+
|
54
|
+
# If you use bundler, this might be useful to you:
|
55
|
+
# if [[ -s Gemfile ]] && ! command -v bundle >/dev/null
|
56
|
+
# then
|
57
|
+
# printf "The rubygem 'bundler' is not installed. Installing it now.\n"
|
58
|
+
# gem install bundler
|
59
|
+
# fi
|
60
|
+
# if [[ -s Gemfile ]] && command -v bundle
|
61
|
+
# then
|
62
|
+
# bundle install
|
63
|
+
# fi
|
64
|
+
|
65
|
+
if [[ $- == *i* ]] # check for interactive shells
|
66
|
+
then
|
67
|
+
echo "Using: $(tput setaf 2)$GEM_HOME$(tput sgr0)" # show the user the ruby and gemset they are using in green
|
68
|
+
else
|
69
|
+
echo "Using: $GEM_HOME" # don't use colors in interactive shells
|
70
|
+
fi
|
71
|
+
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
gnib (0.1.0)
|
5
|
+
activesupport
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
activesupport (3.1.3)
|
11
|
+
multi_json (~> 1.0)
|
12
|
+
diff-lcs (1.1.3)
|
13
|
+
multi_json (1.0.4)
|
14
|
+
rspec (2.7.0)
|
15
|
+
rspec-core (~> 2.7.0)
|
16
|
+
rspec-expectations (~> 2.7.0)
|
17
|
+
rspec-mocks (~> 2.7.0)
|
18
|
+
rspec-core (2.7.1)
|
19
|
+
rspec-expectations (2.7.0)
|
20
|
+
diff-lcs (~> 1.1.2)
|
21
|
+
rspec-mocks (2.7.0)
|
22
|
+
|
23
|
+
PLATFORMS
|
24
|
+
ruby
|
25
|
+
|
26
|
+
DEPENDENCIES
|
27
|
+
gnib!
|
28
|
+
rspec
|
data/README.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
Gnib
|
2
|
+
====
|
3
|
+
|
4
|
+
Gnib is a Ruby interface for Microsoft Bing Search API.
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
|
9
|
+
### Rails 3.x users
|
10
|
+
|
11
|
+
For Rails 3.x projects, add the following line to your `Gemfile`.
|
12
|
+
|
13
|
+
gem 'gnib'
|
14
|
+
|
15
|
+
### All Others
|
16
|
+
|
17
|
+
Install `gnib` gem with Rubygems.
|
18
|
+
|
19
|
+
$ gem install gnib
|
20
|
+
|
21
|
+
Usage
|
22
|
+
-----
|
23
|
+
|
24
|
+
Obtain your Application key from [here] (https://ssl.bing.com/webmaster/developers/appids.aspx)
|
25
|
+
|
26
|
+
### Standalone
|
27
|
+
|
28
|
+
Gnib.config.application_id = 'YOUR_APP_ID'
|
29
|
+
results = Gnib::Search.get('Great', :sources => [:image])
|
30
|
+
|
31
|
+
### Rails 3.x
|
32
|
+
|
33
|
+
In initializers like `config/initializers/gnib.rb`, configure Gnib with
|
34
|
+
your Application key.
|
35
|
+
|
36
|
+
Gnib.config.application_id = 'YOUR_APP_ID'
|
37
|
+
|
38
|
+
You can search items in your actions.
|
39
|
+
|
40
|
+
@results = Gnib::Search.get('hello world', :sources => [:web, :image])
|
41
|
+
|
42
|
+
### (Not so much) More Complicated Usage Example
|
43
|
+
|
44
|
+
`Gnib::Search#get` is a helper function implemented to maximize
|
45
|
+
usability of the library. You can utilize `Gnib::Search`,
|
46
|
+
`Gnib::SearchRequest`, `Gnib::SearchResponse` instances which provide
|
47
|
+
more useful options than that of the helper function.
|
48
|
+
|
49
|
+
search = Gnib::Search.new 'query', :sources => [:web, :image] #
|
50
|
+
Other options include :market, :version, :adult, :latitude, :longitude,
|
51
|
+
...
|
52
|
+
request = search.request
|
53
|
+
response = request.response
|
54
|
+
|
55
|
+
image_results = response.images # Image search results
|
56
|
+
web_results = response.webs # Web search results
|
57
|
+
|
58
|
+
More descriptive documentations will be available soon. Stay tuned!
|
59
|
+
|
60
|
+
References
|
61
|
+
----------
|
62
|
+
|
63
|
+
- [Bing Developer](http://www.bing.com/toolbox/bingdeveloper/)
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
desc 'Default: run specs.'
|
5
|
+
task :default => :spec
|
6
|
+
|
7
|
+
desc "Run specs"
|
8
|
+
RSpec::Core::RakeTask.new do |t|
|
9
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
10
|
+
# Put spec opts in a file named .rspec in root
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Generate code coverage"
|
14
|
+
RSpec::Core::RakeTask.new(:coverage) do |t|
|
15
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
16
|
+
t.rcov = true
|
17
|
+
t.rcov_opts = ['--exclude', 'spec']
|
18
|
+
end
|
19
|
+
|
20
|
+
Bundler::GemHelper.install_tasks
|
data/gnib.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "gnib/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "gnib"
|
7
|
+
s.version = Gnib::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Inbeom Hwang"]
|
10
|
+
s.email = ["inbeom@wafflestudio.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Ruby library for Microsoft Bing Search API}
|
13
|
+
s.description = %q{Gnib provides interfaces for Bing Search API version 2.0}
|
14
|
+
|
15
|
+
s.add_dependency "activesupport"
|
16
|
+
s.add_development_dependency "rspec"
|
17
|
+
|
18
|
+
# s.rubyforge_project = "gnib"
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
end
|
data/lib/gnib.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/inflector'
|
3
|
+
require 'gnib/configurations'
|
4
|
+
require 'gnib/search_request'
|
5
|
+
require 'gnib/search'
|
6
|
+
require 'gnib/search_result'
|
7
|
+
require 'gnib/response'
|
8
|
+
|
9
|
+
module Gnib
|
10
|
+
class << self
|
11
|
+
def config
|
12
|
+
if block_given?
|
13
|
+
yield Configurations.singleton_object
|
14
|
+
else
|
15
|
+
Configurations.singleton_object
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Gnib
|
2
|
+
class Configurations
|
3
|
+
private_class_method :new
|
4
|
+
attr_accessor :application_id, :api_root
|
5
|
+
|
6
|
+
def self.singleton_object
|
7
|
+
@singleton ||= new
|
8
|
+
end
|
9
|
+
|
10
|
+
def api_root
|
11
|
+
@api_root ||= 'http://api.bing.net/json.aspx'
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
# Prevent external initialization
|
16
|
+
def initialize; super; end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Gnib
|
2
|
+
class Response
|
3
|
+
SOURCES = [:web, :image, :news, :spell, :phonebook, :related_search, :translation, :video]
|
4
|
+
def initialize(body)
|
5
|
+
@response_hash = ActiveSupport::JSON.decode(body)['SearchResponse']
|
6
|
+
end
|
7
|
+
|
8
|
+
def results_for(source)
|
9
|
+
results_container = @response_hash[source.to_s.camelize]
|
10
|
+
|
11
|
+
if results_container
|
12
|
+
@response_hash[source.to_s.camelize]['Results'].map do |result|
|
13
|
+
SearchResult.new result
|
14
|
+
end
|
15
|
+
else
|
16
|
+
[]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def result_count_of(source)
|
21
|
+
@response_hash[source.to_s.camelize]['Total'].to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def results
|
25
|
+
ret = []
|
26
|
+
|
27
|
+
SOURCES.each do |type, v|
|
28
|
+
ret |= results_for(type)
|
29
|
+
end
|
30
|
+
|
31
|
+
ret
|
32
|
+
end
|
33
|
+
|
34
|
+
def method_missing(method, *args, &block)
|
35
|
+
singluar_form = method.to_s.singularize.to_sym
|
36
|
+
|
37
|
+
if SOURCES.include? singluar_form
|
38
|
+
results_for(singluar_form)
|
39
|
+
else
|
40
|
+
super
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/gnib/search.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
require 'gnib/search_helper'
|
5
|
+
|
6
|
+
module Gnib
|
7
|
+
class Search
|
8
|
+
extend SearchHelper
|
9
|
+
|
10
|
+
PARAMS = [:query, :sources, :market, :version, :adult, :options, :latitude, :longitude]
|
11
|
+
|
12
|
+
SPECIFIC_PARAMS = {
|
13
|
+
:image => [:count, :offset, :filters],
|
14
|
+
:web => [:count, :offset, :file_type, :options],
|
15
|
+
:news => [:location_override, :category, :sort_by],
|
16
|
+
:phonebook => [:count, :offset, :file_type, :loc_id, :sort_by],
|
17
|
+
:related_search => [],
|
18
|
+
:spell => [],
|
19
|
+
:translation => [:source_language, :target_language],
|
20
|
+
:video => [:count, :offset, :filters, :sort_by]
|
21
|
+
}
|
22
|
+
|
23
|
+
def initialize(q, options = {})
|
24
|
+
@parameters = {}
|
25
|
+
|
26
|
+
# Set default values for required parameters
|
27
|
+
@parameters[:app_id] = Gnib.config.application_id
|
28
|
+
@parameters[:sources] = ['Web']
|
29
|
+
@parameters[:query] = q
|
30
|
+
|
31
|
+
# Iterate params array except query
|
32
|
+
(PARAMS - [:query]).each do |param|
|
33
|
+
@parameters[param] = options[param] if options[param]
|
34
|
+
end
|
35
|
+
|
36
|
+
SPECIFIC_PARAMS.each do |source, params|
|
37
|
+
if options[source]
|
38
|
+
@parameters[source] = {}
|
39
|
+
|
40
|
+
params.each do |param|
|
41
|
+
@parameters[source][param] = options[source][param] if options[source][param]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns a SearchRequest object initialized with URI of self
|
48
|
+
def request
|
49
|
+
SearchRequest.new self.request_uri
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
def request_uri
|
54
|
+
URI.parse("#{Gnib.config.api_root}?#{serialized_parameters}")
|
55
|
+
end
|
56
|
+
|
57
|
+
# Convert @parameters into HTTP GET parameters
|
58
|
+
def serialized_parameters
|
59
|
+
@parameters.map do |k,v|
|
60
|
+
if v.is_a? Hash
|
61
|
+
# Source-specific parameters
|
62
|
+
expanded_hash_parameters(k, v)
|
63
|
+
else
|
64
|
+
# General required and optional parameters
|
65
|
+
"#{k.to_s.camelize}=#{CGI::escape(serialized_parameter(v))}"
|
66
|
+
end
|
67
|
+
end.join('&')
|
68
|
+
end
|
69
|
+
|
70
|
+
# Expand parameters organized in hash form which is used for
|
71
|
+
# source-specific purpose to serialized GET parameter string.
|
72
|
+
def expanded_hash_parameters(source, params_hash, options = {})
|
73
|
+
base_str = "#{source.to_s.camelize}Request"
|
74
|
+
|
75
|
+
params_hash.map do |k, v|
|
76
|
+
"#{base_str}.#{k.to_s.camelize}=#{serialized_parameter(v)}"
|
77
|
+
end.join('&')
|
78
|
+
end
|
79
|
+
|
80
|
+
# Serialize parameter values into string form what Bing recommends them to
|
81
|
+
# be. Currently supports String and Array parameters.
|
82
|
+
#
|
83
|
+
# String parameters
|
84
|
+
def serialized_parameter(v)
|
85
|
+
case v
|
86
|
+
when String
|
87
|
+
v
|
88
|
+
when Array
|
89
|
+
v.map(&:to_s).join(' ')
|
90
|
+
else
|
91
|
+
v.to_s
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module Gnib
|
5
|
+
class SearchRequest
|
6
|
+
def initialize(uri)
|
7
|
+
@uri = uri
|
8
|
+
end
|
9
|
+
|
10
|
+
def response
|
11
|
+
@response_body ||= do_http_request.body
|
12
|
+
Response.new(@response_body)
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
def do_http_request
|
17
|
+
http = Net::HTTP.new(@uri.host, @uri.port)
|
18
|
+
http.request(Net::HTTP::Get.new(@uri.request_uri))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Gnib
|
2
|
+
class SearchResult
|
3
|
+
def initialize(rsp_body)
|
4
|
+
@rsp_body = rsp_body
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_hash
|
8
|
+
@rsp_body
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(sym, *args, &block)
|
12
|
+
val = @rsp_body[sym.to_s.camelize]
|
13
|
+
if val
|
14
|
+
return val unless val.is_a? Hash
|
15
|
+
return SearchResult.new val
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/gnib/version.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"SearchResponse":{"Version":"2.2","Query":{"SearchTerms":"google"},"Image":{"Total":146000000,"Offset":0,"Results":[{"Title":"Google Instant – Google setzt auf Schnelligkeit | Blog WebTec Braun","MediaUrl":"http:\/\/www.blog.webtec-braun.com\/wp-content\/uploads\/google.jpg","Url":"http:\/\/www.blog.webtec-braun.com\/google\/top-news-google-setzt-auf-schnelligkeit.html","DisplayUrl":"http:\/\/www.blog.webtec-braun.com\/google\/top-news-google-setzt-auf-schnelligkeit.html","Width":600,"Height":400,"FileSize":15719,"ContentType":"image\/jpeg","Thumbnail":{"Url":"http:\/\/ts4.mm.bing.net\/images\/thumbnail.aspx?q=1524014450527&id=421bf34508bee00c8f75b0af9529c1ab","ContentType":"image\/jpeg","Width":160,"Height":106,"FileSize":2611}},{"Title":"Google.com 1997-2011","MediaUrl":"http:\/\/blogoscoped.com\/files\/google-com-history\/1997.png","Url":"http:\/\/blogoscoped.com\/archive\/2006-04-21-n63.html","DisplayUrl":"http:\/\/blogoscoped.com\/archive\/2006-04-21-n63.html","Width":730,"Height":440,"FileSize":52312,"ContentType":"image\/png","Thumbnail":{"Url":"http:\/\/ts2.mm.bing.net\/images\/thumbnail.aspx?q=1533478044761&id=87c9b3eae3c7efd70ca8bd4c0000d049","ContentType":"image\/jpeg","Width":160,"Height":96,"FileSize":2462}},{"Title":"google","MediaUrl":"http:\/\/www.alertacosmico.com.ar\/images\/google.png","Url":"http:\/\/www.alertacosmico.com.ar\/google.html","DisplayUrl":"http:\/\/www.alertacosmico.com.ar\/google.html","Width":619,"Height":324,"FileSize":25156,"ContentType":"image\/png","Thumbnail":{"Url":"http:\/\/ts3.mm.bing.net\/images\/thumbnail.aspx?q=1513235355322&id=303ed99b926d0be48b2f97b5614c7306","ContentType":"image\/jpeg","Width":160,"Height":83,"FileSize":2262}},{"Title":"Free | Google Advertising Search Plugin | Top Spot or Not | New Google ...","MediaUrl":"http:\/\/blogoscoped.com\/files\/shaun-google-ie7.jpg","Url":"http:\/\/blogoscoped.com\/archive\/2005-09-20.html","DisplayUrl":"http:\/\/blogoscoped.com\/archive\/2005-09-20.html","Width":1011,"Height":838,"FileSize":100381,"ContentType":"image\/jpeg","Thumbnail":{"Url":"http:\/\/ts2.mm.bing.net\/images\/thumbnail.aspx?q=1516205713873&id=b7ae4c607d359b00a9b1faf0808f4681","ContentType":"image\/jpeg","Width":160,"Height":132,"FileSize":2649}},{"Title":"Google Chrome es el nombre del navegador creado por la empresa Google ...","MediaUrl":"http:\/\/cdn3.tusdescargasdirectas.net\/wp-content\/uploads\/2009\/11\/Google-Chrome.jpg","Url":"http:\/\/tusdescargasdirectas.net\/google-chrome.html","DisplayUrl":"http:\/\/tusdescargasdirectas.net\/google-chrome.html","Width":350,"Height":321,"FileSize":54768,"ContentType":"image\/jpeg","Thumbnail":{"Url":"http:\/\/ts1.mm.bing.net\/images\/thumbnail.aspx?q=1521468318840&id=f0adf89b0cd8ee21990954114ffc2a0d","ContentType":"image\/jpeg","Width":160,"Height":146,"FileSize":4086}},{"Title":"Facebook vs Google","MediaUrl":"http:\/\/www.myviewsandreviews.com\/wp-content\/uploads\/2010\/03\/Facebook-vs-Google.jpg","Url":"http:\/\/www.myviewsandreviews.com\/03\/facebook-vs-google.html","DisplayUrl":"http:\/\/www.myviewsandreviews.com\/03\/facebook-vs-google.html","Width":2100,"Height":1580,"FileSize":257487,"ContentType":"image\/jpeg","Thumbnail":{"Url":"http:\/\/ts1.mm.bing.net\/images\/thumbnail.aspx?q=1533133266808&id=d879272eecbea0f77a66a41d263c1f37","ContentType":"image\/jpeg","Width":160,"Height":120,"FileSize":3355}},{"Title":"Google Toolbar 6.6.1124.846","MediaUrl":"http:\/\/screenshots.de.sftcdn.net\/de\/scrn\/18000\/18858\/google-toolbar-23.jpg","Url":"http:\/\/google-toolbar.softonic.de\/","DisplayUrl":"http:\/\/google-toolbar.softonic.de\/","Width":700,"Height":525,"FileSize":101827,"ContentType":"image\/jpeg","Thumbnail":{"Url":"http:\/\/ts4.mm.bing.net\/images\/thumbnail.aspx?q=1532232607467&id=7934ed841772c774685dbf8c0e5c21ce","ContentType":"image\/jpeg","Width":160,"Height":120,"FileSize":3634}},{"Title":"Google « Cueca Virada – Blog de entretenimento, interatividade ...","MediaUrl":"http:\/\/esporteonline.com\/blogdomarcelao\/wp-content\/uploads\/2009\/03\/google-logos.jpg","Url":"http:\/\/www.cuecavirada.com.br\/tag\/google\/","DisplayUrl":"http:\/\/www.cuecavirada.com.br\/tag\/google\/","Width":480,"Height":369,"FileSize":66281,"ContentType":"image\/jpeg","Thumbnail":{"Url":"http:\/\/ts2.mm.bing.net\/images\/thumbnail.aspx?q=1518768498581&id=f16d4a57b41ee37ca6057a166355ee8c","ContentType":"image\/jpeg","Width":160,"Height":123,"FileSize":6511}},{"Title":" ... Google , google 23 nisan , google 23 nisan rezilliği , google","MediaUrl":"http:\/\/www.bosmezar.com\/wp-content\/uploads\/2011\/04\/google.jpg","Url":"http:\/\/www.bosmezar.com\/googleden-23-nisan-ulusal-egemenlik-bayrami-ayibi.html\/","DisplayUrl":"http:\/\/www.bosmezar.com\/googleden-23-nisan-ulusal-egemenlik-bayrami-ayibi.html\/","Width":513,"Height":510,"FileSize":39022,"ContentType":"image\/jpeg","Thumbnail":{"Url":"http:\/\/ts2.mm.bing.net\/images\/thumbnail.aspx?q=1519788043741&id=fe4520ac3cb69bb297ccb8ec00bb1618","ContentType":"image\/jpeg","Width":160,"Height":159,"FileSize":5621}},{"Title":"20 google chrome Fondos para Google Chrome gratis","MediaUrl":"http:\/\/www.electrocutado.com\/wp-content\/uploads\/2010\/12\/20-google_chrome.jpg","Url":"http:\/\/www.electrocutado.com\/fondos-para-google-chrome-gratis\/","DisplayUrl":"http:\/\/www.electrocutado.com\/fondos-para-google-chrome-gratis\/","Width":600,"Height":400,"FileSize":22100,"ContentType":"image\/jpeg","Thumbnail":{"Url":"http:\/\/ts2.mm.bing.net\/images\/thumbnail.aspx?q=1518657143645&id=8fe1ed85adabacce602b09a00f9f62a9","ContentType":"image\/jpeg","Width":160,"Height":106,"FileSize":3337}}]}}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"SearchResponse":{"Version":"2.2","Query":{"SearchTerms":"google"},"Web":{"Total":28400000,"Offset":0,"Results":[{"Title":"Google","Description":"웹 문서, 이미지, 뉴스그룹, 디렉터리 검색, 한글 페이지 검색.","Url":"http:\/\/www.google.co.kr\/","CacheUrl":"http:\/\/cc.bingj.com\/cache.aspx?q=google&d=4974014912726957&w=111a8224,544e08ef","DisplayUrl":"www.google.co.kr","DateTime":"2011-12-28T12:34:00Z"},{"Title":"Google","Description":"Search the world's information, including webpages, images, videos and more. Google has many special features to help you find exactly what you're looking for.","Url":"http:\/\/www.google.com\/","CacheUrl":"http:\/\/cc.bingj.com\/cache.aspx?q=google&d=4933195533126007&w=72e45eda,26137f94","DisplayUrl":"www.google.com","DateTime":"2011-12-26T16:21:00Z"},{"Title":"iGoogle","Description":"iGoogle은 나만의 Google 페이지입니다. 웹에서 찾은 뉴스, 사진, 날씨 등의 콘텐츠를 자신의 페이지에 추가하세요.","Url":"http:\/\/www.google.co.kr\/ig?sp=korea&hl=ko","CacheUrl":"http:\/\/cc.bingj.com\/cache.aspx?q=google&d=4558287859744921&w=2a57365e,1b78637b","DisplayUrl":"www.google.co.kr\/ig?sp=korea&hl=ko","DateTime":"2011-12-26T05:29:00Z"},{"Title":"Google Images","Description":"Google Images. The most comprehensive image search on the web.","Url":"http:\/\/images.google.com\/","CacheUrl":"http:\/\/cc.bingj.com\/cache.aspx?q=google&d=4584517219321018&w=6b4e3337,232daa97","DisplayUrl":"images.google.com","DateTime":"2011-12-29T09:29:00Z"},{"Title":"Google+: real life sharing, rethought for the web.","Description":"You need a Google Account to join Google+. Don't have one? Create an account","Url":"https:\/\/plus.google.com\/","CacheUrl":"http:\/\/cc.bingj.com\/cache.aspx?q=google&d=27023948180887767&w=61b9de45,d366ac15","DisplayUrl":"https:\/\/plus.google.com","DateTime":"2011-12-31T02:04:00Z"},{"Title":"Google Translate","Description":"Google's free online language translation service instantly translates text and web pages. This translator supports: English, Afrikaans, Albanian, Arabic, Armenian, Azerbaijani, Basque, Belarusian, Bengali, Bulgarian, Catalan ...","Url":"http:\/\/translate.google.com\/","CacheUrl":"http:\/\/cc.bingj.com\/cache.aspx?q=google&d=5038448007579101&w=ec5bfdea,2ab8f20d","DisplayUrl":"translate.google.com","DateTime":"2011-12-27T18:44:00Z"},{"Title":"Google","Description":"Account Options. 로그인","Url":"http:\/\/www.google.com\/intl\/ko\/","CacheUrl":"http:\/\/cc.bingj.com\/cache.aspx?q=google&d=4955370452355220&w=7f327507,42d4a341","DisplayUrl":"www.google.com\/intl\/ko","DateTime":"2011-12-29T13:11:00Z"},{"Title":"Google 학술 검색","Description":"거인의 어깨에 올라서서 더 넓은 세상을 바라보라 - 아이작 뉴턴 Google 학술검색 정보-Google 정보-Google Scholar in English ©2011 Google","Url":"http:\/\/scholar.google.co.kr\/","CacheUrl":"http:\/\/cc.bingj.com\/cache.aspx?q=google&d=4840849451058731&w=7442bce0,5eb1cc76","DisplayUrl":"scholar.google.co.kr","DateTime":"2011-12-26T16:20:00Z"},{"Title":"Google 번역","Description":"Google의 무료 온라인 언어 번역 서비스는 텍스트와 웹페이지를 즉시 번역해 줍니다. 번역 서비스에서 지원하는 기능은 다음과 같습니다. 한국어, 갈리시아어, 구자라트어 ...","Url":"http:\/\/translate.google.com\/?hl=ko&tab=wT","CacheUrl":"http:\/\/cc.bingj.com\/cache.aspx?q=google&d=4897079160537368&w=79d1b9d6,2c1b54fc","DisplayUrl":"translate.google.com\/?hl=ko&tab=wT","DateTime":"2011-12-26T22:24:00Z"},{"Title":"Google Maps","Description":"Interactive maps and satellite\/aerial imagery of the United States.","Url":"http:\/\/maps.google.com\/","CacheUrl":"http:\/\/cc.bingj.com\/cache.aspx?q=google&d=4900077049872785&w=7ffce161,7bede9a9","DisplayUrl":"maps.google.com","DateTime":"2011-12-29T01:35:00Z"}]}}}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gnib::Configurations do
|
4
|
+
it "is not initialized by constructor" do
|
5
|
+
expect { Gnib::Configurations.new }.should raise_error
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#singleton_object" do
|
9
|
+
it "does not return nil object" do
|
10
|
+
Gnib::Configurations.singleton_object.should_not == nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns the singleton object" do
|
14
|
+
obj_before = Gnib::Configurations.singleton_object
|
15
|
+
obj_after = Gnib::Configurations.singleton_object
|
16
|
+
|
17
|
+
obj_before.object_id.should == obj_after.object_id
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "after initialization of singleton object" do
|
22
|
+
let(:config) { Gnib::Configurations.singleton_object }
|
23
|
+
|
24
|
+
describe "#application_id=" do
|
25
|
+
it "sets application id" do
|
26
|
+
config.application_id = 'myid'
|
27
|
+
config.application_id.should == 'myid'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#api_root" do
|
32
|
+
it "returns default value if not modified" do
|
33
|
+
config.api_root.should == 'http://api.bing.net/json.aspx'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#api_root=" do
|
38
|
+
it "sets api root uri" do
|
39
|
+
config.api_root = 'http://google.com'
|
40
|
+
config.api_root.should == 'http://google.com'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gnib::Response do
|
4
|
+
let(:rsp) { Gnib::Response.new(File.open(File.join(File.dirname(__FILE__), '../sample_web_response'), 'r:ASCII-8BIT').read) }
|
5
|
+
|
6
|
+
describe "#result_count_of" do
|
7
|
+
it "counts number of total results" do
|
8
|
+
rsp.result_count_of(:web).should == 28400000
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#results_for" do
|
13
|
+
it "returns result objects for each result" do
|
14
|
+
rsp.results_for(:web).first.class.should == Gnib::SearchResult
|
15
|
+
end
|
16
|
+
|
17
|
+
it "returns results in one page" do
|
18
|
+
rsp.results_for(:web).count.should == 10
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#results" do
|
23
|
+
it "returns appropriate result objects" do
|
24
|
+
rsp.results.first.class.should == Gnib::SearchResult
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns all results objects" do
|
28
|
+
rsp.results.count.should == 10
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gnib::SearchResult do
|
4
|
+
context "when image results are fetched" do
|
5
|
+
let(:result) { Gnib::Response.new(File.open(File.join(File.dirname(__FILE__), '../sample_image_response'), 'r:ASCII-8BIT').read).results_for(:image).first }
|
6
|
+
|
7
|
+
describe "#media_url" do
|
8
|
+
it "returns media url of the result" do
|
9
|
+
result.media_url.should == "http:\/\/www.blog.webtec-braun.com\/wp-content\/uploads\/google.jpg"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#url" do
|
14
|
+
it "returns url of the result" do
|
15
|
+
result.url.should == "http:\/\/www.blog.webtec-braun.com\/google\/top-news-google-setzt-auf-schnelligkeit.html"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#width" do
|
20
|
+
it "returns width of the result" do
|
21
|
+
result.width.should == 600
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#height" do
|
26
|
+
it "returns height of the result" do
|
27
|
+
result.height.should == 400
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#file_size" do
|
32
|
+
it "returns file size of the result" do
|
33
|
+
result.file_size.should == 15719
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#content_type" do
|
38
|
+
it "returns content type of the result" do
|
39
|
+
result.content_type.should == "image/jpeg"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#thumbnail_url" do
|
44
|
+
it "returns url of thumbnail of the result" do
|
45
|
+
result.thumbnail.url.should == "http:\/\/ts4.mm.bing.net\/images\/thumbnail.aspx?q=1524014450527&id=421bf34508bee00c8f75b0af9529c1ab"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when web results are fetched" do
|
52
|
+
let(:result) { Gnib::Response.new(File.open(File.join(File.dirname(__FILE__), '../sample_web_response'), 'r:ASCII-8BIT').read).results_for(:web).first }
|
53
|
+
|
54
|
+
it "parses the json and retrieves attributes" do
|
55
|
+
result.title.should == 'Google'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gnib::Search do
|
4
|
+
before(:all) do
|
5
|
+
Gnib.config.application_id = 'myid'
|
6
|
+
end
|
7
|
+
|
8
|
+
it "is initialized with query" do
|
9
|
+
expect { s = Gnib::Search.new('google') }.should_not raise_error
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when a string parameter is provided" do
|
13
|
+
let(:search) { Gnib::Search.new('google') }
|
14
|
+
|
15
|
+
it "serializes it appropriately" do
|
16
|
+
serialized_str = search.send :serialized_parameters
|
17
|
+
serialized_str.should include("Query=#{CGI::escape('google')}")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has app id in parameters" do
|
21
|
+
serialized_str = search.send :serialized_parameters
|
22
|
+
serialized_str.should include("AppId=myid")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when an array parameter is provided" do
|
27
|
+
let(:search) { Gnib::Search.new('google', :sources => ['image', 'spell']) }
|
28
|
+
|
29
|
+
it "serializes it appropriately" do
|
30
|
+
serialized_str = search.send :serialized_parameters
|
31
|
+
serialized_str.should include("Sources=#{CGI::escape('image+spell')}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gnib
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Inbeom Hwang
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: &70318958358140 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70318958358140
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70318958357720 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70318958357720
|
36
|
+
description: Gnib provides interfaces for Bing Search API version 2.0
|
37
|
+
email:
|
38
|
+
- inbeom@wafflestudio.com
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
extra_rdoc_files: []
|
42
|
+
files:
|
43
|
+
- .gitignore
|
44
|
+
- .rvmrc
|
45
|
+
- Gemfile
|
46
|
+
- Gemfile.lock
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
49
|
+
- gnib.gemspec
|
50
|
+
- lib/gnib.rb
|
51
|
+
- lib/gnib/configurations.rb
|
52
|
+
- lib/gnib/response.rb
|
53
|
+
- lib/gnib/search.rb
|
54
|
+
- lib/gnib/search_helper.rb
|
55
|
+
- lib/gnib/search_request.rb
|
56
|
+
- lib/gnib/search_result.rb
|
57
|
+
- lib/gnib/version.rb
|
58
|
+
- spec/sample_image_response
|
59
|
+
- spec/sample_web_response
|
60
|
+
- spec/spec_helper.rb
|
61
|
+
- spec/unit/configurations_spec.rb
|
62
|
+
- spec/unit/response_spec.rb
|
63
|
+
- spec/unit/search_result_spec.rb
|
64
|
+
- spec/unit/search_spec.rb
|
65
|
+
homepage: ''
|
66
|
+
licenses: []
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.8.10
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Ruby library for Microsoft Bing Search API
|
89
|
+
test_files:
|
90
|
+
- spec/sample_image_response
|
91
|
+
- spec/sample_web_response
|
92
|
+
- spec/spec_helper.rb
|
93
|
+
- spec/unit/configurations_spec.rb
|
94
|
+
- spec/unit/response_spec.rb
|
95
|
+
- spec/unit/search_result_spec.rb
|
96
|
+
- spec/unit/search_spec.rb
|