binged 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem "hashie"
4
+ gem 'activesupport', '>= 3.0.0'
5
+
6
+ group :development do
7
+ gem "rspec", ">= 1.3.0"
8
+ gem "fakeweb", ">=1.2.8"
9
+ gem "yard", ">= 0"
10
+ end
data/HISTORY CHANGED
@@ -1,9 +1,13 @@
1
+ == 1.0.0 (unreleased)
2
+ * Migrate to Bing Search API 2.0. See https://datamarket.azure.com/dataset/bing/search and http://go.microsoft.com/fwlink/?LinkID=248077 for more details.
3
+ * Raise a Bing::Search::Error in at least some of the failure modes.
4
+
1
5
  == 0.3.0 2010-03-15
2
6
 
3
7
  === New features
4
8
  * Added an Video source provider to allow for Video searching with Binged
5
9
 
6
10
  == 0.2.0 2010-03-12
7
-
11
+
8
12
  === New features
9
13
  * Added an Image source provider to allow for Image searching with Binged
data/README.md CHANGED
@@ -15,19 +15,19 @@ To use binged, you will require a Bing API key. Create one at: [http://www.bing.
15
15
  ## Usage
16
16
 
17
17
  ### Instantiate a client
18
- binged = Binged::Client.new(:api_key => 'binged')
19
-
18
+ binged = Binged::Client.new(:account_key => 'binged')
19
+
20
20
  ### Ruby on Rails
21
-
21
+
22
22
  Binged allows for configuration to be done once using a configure block. To use binged in your Ruby on Rails project, configure it globally in an initializer.
23
-
23
+
24
24
  # config/initializers/binged.rb
25
25
  Binged.configure do |config|
26
- config.api_key = 'api_key'
26
+ config.account_key = 'account_key'
27
27
  end
28
-
28
+
29
29
  # Client initialization
30
- binged = Binged::Client.new
30
+ binged = Binged::Client.new
31
31
 
32
32
  ### Web Search Example
33
33
 
@@ -39,10 +39,10 @@ Binged allows for configuration to be done once using a configure block. To use
39
39
 
40
40
  # Find all portrait Matz images with a wide aspect ratio
41
41
  image_search = Binged::Client.new.image
42
- image_search.containing('Yukihiro Matsumoto').portrait.wide.each {|image| pp image}
43
-
42
+ image_search.containing('Yukihiro Matsumoto').portrait.safe_search(:strict).wide.each {|image| pp image}
43
+
44
44
  ## Note on Patches/Pull Requests
45
-
45
+
46
46
  * Fork the project.
47
47
  * Make your feature addition or bug fix.
48
48
  * Add tests for it. This is important so I don't break it in a
data/Rakefile CHANGED
@@ -10,11 +10,6 @@ begin
10
10
  gem.email = "kevin.faustino@gmail.com"
11
11
  gem.homepage = "http://github.com/kfaustino/binged"
12
12
  gem.authors = ["Kevin Faustino"]
13
- gem.add_dependency "hashie", "~>0.1.0"
14
- gem.add_dependency "crack", ">=0.1.6"
15
- gem.add_development_dependency "rspec", ">= 1.3.0"
16
- gem.add_development_dependency "fakeweb", ">=1.2.8"
17
- gem.add_development_dependency "yard", ">= 0"
18
13
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
14
  end
20
15
  Jeweler::GemcutterTasks.new
@@ -22,20 +17,16 @@ rescue LoadError
22
17
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
23
18
  end
24
19
 
25
- require 'spec/rake/spectask'
26
- Spec::Rake::SpecTask.new(:spec) do |spec|
27
- spec.libs << 'lib' << 'spec'
28
- spec.spec_files = FileList['spec/**/*_spec.rb']
20
+ require 'rspec/core/rake_task'
21
+ RSpec::Core::RakeTask.new do |t|
22
+ t.pattern = 'spec/**/*_spec.rb'
29
23
  end
30
24
 
31
- Spec::Rake::SpecTask.new(:rcov) do |spec|
32
- spec.libs << 'lib' << 'spec'
33
- spec.pattern = 'spec/**/*_spec.rb'
34
- spec.rcov = true
25
+ RSpec::Core::RakeTask.new(:rcov) do |t|
26
+ t.pattern = 'spec/**/*_spec.rb'
27
+ t.rcov = true
35
28
  end
36
29
 
37
- task :spec => :check_dependencies
38
-
39
30
  task :default => :spec
40
31
 
41
32
  begin
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 1.0.0
data/binged.gemspec CHANGED
@@ -1,85 +1,76 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{binged}
8
- s.version = "0.3.0"
7
+ s.name = "binged"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kevin Faustino"]
12
- s.date = %q{2010-03-15}
13
- s.description = %q{A wrapper for the bing api}
14
- s.email = %q{kevin.faustino@gmail.com}
12
+ s.date = "2012-11-06"
13
+ s.description = "A wrapper for the bing api"
14
+ s.email = "kevin.faustino@gmail.com"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.md"
17
+ "README.md"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
- ".gitignore",
22
- "HISTORY",
23
- "LICENSE",
24
- "README.md",
25
- "Rakefile",
26
- "VERSION",
27
- "binged.gemspec",
28
- "lib/binged.rb",
29
- "lib/binged/client.rb",
30
- "lib/binged/hashie_extensions.rb",
31
- "lib/binged/search.rb",
32
- "lib/binged/search/base.rb",
33
- "lib/binged/search/image.rb",
34
- "lib/binged/search/video.rb",
35
- "lib/binged/search/web.rb",
36
- "spec/binged/search/image_spec.rb",
37
- "spec/binged/search/video_spec.rb",
38
- "spec/binged/search/web_spec.rb",
39
- "spec/binged_spec.rb",
40
- "spec/fixtures/images.json",
41
- "spec/fixtures/videos.json",
42
- "spec/fixtures/web.json",
43
- "spec/spec.opts",
44
- "spec/spec_helper.rb",
45
- "spec/support/shared_examples/filter.rb",
46
- "spec/support/shared_examples/pageable.rb"
47
- ]
48
- s.homepage = %q{http://github.com/kfaustino/binged}
49
- s.rdoc_options = ["--charset=UTF-8"]
50
- s.require_paths = ["lib"]
51
- s.rubygems_version = %q{1.3.6}
52
- s.summary = %q{A wrapper for the bing api}
53
- s.test_files = [
21
+ "Gemfile",
22
+ "HISTORY",
23
+ "LICENSE",
24
+ "README.md",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "binged.gemspec",
28
+ "lib/binged.rb",
29
+ "lib/binged/client.rb",
30
+ "lib/binged/hashie_extensions.rb",
31
+ "lib/binged/search.rb",
32
+ "lib/binged/search/base.rb",
33
+ "lib/binged/search/image.rb",
34
+ "lib/binged/search/video.rb",
35
+ "lib/binged/search/web.rb",
36
+ "spec/binged/search/client_spec.rb",
54
37
  "spec/binged/search/image_spec.rb",
55
- "spec/binged/search/video_spec.rb",
56
- "spec/binged/search/web_spec.rb",
57
- "spec/binged_spec.rb",
58
- "spec/spec_helper.rb",
59
- "spec/support/shared_examples/filter.rb",
60
- "spec/support/shared_examples/pageable.rb"
38
+ "spec/binged/search/video_spec.rb",
39
+ "spec/binged/search/web_spec.rb",
40
+ "spec/binged_spec.rb",
41
+ "spec/fixtures/bad_request.curl",
42
+ "spec/fixtures/images.curl",
43
+ "spec/fixtures/videos.curl",
44
+ "spec/fixtures/web.curl",
45
+ "spec/spec.opts",
46
+ "spec/spec_helper.rb",
47
+ "spec/support/shared_examples/filter.rb",
48
+ "spec/support/shared_examples/pageable.rb"
61
49
  ]
50
+ s.homepage = "http://github.com/kfaustino/binged"
51
+ s.require_paths = ["lib"]
52
+ s.rubygems_version = "1.8.23"
53
+ s.summary = "A wrapper for the bing api"
62
54
 
63
55
  if s.respond_to? :specification_version then
64
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
65
56
  s.specification_version = 3
66
57
 
67
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
68
- s.add_runtime_dependency(%q<hashie>, ["~> 0.1.0"])
69
- s.add_runtime_dependency(%q<crack>, [">= 0.1.6"])
58
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
+ s.add_runtime_dependency(%q<hashie>, [">= 0"])
60
+ s.add_runtime_dependency(%q<activesupport>, [">= 3.0.0"])
70
61
  s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
71
62
  s.add_development_dependency(%q<fakeweb>, [">= 1.2.8"])
72
63
  s.add_development_dependency(%q<yard>, [">= 0"])
73
64
  else
74
- s.add_dependency(%q<hashie>, ["~> 0.1.0"])
75
- s.add_dependency(%q<crack>, [">= 0.1.6"])
65
+ s.add_dependency(%q<hashie>, [">= 0"])
66
+ s.add_dependency(%q<activesupport>, [">= 3.0.0"])
76
67
  s.add_dependency(%q<rspec>, [">= 1.3.0"])
77
68
  s.add_dependency(%q<fakeweb>, [">= 1.2.8"])
78
69
  s.add_dependency(%q<yard>, [">= 0"])
79
70
  end
80
71
  else
81
- s.add_dependency(%q<hashie>, ["~> 0.1.0"])
82
- s.add_dependency(%q<crack>, [">= 0.1.6"])
72
+ s.add_dependency(%q<hashie>, [">= 0"])
73
+ s.add_dependency(%q<activesupport>, [">= 3.0.0"])
83
74
  s.add_dependency(%q<rspec>, [">= 1.3.0"])
84
75
  s.add_dependency(%q<fakeweb>, [">= 1.2.8"])
85
76
  s.add_dependency(%q<yard>, [">= 0"])
data/lib/binged/client.rb CHANGED
@@ -3,30 +3,32 @@ module Binged
3
3
  # A client which encapsulates the Bing API
4
4
  class Client
5
5
 
6
- attr_accessor :api_key
6
+ attr_accessor :account_key
7
7
 
8
8
  # @param [Hash] options the options to create a client with.
9
- # @option options [String] :api_key The Bing API key used to make all API calls.
9
+ # @option options [String] :account_key The Bing API key used to make all API calls.
10
10
  def initialize(options = {})
11
- @api_key = options[:api_key] || Binged.api_key
11
+ invalid_options = options.keys - [:account_key]
12
+ raise ArgumentError, "Invalid options: #{invalid_options.inspect}." unless invalid_options.empty?
13
+ @account_key = options[:account_key] || Binged.account_key
12
14
  end
13
15
 
14
16
  # Create a web search through Bing
15
- #
17
+ #
16
18
  # @param [String] query The search term to be sent to Bing
17
19
  def web(query='')
18
20
  Search::Web.new(self,query)
19
21
  end
20
-
22
+
21
23
  # Create a image search through Bing
22
- #
24
+ #
23
25
  # @param [String] query The search term to be sent to Bing
24
26
  def image(query='')
25
27
  Search::Image.new(self,query)
26
28
  end
27
-
29
+
28
30
  # Create a video search through Bing
29
- #
31
+ #
30
32
  # @param [String] query The search term to be sent to Bing
31
33
  def video(query='')
32
34
  Search::Video.new(self,query)
@@ -1,12 +1,16 @@
1
1
  module Binged
2
2
  module Search
3
+ class Error < StandardError
4
+ end
3
5
 
4
6
  # @abstract Subclass and set @source to implement a custom Searchable class
5
7
  class Base
6
8
  include Enumerable
7
9
  attr_reader :client, :query, :source
8
10
 
9
- BASE_URI = 'http://api.bing.net/json.aspx?'
11
+ BASE_URI = 'https://api.datamarket.azure.com/Data.ashx/Bing/Search/'
12
+
13
+ SUPPORTED_ADULT_OPTIONS = [:off, :moderate, :strict]
10
14
 
11
15
  # @param [Binged::Client] client
12
16
  # @param [String] query The search term to be sent to Bing
@@ -26,6 +30,12 @@ module Binged
26
30
  self
27
31
  end
28
32
 
33
+ def adult(adult_option)
34
+ @query[:Adult] = adult_option if SUPPORTED_ADULT_OPTIONS.include?(adult_option)
35
+ self
36
+ end
37
+ alias safe_search adult
38
+
29
39
  # Clears all filters to perform a new search
30
40
  def clear
31
41
  @fetch = nil
@@ -39,7 +49,7 @@ module Binged
39
49
  def fetch
40
50
  if @fetch.nil?
41
51
  response = perform
42
- @fetch = Hashie::Mash.new(response["SearchResponse"][self.source.to_s.capitalize])
52
+ @fetch = Hashie::Mash.new(response["d"])
43
53
  end
44
54
 
45
55
  @fetch
@@ -49,16 +59,26 @@ module Binged
49
59
  #
50
60
  # @return [Hash] Hash of Bing API response
51
61
  def perform
52
- url = URI.parse BASE_URI
62
+ url = URI.parse [BASE_URI, self.source.to_s.capitalize].join
53
63
  query = @query.dup
54
64
  query[:Query] = query[:Query].join(' ')
55
- query[:Sources] = self.source
56
65
  callbacks.each {|callback| callback.call(query) }
57
- query_options = default_options.merge(query).to_params
66
+ query.each do |key, value|
67
+ query[key] = %{'#{value}'} unless key[0] == '$' || ['Latitude', 'Longitude'].include?(key)
68
+ end
69
+ query_options = default_options.merge(query).to_query
58
70
  query_options.gsub! '%2B', '+'
59
71
  url.query = query_options
60
- response = Net::HTTP.get(url)
61
- Crack::JSON.parse(response)
72
+ request = Net::HTTP::Get.new(url.request_uri)
73
+ request.basic_auth(@client.account_key, @client.account_key)
74
+ response = Net::HTTP.start(url.hostname, url.port, :use_ssl => true) {|http|
75
+ http.request(request)
76
+ }
77
+ begin
78
+ JSON.parse(response.body)
79
+ rescue JSON::ParserError => e
80
+ raise Error, response.body.strip
81
+ end
62
82
  end
63
83
 
64
84
  # @yieldreturn [Hash] A result from a Bing query
@@ -73,13 +93,13 @@ module Binged
73
93
  private
74
94
 
75
95
  def default_options
76
- {:AppId => @client.api_key, :JsonType => 'raw', :Version => '2.2' }
96
+ { '$format' => 'JSON' }
77
97
  end
78
98
 
79
99
  def reset_query
80
100
  @query = { :Query => [] }
81
101
  end
82
-
102
+
83
103
  end
84
104
 
85
105
  end
@@ -17,7 +17,7 @@ module Binged
17
17
  end
18
18
 
19
19
  # Restrict images to those small in size
20
- #
20
+ #
21
21
  # @return [self]
22
22
  def small
23
23
  filter << 'Size:Small'
@@ -25,7 +25,7 @@ module Binged
25
25
  end
26
26
 
27
27
  # Restrict images to those medium in size
28
- #
28
+ #
29
29
  # @return [self]
30
30
  def medium
31
31
  filter << 'Size:Medium'
@@ -58,7 +58,7 @@ module Binged
58
58
  end
59
59
 
60
60
  # Restrict images to those that have a square aspect ratio
61
- #
61
+ #
62
62
  # @return [self]
63
63
  def square
64
64
  filter << 'Aspect:Square'
@@ -66,7 +66,7 @@ module Binged
66
66
  end
67
67
 
68
68
  # Restrict images to those that have a wide aspect ratio
69
- #
69
+ #
70
70
  # @return [self]
71
71
  def wide
72
72
  filter << 'Aspect:Wide'
@@ -74,55 +74,55 @@ module Binged
74
74
  end
75
75
 
76
76
  # Restrict images to those that have a tall aspect ratio
77
- #
77
+ #
78
78
  # @return [self]
79
79
  def tall
80
80
  filter << 'Aspect:Tall'
81
81
  self
82
82
  end
83
-
83
+
84
84
  # Restrict images to those that are in color
85
- #
85
+ #
86
86
  # @return [self]
87
87
  def color
88
88
  filter << 'Color:Color'
89
- self
89
+ self
90
+ end
91
+
92
+ # Restrict images to those that are in black and white
93
+ #
94
+ # @return [self]
95
+ def monochrome
96
+ filter << 'Color:Monochrome'
97
+ self
90
98
  end
91
-
99
+
92
100
  # Restrict images to those which contain photos
93
- #
101
+ #
94
102
  # @return [self]
95
103
  def photo
96
104
  filter << 'Style:Photo'
97
105
  self
98
106
  end
99
-
107
+
100
108
  # Restrict images to those which contain graphics or illustrations
101
- #
109
+ #
102
110
  # @return [self]
103
111
  def graphics
104
112
  filter << 'Style:Graphics'
105
113
  self
106
114
  end
107
-
108
- # Restrict images to those that are in black and white
109
- #
110
- # @return [self]
111
- def monochrome
112
- filter << 'Color:Monochrome'
113
- self
114
- end
115
-
115
+
116
116
  # Restrict images to those which contain faces
117
- #
117
+ #
118
118
  # @return [self]
119
119
  def face
120
120
  filter << 'Face:Face'
121
121
  self
122
122
  end
123
-
123
+
124
124
  # Restrict images to those which contain portraits(head and shoulders)
125
- #
125
+ #
126
126
  # @return [self]
127
127
  def portrait
128
128
  filter << 'Face:Portrait'
@@ -132,11 +132,11 @@ module Binged
132
132
  private
133
133
 
134
134
  def create_filter_callback
135
- @callbacks << Proc.new { |query| query['Image.Filters'] = query['Image.Filters'].join('+') if query['Image.Filters'] }
135
+ @callbacks << Proc.new { |query| query['ImageFilters'] = query['ImageFilters'].join('+') if query['ImageFilters'] && !query['ImageFilters'].empty? }
136
136
  end
137
137
 
138
138
  def filter
139
- @query['Image.Filters'] ||= []
139
+ @query['ImageFilters'] ||= []
140
140
  end
141
141
 
142
142
  end
data/lib/binged/search.rb CHANGED
@@ -8,14 +8,14 @@ module Binged
8
8
  autoload :Video, "binged/search/video"
9
9
 
10
10
  module Pageable
11
-
11
+
12
12
  # Set the page number of the results to display
13
13
  #
14
14
  # @param [Fixnum] num The page number of the search results
15
15
  # @return [self]
16
16
  def page(num=1)
17
17
  @offset = num - 1
18
- @query["#{@source.to_s.capitalize}.Offset"] = @results_per_page * @offset
18
+ @query["$skip"] = @results_per_page * @offset
19
19
  self
20
20
  end
21
21
 
@@ -25,20 +25,20 @@ module Binged
25
25
  # @return [self]
26
26
  def per_page(num)
27
27
  @results_per_page = num
28
- @query["#{@source.to_s.capitalize}.Count"] = @results_per_page
28
+ @query["$top"] = @results_per_page
29
29
  self
30
30
  end
31
-
31
+
32
32
  protected
33
-
33
+
34
34
  def set_paging_defaults
35
35
  self.per_page(20).page(1)
36
36
  end
37
-
37
+
38
38
  end
39
-
39
+
40
40
  module Filter
41
-
41
+
42
42
  # # Isolate search results to a specific site
43
43
  #
44
44
  # @example
@@ -50,8 +50,8 @@ module Binged
50
50
  @query[:Query] << "site:#{site}"
51
51
  self
52
52
  end
53
-
53
+
54
54
  end
55
-
55
+
56
56
  end
57
57
  end
data/lib/binged.rb CHANGED
@@ -1,9 +1,9 @@
1
- require 'crack'
1
+ require 'active_support/core_ext/object/to_query'
2
+ require 'json'
2
3
  require 'hashie'
3
- require 'net/http'
4
+ require 'net/https'
4
5
  require 'uri'
5
6
 
6
- Hash.send :include, Hashie::HashExtensions
7
7
  require 'binged/hashie_extensions'
8
8
 
9
9
  # The module that contains everything Binged related
@@ -13,23 +13,21 @@ require 'binged/hashie_extensions'
13
13
  module Binged
14
14
  autoload :Client, "binged/client"
15
15
  autoload :Search, "binged/search"
16
-
16
+
17
+ extend self
18
+
17
19
  # Configure global options for Binged
18
- #
20
+ #
19
21
  # For example:
20
- #
22
+ #
21
23
  # Binged.configure do |config|
22
- # config.api_key = 'api_key'
24
+ # config.account_key = 'account_key'
23
25
  # end
24
- def self.configure
26
+ attr_accessor :account_key
27
+
28
+ def configure
25
29
  yield self
26
30
  true
27
31
  end
28
32
 
29
- class << self
30
- attr_accessor :api_key
31
- end
32
-
33
33
  end
34
-
35
-
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe Binged::Client do
4
+ describe '.new' do
5
+ context 'with a defunct api_key' do
6
+ it 'raises' do
7
+ expect {
8
+ Binged::Client.new(:api_key => 'binged')
9
+ }.to raise_error(ArgumentError)
10
+ end
11
+ end
12
+ end
13
+ end