gnib 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.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
|