yelp 1.0.0 → 2.0.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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -504
- data/README.md +152 -0
- data/Rakefile +4 -24
- data/lib/yelp.rb +18 -13
- data/lib/yelp/burst_struct.rb +51 -0
- data/lib/yelp/client.rb +86 -86
- data/lib/yelp/configuration.rb +31 -0
- data/lib/yelp/endpoint/business.rb +42 -0
- data/lib/yelp/endpoint/search.rb +170 -0
- data/lib/yelp/error.rb +55 -0
- data/lib/yelp/version.rb +3 -0
- data/spec/fixtures/vcr_cassettes/business.yml +73 -0
- data/spec/fixtures/vcr_cassettes/search.yml +361 -0
- data/spec/fixtures/vcr_cassettes/search_bounding_box.yml +359 -0
- data/spec/fixtures/vcr_cassettes/search_by_coordinates.yml +387 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/request_error.rb +11 -0
- data/spec/support/shared_configuration.rb +11 -0
- data/spec/yelp/burst_struct_spec.rb +124 -0
- data/spec/yelp/client_spec.rb +75 -0
- data/spec/yelp/configuration_spec.rb +44 -0
- data/spec/yelp/endpoint/business_spec.rb +26 -0
- data/spec/yelp/endpoint/search_spec.rb +72 -0
- data/spec/yelp/error_spec.rb +22 -0
- data/spec/yelp/yelp_spec.rb +10 -0
- data/tasks/console.rake +4 -0
- data/yelp.gemspec +32 -0
- metadata +252 -90
- data/CHANGELOG.rdoc +0 -48
- data/Manifest.txt +0 -24
- data/README.rdoc +0 -118
- data/TODO.txt +0 -6
- data/lib/yelp/neighborhood/request/base.rb +0 -13
- data/lib/yelp/neighborhood/request/geo_point.rb +0 -23
- data/lib/yelp/neighborhood/request/location.rb +0 -53
- data/lib/yelp/phone/request/number.rb +0 -24
- data/lib/yelp/record.rb +0 -16
- data/lib/yelp/request.rb +0 -44
- data/lib/yelp/response_format.rb +0 -36
- data/lib/yelp/review/request/base.rb +0 -31
- data/lib/yelp/review/request/bounding_box.rb +0 -37
- data/lib/yelp/review/request/geo_point.rb +0 -28
- data/lib/yelp/review/request/location.rb +0 -63
- data/test/test_client.rb +0 -11
- data/test/test_neighborhood_search.rb +0 -46
- data/test/test_phone_search.rb +0 -20
- data/test/test_review_search.rb +0 -168
- data/test/yelp_helper.rb +0 -45
data/README.md
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# yelp-ruby
|
2
|
+
|
3
|
+
This is a Ruby Gem for the Yelp API. It'll simplifies the process of consuming data from the Yelp API for developers using Ruby. The library encompasses both Search and Business API functions.
|
4
|
+
|
5
|
+
Please remember to read and follow the [Terms of Use](http://www.yelp.com/developers/getting_started/api_terms) and [display requirements](http://www.yelp.com/developers/getting_started/display_requirements) before creating your applications.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'yelp', require: 'yelp'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install yelp
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### Basic usage
|
24
|
+
|
25
|
+
The gem uses a client model to query against the API. You create and configure a client with your API keys and make requests through that.
|
26
|
+
|
27
|
+
```
|
28
|
+
require 'yelp'
|
29
|
+
|
30
|
+
client = Yelp::Client.new({ consumer_key: YOUR_CONSUMER_KEY,
|
31
|
+
consumer_secret: YOUR_CONSUMER_SECRET,
|
32
|
+
token: YOUR_TOKEN,
|
33
|
+
token_secret: YOUR_TOKEN_SECRET
|
34
|
+
})
|
35
|
+
```
|
36
|
+
|
37
|
+
Alternatively, you can also globally configure the client using a configure
|
38
|
+
block, and access a client singleton using `Yelp.client`. If you intend to
|
39
|
+
use the gem with Rails, the client should be configured in an initializer.
|
40
|
+
|
41
|
+
```
|
42
|
+
require 'yelp'
|
43
|
+
|
44
|
+
Yelp.client.configure do |config|
|
45
|
+
config.consumer_key = YOUR_CONSUMER_KEY
|
46
|
+
config.consumer_secret = YOUR_CONSUMER_SECRET
|
47
|
+
config.token = YOUR_TOKEN
|
48
|
+
config.token_secret = YOUR_TOKEN_SECRET
|
49
|
+
end
|
50
|
+
|
51
|
+
Yelp.client.search('San Francisco', { term: 'food' })
|
52
|
+
```
|
53
|
+
|
54
|
+
After creating the client you're able to make requests to either the Search API or Business API. Note: all four keys are required for making requests against the Yelp API. If you need any keys sign up and get access from [http://www.yelp.com/developers](http://www.yelp.com/developers).
|
55
|
+
|
56
|
+
### [Search API](http://www.yelp.com/developers/documentation/v2/search_api)
|
57
|
+
|
58
|
+
Once you have a client you can use ``#search`` to make a request to the Search API.
|
59
|
+
|
60
|
+
```
|
61
|
+
client.search('San Francisco')
|
62
|
+
```
|
63
|
+
|
64
|
+
You can also pass in general params and locale options to the method as hashes
|
65
|
+
|
66
|
+
```
|
67
|
+
params = { term: 'food',
|
68
|
+
limit: 3,
|
69
|
+
category_filter: 'discgolf'
|
70
|
+
}
|
71
|
+
|
72
|
+
locale = { lang: 'fr' }
|
73
|
+
|
74
|
+
client.search('San Francisco', params, locale)
|
75
|
+
```
|
76
|
+
|
77
|
+
Key names and options for params and locale match the documented names on the [Yelp Search API](http://www.yelp.com/developers/documentation/v2/search_api)
|
78
|
+
|
79
|
+
Additionally there are two more search methods for searching by a [bounding box](http://www.yelp.com/developers/documentation/v2/search_api#searchGBB) or for [geographical coordinates](http://www.yelp.com/developers/documentation/v2/search_api#searchGC):
|
80
|
+
|
81
|
+
```
|
82
|
+
# bounding box
|
83
|
+
bounding_box = { sw_latitude: 37.7577, sw_longitude: -122.4376, ne_latitude: 37.785381, ne_longitude: -122.391681 }
|
84
|
+
client.search_by_bounding_box(bounding_box, params, locale)
|
85
|
+
|
86
|
+
# coordinates
|
87
|
+
coordinates = { latitude: 37.7577, longitude: -122.4376 }
|
88
|
+
client.search_by_coordinates(coordinates, params, locale)
|
89
|
+
```
|
90
|
+
|
91
|
+
### [Business API](http://www.yelp.com/developers/documentation/v2/business)
|
92
|
+
|
93
|
+
To use the Business API after you have a client you just need to call ``#business`` with a business id
|
94
|
+
|
95
|
+
```
|
96
|
+
client.business('yelp-san-francisco')
|
97
|
+
```
|
98
|
+
|
99
|
+
You can pass in locale information as well
|
100
|
+
|
101
|
+
```
|
102
|
+
locale = { lang: 'fr' }
|
103
|
+
|
104
|
+
client.business('yelp-san-francisco', locale)
|
105
|
+
```
|
106
|
+
|
107
|
+
## Responses
|
108
|
+
|
109
|
+
Responses from the API are all parsed and converted into Ruby objects. You're able to access information using dot-notation
|
110
|
+
|
111
|
+
```
|
112
|
+
## search
|
113
|
+
response = client.search('San Francisco')
|
114
|
+
|
115
|
+
response.businesses
|
116
|
+
# [<Business 1>, <Business 2>, ...]
|
117
|
+
|
118
|
+
response.businesses[0].name
|
119
|
+
# "Kim Makoi, DC"
|
120
|
+
|
121
|
+
response.businesses[0].rating
|
122
|
+
# 5.0
|
123
|
+
|
124
|
+
|
125
|
+
## business
|
126
|
+
response = client.business('yelp-san-francisco')
|
127
|
+
|
128
|
+
response.name
|
129
|
+
# Yelp
|
130
|
+
|
131
|
+
response.categories
|
132
|
+
# [["Local Flavor", "localflavor"], ["Mass Media", "massmedia"]]
|
133
|
+
```
|
134
|
+
|
135
|
+
For specific response values check out the docs for the [search api](http://www.yelp.com/developers/documentation/v2/search_api#rValue) and the [business api](http://www.yelp.com/developers/documentation/v2/business#rValue)
|
136
|
+
|
137
|
+
## Contributing
|
138
|
+
|
139
|
+
1. Fork it ( http://github.com/yelp/yelp-ruby/fork )
|
140
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
141
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
142
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
143
|
+
5. Create new Pull Request
|
144
|
+
|
145
|
+
### Git Workflow
|
146
|
+
|
147
|
+
We are using the [git flow](http://nvie.com/posts/a-successful-git-branching-model/)
|
148
|
+
workflow. Atlassian has a [solid overview](https://www.atlassian.com/git/workflows#!workflow-gitflow).
|
149
|
+
Essentially, new development is merged into the develop branch from feature
|
150
|
+
branches, then merged from develop to a release branch, then to master from
|
151
|
+
the release branch. Master should always contain the most recently released
|
152
|
+
version of the gem.
|
data/Rakefile
CHANGED
@@ -1,25 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require 'hoe'
|
3
|
-
$:.unshift(File.dirname(__FILE__) + "/lib")
|
4
|
-
require 'yelp'
|
1
|
+
require "bundler/gem_tasks"
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
self.author = 'Walter Korman'
|
10
|
-
self.email = 'shaper@fatgoose.com'
|
11
|
-
self.extra_deps << [ 'json', '>= 1.1.1' ]
|
12
|
-
self.summary = 'An object-oriented interface to the Yelp Developer API.'
|
13
|
-
self.description = <<EDOC
|
14
|
-
The yelp rubygem provides a Ruby object-oriented interface to the Yelp
|
15
|
-
REST API described in detail at:
|
16
|
-
|
17
|
-
http://www.yelp.com/developers/getting_started
|
18
|
-
EDOC
|
19
|
-
self.url = 'http://rubyforge.org/projects/yelp'
|
20
|
-
self.changes = p.paragraphs_of('CHANGELOG.rdoc', 0..1).join("\n\n")
|
21
|
-
self.remote_rdoc_dir = '' # Release to root
|
22
|
-
self.readme_file = 'README.rdoc'
|
23
|
-
self.history_file = 'CHANGELOG.rdoc'
|
24
|
-
self.extra_rdoc_files = [ 'CHANGELOG.rdoc', 'README.rdoc' ]
|
25
|
-
end
|
3
|
+
Dir["tasks/**/*.rake"].each do |file|
|
4
|
+
load(file)
|
5
|
+
end
|
data/lib/yelp.rb
CHANGED
@@ -1,16 +1,21 @@
|
|
1
|
+
require 'yelp/version'
|
1
2
|
require 'yelp/client'
|
2
|
-
require 'yelp/record'
|
3
|
-
require 'yelp/request'
|
4
|
-
require 'yelp/response_format'
|
5
|
-
require 'yelp/neighborhood/request/base'
|
6
|
-
require 'yelp/neighborhood/request/geo_point'
|
7
|
-
require 'yelp/neighborhood/request/location'
|
8
|
-
require 'yelp/phone/request/number'
|
9
|
-
require 'yelp/review/request/base'
|
10
|
-
require 'yelp/review/request/bounding_box'
|
11
|
-
require 'yelp/review/request/geo_point'
|
12
|
-
require 'yelp/review/request/location'
|
13
3
|
|
14
|
-
|
15
|
-
|
4
|
+
module Yelp
|
5
|
+
# Returns an initially-unconfigured instance of the client.
|
6
|
+
# @return [Client] an instance of the client
|
7
|
+
#
|
8
|
+
# @example Configuring and using the client
|
9
|
+
# Yelp.client.configure do |config|
|
10
|
+
# config.consumer_key = 'abc'
|
11
|
+
# config.consumer_secret = 'def'
|
12
|
+
# config.token = 'ghi'
|
13
|
+
# config.token_secret = 'jkl'
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# Yelp.client.search('San Francisco', { term: 'food' })
|
17
|
+
#
|
18
|
+
def self.client
|
19
|
+
@client ||= Yelp::Client.new
|
20
|
+
end
|
16
21
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module BurstStruct
|
2
|
+
class Burst
|
3
|
+
def initialize(hash = {})
|
4
|
+
@hash = hash
|
5
|
+
end
|
6
|
+
|
7
|
+
def method_missing(method_name, *arguments, &block)
|
8
|
+
key = find_key(method_name)
|
9
|
+
|
10
|
+
if key
|
11
|
+
return_or_build_struct(key)
|
12
|
+
else
|
13
|
+
super
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def respond_to?(method_name, include_private = false)
|
18
|
+
@hash.keys.include?(method_name) || super
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.convert_array(array)
|
22
|
+
array.map do |item|
|
23
|
+
case item
|
24
|
+
when Hash
|
25
|
+
Burst.new(item)
|
26
|
+
when Array
|
27
|
+
Burst.convert_array(item)
|
28
|
+
else
|
29
|
+
item
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_json(options = {})
|
35
|
+
JSON.generate(@hash)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def return_or_build_struct(method_name)
|
41
|
+
return Burst.new(@hash[method_name]) if @hash[method_name].is_a?(Hash)
|
42
|
+
return Burst.convert_array(@hash[method_name]) if @hash[method_name].is_a?(Array)
|
43
|
+
@hash[method_name]
|
44
|
+
end
|
45
|
+
|
46
|
+
def find_key(method_name)
|
47
|
+
return method_name.to_sym if @hash.keys.include? method_name.to_sym
|
48
|
+
return method_name.to_s if @hash.keys.include? method_name.to_s
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/yelp/client.rb
CHANGED
@@ -1,105 +1,105 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require 'open-uri'
|
4
|
-
require 'rubygems'
|
5
|
-
require 'json'
|
6
|
-
require 'yaml'
|
7
|
-
require 'zlib'
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
8
3
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
# client = Yelp::Client.new
|
17
|
-
# request = Yelp::Review::Request::Location.new(
|
18
|
-
# :address => '650 Mission St',
|
19
|
-
# :city => 'San Francisco',
|
20
|
-
# :state => 'CA',
|
21
|
-
# :radius => 2,
|
22
|
-
# :term => 'cream puffs',
|
23
|
-
# :yws_id => 'YOUR_YWSID_HERE')
|
24
|
-
# response = client.search(request)
|
25
|
-
#
|
26
|
-
# By default, response content is formatted as a Ruby hash converted from
|
27
|
-
# Yelp's source JSON response content. Alternate response formats can be
|
28
|
-
# specified on request record construction via the Yelp::Request
|
29
|
-
# +response_format+ parameter, available in all request record types.
|
30
|
-
#
|
4
|
+
require 'yelp/burst_struct'
|
5
|
+
require 'yelp/configuration'
|
6
|
+
require 'yelp/error'
|
7
|
+
require 'yelp/endpoint/business'
|
8
|
+
require 'yelp/endpoint/search'
|
9
|
+
|
10
|
+
module Yelp
|
31
11
|
class Client
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
#
|
39
|
-
#
|
40
|
-
|
12
|
+
API_HOST = 'http://api.yelp.com'
|
13
|
+
REQUEST_CLASSES = [ Yelp::Endpoint::Search,
|
14
|
+
Yelp::Endpoint::Business ]
|
15
|
+
|
16
|
+
attr_reader :configuration
|
17
|
+
|
18
|
+
# Creates an instance of the Yelp client
|
19
|
+
# @param options [Hash, nil] a hash of the consumer key, consumer
|
20
|
+
# secret, token, and token secret
|
21
|
+
# @return [Client] a new client initialized with the keys
|
22
|
+
def initialize(options = nil)
|
23
|
+
@configuration = nil
|
24
|
+
define_request_methods
|
25
|
+
|
26
|
+
unless options.nil?
|
27
|
+
@configuration = Configuration.new(options)
|
28
|
+
check_api_keys
|
29
|
+
end
|
30
|
+
end
|
41
31
|
|
42
|
-
# the
|
43
|
-
|
32
|
+
# Configure the API client
|
33
|
+
# @yield [Configuration] a configuration object
|
34
|
+
# @raise [MissingAPIKeys] if the configuration is invalid
|
35
|
+
# @example Simple configuration
|
36
|
+
# Yelp.client.configure do |config|
|
37
|
+
# config.consumer_key = 'abc'
|
38
|
+
# config.consumer_secret = 'def'
|
39
|
+
# config.token = 'ghi'
|
40
|
+
# config.token_secret = 'jkl'
|
41
|
+
# end
|
42
|
+
def configure
|
43
|
+
raise AlreadyConfigured unless @configuration.nil?
|
44
44
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
def initialize
|
49
|
-
@agent = DEFAULT_AGENT
|
50
|
-
@debug = false
|
51
|
-
@logger = nil
|
45
|
+
@configuration = Configuration.new
|
46
|
+
yield(@configuration)
|
47
|
+
check_api_keys
|
52
48
|
end
|
53
|
-
|
54
|
-
# Submits the supplied search request to Yelp and returns the response in
|
55
|
-
# the format specified by the request.
|
56
|
-
#
|
57
|
-
def search (request)
|
58
|
-
# build the full set of hash params with which the url is constructed
|
59
|
-
params = request.to_yelp_params
|
60
49
|
|
61
|
-
|
62
|
-
|
63
|
-
|
50
|
+
# Checks that all the keys needed were given
|
51
|
+
def check_api_keys
|
52
|
+
if configuration.nil? || !configuration.valid?
|
53
|
+
@configuration = nil
|
54
|
+
raise MissingAPIKeys
|
55
|
+
else
|
56
|
+
# Freeze the configuration so it cannot be modified once the gem is
|
57
|
+
# configured. This prevents the configuration changing while the gem
|
58
|
+
# is operating, which would necessitate invalidating various caches.
|
59
|
+
@configuration.freeze
|
60
|
+
end
|
61
|
+
end
|
64
62
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
source = open(url, http_params)
|
63
|
+
# API connection
|
64
|
+
def connection
|
65
|
+
return @connection if instance_variable_defined?(:@connection)
|
69
66
|
|
70
|
-
|
71
|
-
|
72
|
-
|
67
|
+
check_api_keys
|
68
|
+
@connection = Faraday.new(API_HOST) do |conn|
|
69
|
+
# Use the Faraday OAuth middleware for OAuth 1.0 requests
|
70
|
+
conn.request :oauth, @configuration.auth_keys
|
73
71
|
|
74
|
-
|
75
|
-
|
72
|
+
# Using default http library, had to specify to get working
|
73
|
+
conn.adapter :net_http
|
74
|
+
end
|
76
75
|
end
|
77
76
|
|
78
|
-
|
77
|
+
private
|
79
78
|
|
80
|
-
|
81
|
-
|
79
|
+
# This goes through each endpoint class and creates singletone methods
|
80
|
+
# on the client that query those classes. We do this to avoid possible
|
81
|
+
# namespace collisions in the future when adding new classes
|
82
|
+
def define_request_methods
|
83
|
+
REQUEST_CLASSES.each do |request_class|
|
84
|
+
endpoint_instance = request_class.new(self)
|
85
|
+
create_methods_from_instance(endpoint_instance)
|
82
86
|
end
|
87
|
+
end
|
83
88
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
89
|
+
# Loop through all of the endpoint instances' public singleton methods to
|
90
|
+
# add the method to client
|
91
|
+
def create_methods_from_instance(instance)
|
92
|
+
instance.public_methods(false).each do |method_name|
|
93
|
+
add_method(instance, method_name)
|
88
94
|
end
|
95
|
+
end
|
89
96
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
next if value.nil?
|
96
|
-
url << '&' if (param_count > 0)
|
97
|
-
key_str = (params[key].kind_of?(Array)) ?
|
98
|
-
params[key].map { |k| CGI.escape(k.to_s) }.join("+") : CGI.escape(params[key].to_s)
|
99
|
-
url << "#{CGI.escape(key.to_s)}=#{key_str}"
|
100
|
-
param_count += 1
|
101
|
-
end
|
102
|
-
url
|
97
|
+
# Define the method on the client and send it to the endpoint instance
|
98
|
+
# with the args passed in
|
99
|
+
def add_method(instance, method_name)
|
100
|
+
define_singleton_method(method_name) do |*args|
|
101
|
+
instance.public_send(method_name, *args)
|
103
102
|
end
|
103
|
+
end
|
104
104
|
end
|
105
105
|
end
|