yummly 0.0.1

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 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