yummly 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ .idea
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in yummly.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Theo Mills
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Yummly
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'yummly'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install yummly
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/yummly/api.rb ADDED
@@ -0,0 +1,35 @@
1
+ # This class is the primary mechanism to execute Yummly API calls.
2
+ #
3
+ # Currently Yummly only has two public API calls: one for searching recipes and the other to retrieve a specific recipe.
4
+ #
5
+ # @example
6
+ # Yummly::Api.find('French-Onion-Soup-The-Pioneer-Woman-Cooks-_-Ree-Drummond-41364')
7
+ # @example
8
+ # Yummly::Api.search('Onion soup')
9
+ class Yummly::Api
10
+
11
+ # Retrieves a single recipe.
12
+ #
13
+ # @param [String] id The yummly recipe identifier.
14
+ # @return [Yummly::Recipe] a instance of a recipe object
15
+ # @example
16
+ # recipe = Yummly::Api.find('French-Onion-Soup-The-Pioneer-Woman-Cooks-_-Ree-Drummond-41364')
17
+ def self.find(id)
18
+ recipe_json = Yummly::Connection.get("recipe/#{id}")
19
+ Yummly::Recipe.new(recipe_json)
20
+ end
21
+
22
+ # Searches for recipes that match the supplied search terms.
23
+ #
24
+ # @param [String] terms A string of terms used to search API
25
+ # @param [Hash] params Additional options to pass to the search API
26
+ # @return [Array] a collection of recipe objects
27
+ # @example
28
+ # recipes = Yummly::Api.search('Onion soup')
29
+ def self.search(terms, params = {})
30
+ params[:q] = terms unless params.has_key?(:q)
31
+ result = Yummly::Connection.get(:recipes, params)
32
+ result["matches"].collect { |recipe_json| Yummly::Recipe.new(recipe_json) }
33
+ end
34
+
35
+ end
@@ -0,0 +1,36 @@
1
+ # Configuration class that stores configuration options for the Yummly API.
2
+ #
3
+ # Yummly requires an App ID and APP key combination to authenticate against its API. At the very least these must be
4
+ # supplied in the configuration.
5
+ #
6
+ # Additionally for certain paid plans Yummly offers SSL API access, so setting the configuration option use_ssl to true
7
+ # will send all API calls over HTTPS. This options defaults to false.
8
+ #
9
+ # Configuration options are typically set via the Yummly.config method.
10
+ # @see Yummly.configure
11
+ # @example
12
+ # Yummly.configure do |config|
13
+ # config.app_id = "12345"
14
+ # config.app_key = "XXXXXXXXXXXXXXXXXXXXXXXX"
15
+ # end
16
+ class Yummly::Configuration
17
+
18
+ attr_accessor :app_key,
19
+ :app_id,
20
+ :use_ssl
21
+
22
+ # Creates a configuration object, defaulting use_ssl to false.
23
+ def initialize
24
+ @use_ssl = false
25
+ end
26
+
27
+ # Returns true if API calls to Yummly should use SSL.
28
+ #
29
+ # @return [Boolean] true if API calls to Yummly should use SSL
30
+ # @example
31
+ # Yummly.configuration.use_ssl?
32
+ def use_ssl?
33
+ use_ssl
34
+ end
35
+
36
+ end
@@ -0,0 +1,29 @@
1
+ # This class handles the HTTP interactions with the Yummly API calls.
2
+ class Yummly::Connection
3
+
4
+ attr_accessor :connection
5
+
6
+ def self.get(command, params = {})
7
+ params['_app_id'] = Yummly.configuration.app_id
8
+ params['_app_key'] = Yummly.configuration.app_key
9
+ response = self.api_connection.get("/#{self.api_version}/api/#{command}?#{Rack::Utils.build_query(params)}")
10
+ JSON.parse(response.body)
11
+ end
12
+
13
+ def self.api_connection
14
+ Faraday.new(:url => "#{self.protocol}://api.yummly.com") do |faraday|
15
+ faraday.request :url_encoded # form-encode POST params
16
+ faraday.response :logger # log requests to STDOUT
17
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
18
+ end
19
+ end
20
+
21
+ def self.protocol
22
+ Yummly.configuration.use_ssl? ? 'https' : 'http'
23
+ end
24
+
25
+ def self.api_version
26
+ Yummly::API_VERSION
27
+ end
28
+
29
+ end
@@ -0,0 +1,19 @@
1
+ # Contains the flavor scores for a recipe, each on a range from 0 to 1.
2
+ class Yummly::Flavor
3
+
4
+ attr_accessor :spiciness,
5
+ :bitterness,
6
+ :sweetness,
7
+ :savoriness,
8
+ :saltiness,
9
+ :sourness
10
+
11
+ def initialize(values)
12
+ @spiciness = values["spicy"]
13
+ @bitterness = values["bitter"]
14
+ @sweetness = values["sweet"]
15
+ @savoriness = values["meaty"]
16
+ @sourness = values["sour"]
17
+ end
18
+
19
+ end
@@ -0,0 +1,19 @@
1
+ # The image that should be displayed along with the recipe if images are available. Comes in 3 different sizes.
2
+ class Yummly::Image
3
+
4
+ # small (90×60)
5
+ attr_accessor :small_url
6
+
7
+ # medium (180×120)
8
+ attr_accessor :medium_url
9
+
10
+ # large (360×240)
11
+ attr_accessor :large_url
12
+
13
+ def initialize(values)
14
+ @large_url = values["hostedLargeUrl"]
15
+ @medium_url = values["hostedMediumUrl"]
16
+ @small_url = values["hostedSmallUrl"]
17
+ end
18
+
19
+ end
@@ -0,0 +1,25 @@
1
+ # The nutritional composition of the recipe, in the form of a list of nutrients and their amounts, per serving. Yummly
2
+ # will return nutrition estimates only for those recipes where we are reasonably confident in their accuracy. These are
3
+ # only estimates and you should be clear about that in what you tell your users.
4
+ class Yummly::NutritionEstimate
5
+
6
+ # Nutrition attribute’s search parameter name.
7
+ attr_accessor :attribute
8
+
9
+ # Display name of this nutrition attribute.
10
+ attr_accessor :description
11
+
12
+ # Nutrition attribute value for this recipe.
13
+ attr_accessor :value
14
+
15
+ # Implied unit of measure as a Yummly::Unit object.
16
+ attr_accessor :unit
17
+
18
+ def initialize(values)
19
+ @attribute = values["attribute"]
20
+ @description = values["description"]
21
+ @value = values["value"]
22
+ @unit = Yummly::Unit.new(values["unit"])
23
+ end
24
+
25
+ end
@@ -0,0 +1,101 @@
1
+ # This class maps a Yummly response to attributes on to a recipe object. Because the search and find API calls return
2
+ # recipe data slightly different structures, it also automatically rectifies these differences where possible.
3
+ #
4
+ # When a response attribute is an array, collections of related objects will be created for convenience. For example,
5
+ # the "images" attribute on the response maps to the #images method which returns a collection of Yummlly::Image
6
+ # objects.
7
+ class Yummly::Recipe
8
+
9
+ attr_accessor :response
10
+
11
+ def initialize(recipe_json)
12
+ @response = recipe_json
13
+ end
14
+
15
+ # Nutrition attribute’s search parameter name.
16
+ def attribute
17
+ response["attribute"]
18
+ end
19
+
20
+ def attributes
21
+ response["attributes"]
22
+ end
23
+
24
+ def attribution
25
+ response["attribution"]
26
+ end
27
+
28
+ def description
29
+ response["description"]
30
+ end
31
+
32
+ # @return [Yummly::Flavor] instance of a Yummly::Flavor object
33
+ def flavor
34
+ @flavor ||= Yummly::Flavor.new(response["flavors"])
35
+ end
36
+
37
+ # @return [String] the Yummly id for this recipe.
38
+ def id
39
+ response["id"]
40
+ end
41
+
42
+ # @return [Array] collection of Yummly::Image objects.
43
+ def images
44
+ @images ||= images_node.collect { |image| Yummly::Image.new(image) }
45
+ end
46
+
47
+ # @return [Array] collection of strings of ingredients.
48
+ def ingredients
49
+ response["ingredients"]
50
+ end
51
+
52
+ # @return [Array] collection of strings of ingredients.
53
+ def ingredient_lines
54
+ response["ingredientLines"]
55
+ end
56
+
57
+ # Returns the name of the recipe, automatically finding it using the correct response node.
58
+ # @return [String] name of the recipe
59
+ def name
60
+ response["name"] || recipe_name
61
+ end
62
+
63
+ # @return [Integer] number of servings this recipe provides.
64
+ def number_of_servings
65
+ response["numberOfServings"]
66
+ end
67
+
68
+ # The nutritional composition of the recipe, in the form of a list of nutrients and their amounts, per serving. We
69
+ # will return nutrition estimates only for those recipes where we are reasonably confident in their accuracy. These
70
+ # are only estimates and you should be clear about that in what you tell your users.
71
+ # @return [Array] collection of Yummly::NutritionEstimate objects.
72
+ def nutrition_estimates
73
+ @nutrition_estimates ||= response["nutritionEstimates"].collect { |ne| Yummly::NutritionEstimate.new(ne) }
74
+ end
75
+
76
+ def rating
77
+ response["rating"]
78
+ end
79
+
80
+ def recipe_name
81
+ response["recipeName"]
82
+ end
83
+
84
+ def total_time
85
+ response["totalTime"]
86
+ end
87
+
88
+ def total_time_in_seconds
89
+ response["totalTimeInSeconds"]
90
+ end
91
+
92
+ private
93
+
94
+ # The search and find API calls populate different image attribute nodes in their respective responses. This method
95
+ # determines which one has been populated and returns a populated node for the images collection method to use. This
96
+ # allows the developer using this API to only use one method to access images.
97
+ def images_node
98
+ response["images"] || response["smallImageUrls"].collect { |url| { "hostedSmallUrl" => url } }
99
+ end
100
+
101
+ end
@@ -0,0 +1,19 @@
1
+ # Contains details about the origin of the recipe.
2
+ class Yummly::Source
3
+
4
+ # The original source url of this recipe.
5
+ attr_accessor :recipe_url
6
+
7
+ # The url of the source site of this recipe.
8
+ attr_accessor :site_url
9
+
10
+ # The display name of the source site.
11
+ attr_accessor :display_name
12
+
13
+ def initialize(values)
14
+ @recipe_url = values["sourceRecipeUrl"]
15
+ @site_url = values["sourceSiteUrl"]
16
+ @display_name= values["sourceDisplayName"]
17
+ end
18
+
19
+ end
@@ -0,0 +1,23 @@
1
+ # The implied unit of measure for a nutrition estimate.
2
+ class Yummly::Unit
3
+
4
+ # Single unit display name for unit of measure.
5
+ attr_accessor :name
6
+
7
+ # Single unit abbreviation for unit of measure.
8
+ attr_accessor :abbreviation
9
+
10
+ # Plural display name for unit of measure.
11
+ attr_accessor :plural
12
+
13
+ # Plural unit abbreviation for unit of measure.
14
+ attr_accessor :plural_abbreviation
15
+
16
+ def initialize(values)
17
+ @name = values["name"]
18
+ @abbreviation = values["abbreviation"]
19
+ @plural = values["plural"]
20
+ @plural_abbreviation = values["pluralAbbreviation"]
21
+ end
22
+
23
+ end
@@ -0,0 +1,3 @@
1
+ module Yummly
2
+ VERSION = "0.0.1"
3
+ end
data/lib/yummly.rb ADDED
@@ -0,0 +1,25 @@
1
+ require "yummly/api"
2
+ require "yummly/configuration"
3
+ require "yummly/flavor"
4
+ require "yummly/image"
5
+ require "yummly/nutrition_estimate"
6
+ require "yummly/recipe"
7
+ require "yummly/source"
8
+ require "yummly/unit"
9
+ require "yummly/version"
10
+
11
+ module Yummly
12
+
13
+ API_VERSION = 'v1'
14
+
15
+ class << self
16
+
17
+ attr_accessor :configuration
18
+
19
+ def configure
20
+ configuration = Yummly::Configuration.new
21
+ yield(configuration)
22
+ self.configuration = configuration
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ require "spec_helper"
2
+
3
+ describe Yummly::Configuration do
4
+ subject { Yummly::Configuration.new }
5
+
6
+ specify { subject.should respond_to(:app_key) }
7
+ specify { subject.should respond_to(:app_id) }
8
+
9
+ describe "#use_ssl?" do
10
+ specify { subject.use_ssl?.should be_false }
11
+
12
+ context "when set" do
13
+ before { subject.use_ssl = true }
14
+ specify { subject.use_ssl?.should be_true }
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,20 @@
1
+ require 'bundler/setup'
2
+ require 'yummly'
3
+
4
+ # This file was generated by the `rspec --init` command. Conventionally, all
5
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
6
+ # Require this file using `require "spec_helper"` to ensure that it is only
7
+ # loaded once.
8
+ #
9
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
10
+ RSpec.configure do |config|
11
+ config.treat_symbols_as_metadata_keys_with_true_values = true
12
+ config.run_all_when_everything_filtered = true
13
+ config.filter_run :focus
14
+
15
+ # Run specs in random order to surface order dependencies. If you find an
16
+ # order dependency and want to debug it, you can fix the order by providing
17
+ # the seed, which is printed after each run.
18
+ # --seed 1234
19
+ config.order = 'random'
20
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe Yummly do
4
+ subject { Yummly::Configuration.new }
5
+
6
+ describe ".configure" do
7
+
8
+ let(:app_id) { "12345" }
9
+ let(:app_key) { "XEARSGSTH12345789" }
10
+
11
+ before do
12
+ Yummly.configure do |config|
13
+ config.use_ssl = true
14
+ config.app_id = app_id
15
+ config.app_key = app_key
16
+ end
17
+ end
18
+
19
+ specify { Yummly.configuration.use_ssl?.should be_true }
20
+ specify { Yummly.configuration.app_id.should == app_id }
21
+ specify { Yummly.configuration.app_key.should == app_key }
22
+ end
23
+
24
+ end
data/yummly.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'yummly/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "yummly"
8
+ gem.version = Yummly::VERSION
9
+ gem.authors = ["Theo Mills"]
10
+ gem.email = ["twmills@twmills.com"]
11
+ gem.description = %q{Ruby wrapper to the Yummly API}
12
+ gem.summary = %q{Ruby wrapper to the Yummly API}
13
+ gem.homepage = "https://github.com/twmills/yummly"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ gem.add_dependency('faraday', '>= 0.8.7')
20
+ gem.add_development_dependency "rspec"
21
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: yummly
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Theo Mills
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.8.7
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.8.7
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Ruby wrapper to the Yummly API
47
+ email:
48
+ - twmills@twmills.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - .rspec
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - lib/yummly.rb
60
+ - lib/yummly/api.rb
61
+ - lib/yummly/configuration.rb
62
+ - lib/yummly/connection.rb
63
+ - lib/yummly/flavor.rb
64
+ - lib/yummly/image.rb
65
+ - lib/yummly/nutrition_estimate.rb
66
+ - lib/yummly/recipe.rb
67
+ - lib/yummly/source.rb
68
+ - lib/yummly/unit.rb
69
+ - lib/yummly/version.rb
70
+ - spec/configuration_spec.rb
71
+ - spec/spec_helper.rb
72
+ - spec/yummly_spec.rb
73
+ - yummly.gemspec
74
+ homepage: https://github.com/twmills/yummly
75
+ licenses: []
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 1.8.25
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: Ruby wrapper to the Yummly API
98
+ test_files:
99
+ - spec/configuration_spec.rb
100
+ - spec/spec_helper.rb
101
+ - spec/yummly_spec.rb