yelp 0.1.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/Manifest.txt ADDED
@@ -0,0 +1,24 @@
1
+ History.txt
2
+ LICENSE.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ TODO.txt
7
+ lib/yelp.rb
8
+ lib/yelp/client.rb
9
+ lib/yelp/record.rb
10
+ lib/yelp/response_format.rb
11
+ lib/yelp/request.rb
12
+ lib/yelp/neighborhood/request/base.rb
13
+ lib/yelp/neighborhood/request/geo_point.rb
14
+ lib/yelp/neighborhood/request/location.rb
15
+ lib/yelp/phone/request/number.rb
16
+ lib/yelp/review/request/base.rb
17
+ lib/yelp/review/request/bounding_box.rb
18
+ lib/yelp/review/request/geo_point.rb
19
+ lib/yelp/review/request/location.rb
20
+ test/test_client.rb
21
+ test/test_neighborhood_search.rb
22
+ test/test_phone_search.rb
23
+ test/test_review_search.rb
24
+ test/yelp_helper.rb
data/README.txt ADDED
@@ -0,0 +1,108 @@
1
+ = yelp
2
+
3
+ A Ruby object-oriented interface to the local business content available
4
+ on Yelp at http://www.yelp.com. Functionality is provided to perform
5
+ all searches available via the developer API including:
6
+
7
+ * search for business reviews by geo-bounding-box, geo-point, or address/location.
8
+ * search for a business review by business phone number.
9
+ * search for a neighborhood by geo-point or address/location.
10
+
11
+ More detailed information on the underlying Yelp API, error response codes, and so forth is available at http://www.yelp.com/developers/getting_started.
12
+
13
+ The RubyForge project is hosted at http://rubyforge.org/projects/yelp. This documentation is available at http://yelp.rubyforge.org.
14
+
15
+ == About
16
+
17
+ Everybody loves Yelp! For those seeking burritos in the Mission District of
18
+ San Francisco, it's easy to feel awash in a sea of taquerias with little to go
19
+ on for decision-making other than whether the rice has peas in it (generally a
20
+ negatory data point) or how long the line happens to be around lunchtime.
21
+
22
+ Worry no longer! Yelp is here.
23
+
24
+ Why should you use this library rather than writing directly to their API, or rolling your own? A few reasons that come to mind:
25
+
26
+ * we've done a variety of mini-legwork from which you, Yelp and our fellow netizens will benefit, such as making sure we inform the Yelp server that we support gzipped data over the wire to save on bandwidth.
27
+ * we have rudimentary tests, whereas your implementation doesn't (since you haven't even written it yet).
28
+ * we return responses (by default, configurable) as JSON data converted into a Ruby hash and appropriate data types where applicable.
29
+ * (subjective but we know we're right) -- we think our API is a nicer layer for Ruby developers to work with than the bare-bones REST API that Yelp provides.
30
+
31
+ == Requirements
32
+
33
+ You must have a Yelp Web Service ID (YWSID) available at http://www.yelp.com/developers/getting_started/api_access.
34
+
35
+ You must conform to the Yelp Branding Requirements when making use of content
36
+ retrieved via their API, documented at http://www.yelp.com/developers/getting_started/api_branding.
37
+
38
+ For tests to execute successfully you must have the YWSID set in your
39
+ environment via (shell-dependent, bash example provided):
40
+
41
+ % export YWSID='YOUR_ID_HERE'
42
+
43
+ == Installing
44
+
45
+ We recommend installing <tt>yelp</tt> via rubygems[http://rubyforge.org/projects/rubygems/] (see also http://www.rubygems.org).
46
+
47
+ Once you have +rubygems+ installed on your system, you can easily install the <tt>yelp</tt> gem by executing:
48
+
49
+ % gem install --include-dependencies yelp
50
+
51
+ == Usage
52
+
53
+ Instantiate a Yelp::Client and use its +search+ method to make requests of
54
+ the Yelp server.
55
+
56
+ The available search request types are:
57
+
58
+ * Yelp::Review::Request::BoundingBox
59
+ * Yelp::Review::Request::GeoPoint
60
+ * Yelp::Review::Request::Location
61
+ * Yelp::Phone::Request::Number
62
+ * Yelp::Neighborhood::Request::GeoPoint
63
+ * Yelp::Neighborhood::Request::Location
64
+
65
+ By default, response content is formatted as a Ruby hash converted from Yelp's
66
+ source JSON response content. Alternate response formats (including the
67
+ original pure JSON) can be specified on request record construction via the
68
+ Yelp::Request +response_format+ parameter, available in all request record
69
+ types.
70
+
71
+ A few examples:
72
+
73
+ # construct a client instance
74
+ client = Yelp::Client.new
75
+
76
+ # perform an address/location-based search for cream puffs nearby
77
+ request = Yelp::Review::Request::Location.new(
78
+ :address => '650 Mission St',
79
+ :city => 'San Francisco',
80
+ :state => 'CA',
81
+ :radius => 2,
82
+ :term => 'cream puffs',
83
+ :yws_id => 'YOUR_YWSID_HERE')
84
+ response = client.search(request)
85
+
86
+ # perform a neighborhood name lookup for a specific geo-location point
87
+ request = Yelp::Neighborhood::Request::GeoPoint.new(
88
+ :latitude => 37.782093,
89
+ :longitude => -122.483230,
90
+ :yws_id => 'YOUR_YWSID_HERE')
91
+ response = client.search(request)
92
+
93
+ # perform a business review search based on a business phone number
94
+ request = Yelp::Phone::Request::Number.new(
95
+ :phone_number => '4155551212',
96
+ :yws_id => 'YOUR_YWSID_HERE')
97
+ response = client.search(request)
98
+
99
+ If you want to convert some addresses to latitude/longitude, or vice
100
+ versa, for testing or what have you -- try http://stevemorse.org/jcal/latlon.php.
101
+
102
+ == License
103
+
104
+ This library is provided via the GNU LGPL license at http://www.gnu.org/licenses/lgpl.html.
105
+
106
+ == Authors
107
+
108
+ Copyright 2007, Walter Korman <shaper@wgks.org>, http://lemurware.blogspot.com
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ $:.unshift(File.dirname(__FILE__) + "/lib")
4
+ require 'yelp'
5
+
6
+ Hoe.new('yelp', Yelp::VERSION) do |p|
7
+ p.rubyforge_name = 'yelp'
8
+ p.author = 'Walter Korman'
9
+ p.email = 'shaper@wgks.org'
10
+ p.extra_deps = [ 'json', '>= 1.1.1' ]
11
+ p.summary = 'An object-oriented interface to the Yelp Developer API.'
12
+ p.description = 'An object-oriented interface to the Yelp Developer API.'
13
+ p.url = 'http://www.samskivert.com/shaper/yelp'
14
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
15
+ p.remote_rdoc_dir = '' # Release to root
16
+ # p.spec_extras = { :rdoc_options => '--main' << 'README' }
17
+ end
data/TODO.txt ADDED
@@ -0,0 +1,6 @@
1
+ * look into rails partials inability to properly enumerate the response
2
+ business records with the :collection param.
3
+ * think about how to gracefully report errors
4
+ * should we use "require 'json/add/rails'" for json for rails happiness?
5
+ * use SAX-based XML parsing rather than DOM
6
+ * consider supporting keep-alive for high volume requests
data/lib/yelp.rb ADDED
@@ -0,0 +1,16 @@
1
+ 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
+
14
+ class Yelp
15
+ VERSION = '0.1.1'
16
+ end
@@ -0,0 +1,103 @@
1
+ require 'cgi'
2
+ require 'logger'
3
+ require 'open-uri'
4
+ require 'rubygems'
5
+ require 'json'
6
+ require 'yaml'
7
+ require 'zlib'
8
+
9
+ class Yelp
10
+ # Provides access to the Yelp search facilities as documented at:
11
+ #
12
+ # http://www.yelp.com/developers/documentation
13
+ #
14
+ # Example usage:
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
+ #
31
+ class Client
32
+ # allows specifying the user agent string to submit with search requests
33
+ attr_accessor :agent
34
+
35
+ # whether debug mode is enabled for logging purposes, defaulting to false
36
+ attr_accessor :debug
37
+
38
+ # the Logger compatible object with which log messages are outputted,
39
+ # defaulting to output to STDOUT
40
+ attr_accessor :logger
41
+
42
+ # the default user agent submitted with search requests
43
+ DEFAULT_AGENT = 'yelp for Ruby (http://www.rubyforge.org/projects/yelp/)'
44
+
45
+ # Constructs a new client that uses the supplied YWSID for submitting
46
+ # search requests.
47
+ #
48
+ def initialize
49
+ @agent = DEFAULT_AGENT
50
+ @debug = false
51
+ @logger = nil
52
+ 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
+
61
+ # construct the url with which we obtain results
62
+ url = build_url(request.base_url, params)
63
+ debug_msg "submitting search [url=#{url}, request=#{request.to_yaml}]."
64
+
65
+ # submit the http request for the results
66
+ http_params = { 'User-Agent' => @agent }
67
+ http_params['Accept-Encoding'] = 'gzip,deflate' if request.compress_response?
68
+ source = open(url, http_params)
69
+
70
+ # read the response content
71
+ content = (request.compress_response?) ? Zlib::GzipReader.new(source).read : source.read
72
+ debug_msg((request.response_format.serialized?) ? "received response [content_length=#{content.length}]." : "received response [content_length=#{content.length}, content=#{content}].")
73
+
74
+ # format the output as specified in the request
75
+ format_content(request.response_format, content)
76
+ end
77
+
78
+ protected
79
+
80
+ def format_content (response_format, content)
81
+ (response_format == Yelp::ResponseFormat::JSON_TO_RUBY) ? JSON.parse(content) : content
82
+ end
83
+
84
+ def debug_msg (message)
85
+ return if !@debug
86
+ @logger = Logger.new(STDOUT) if (!@logger)
87
+ @logger.debug message
88
+ end
89
+
90
+ def build_url (base_url, params)
91
+ url = base_url.clone
92
+ url << '?'
93
+ param_count = 0
94
+ params.each do |key, value|
95
+ next if value.nil?
96
+ url << '&' if (param_count > 0)
97
+ url << "#{key}=#{CGI.escape(params[key].to_s)}"
98
+ param_count += 1
99
+ end
100
+ url
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,13 @@
1
+ require 'yelp/request'
2
+
3
+ class Yelp
4
+ module Neighborhood
5
+ module Request
6
+ class Base < Yelp::Request
7
+ def base_url
8
+ 'http://api.yelp.com/neighborhood_search'
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ require 'yelp/neighborhood/request/base'
2
+
3
+ class Yelp
4
+ module Neighborhood
5
+ module Request
6
+ # Describes a request to search for the name of a neighborhood at a
7
+ # specific geo-point location.
8
+ #
9
+ class GeoPoint < Yelp::Neighborhood::Request::Base
10
+ # latitude of geo-point for which a neighborhood name is desired
11
+ attr_reader :latitude
12
+
13
+ # longitude of geo-point for which a neighborhood name is desired
14
+ attr_reader :longitude
15
+
16
+ def to_yelp_params
17
+ super.merge(:lat => latitude,
18
+ :long => longitude)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,53 @@
1
+ require 'yelp/neighborhood/request/base'
2
+
3
+ class Yelp
4
+ module Neighborhood
5
+ module Request
6
+ # Describes a request to search for a neighborhood name for a specific
7
+ # address/location. You do not need to specify all of the address
8
+ # attributes -- some subset of the core +address+, +city+,
9
+ # +state+ and +zipcode+ will suffice.
10
+ #
11
+ class Location < Yelp::Neighborhood::Request::Base
12
+ # the street address of the location sought
13
+ attr_reader :address
14
+
15
+ # the city of the location sought
16
+ attr_reader :city
17
+
18
+ # the state of the location sought
19
+ attr_reader :state
20
+
21
+ # the zipcode of the location sought
22
+ attr_reader :zipcode
23
+
24
+ def initialize (params)
25
+ # we explicitly initialize the location fields since we reference
26
+ # them later when building a full location string and we want
27
+ # to know they were initialized properly (and avoid warnings)
28
+ super({
29
+ :address => nil,
30
+ :city => nil,
31
+ :state => nil,
32
+ :zipcode => nil
33
+ }.merge(params))
34
+ end
35
+
36
+ def to_yelp_params
37
+ super.merge(:location => build_location_string)
38
+ end
39
+
40
+ protected
41
+
42
+ # Returns the Yelp-compatible concatenated string with the various
43
+ # possible bits of an address-oriented location.
44
+ #
45
+ def build_location_string
46
+ # per the Yelp documentation, the location string is to be built
47
+ # as some combination of "address, city, state, or zip".
48
+ [ @address, @city, @state, @zipcode ].compact.join(" ")
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,24 @@
1
+ require 'yelp/request'
2
+
3
+ class Yelp
4
+ module Phone
5
+ module Request
6
+ # Describes a request to search for a business review for the business
7
+ # associated with a specific phone number.
8
+ #
9
+ class Number < Yelp::Request
10
+ # the phone number of the business to search for, formatted as
11
+ # '1112223333'. Make sure you don't have any hyphens or parentheses.
12
+ attr_reader :phone_number
13
+
14
+ def base_url
15
+ 'http://api.yelp.com/phone_search'
16
+ end
17
+
18
+ def to_yelp_params
19
+ super.merge(:phone => phone_number)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ class Yelp
2
+ # General-purpose record that allows passing a hash with parameters
3
+ # to populate object attributes defined via methods like
4
+ # +attr_reader+ or +attr_accessor+.
5
+ #
6
+ class Record
7
+ def initialize (params)
8
+ if !params.nil?
9
+ params.each do |key, value|
10
+ name = key.to_s
11
+ instance_variable_set("@#{name}", value) if respond_to?(name)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,44 @@
1
+ require 'yelp/record'
2
+
3
+ class Yelp
4
+ class Request < Yelp::Record
5
+ # specifies whether the response content should be transmitted
6
+ # over the wire compressed, defaulting to true.
7
+ attr_reader :compress_response
8
+
9
+ # one of the Yelp::ResponseFormat format specifiers detailing the
10
+ # desired format of the search results, defaulting to
11
+ # Yelp::ResponseFormat::JSON_TO_RUBY.
12
+ attr_reader :response_format
13
+
14
+ # the Yelp Web Services ID to be passed with the request for
15
+ # authentication purposes. See http://www.yelp.com/developers/getting_started/api_access
16
+ # to get your own.
17
+ attr_reader :yws_id
18
+
19
+ alias :compress_response? :compress_response
20
+
21
+ def initialize (params)
22
+ default_params = {
23
+ :compress_response => true,
24
+ :response_format => Yelp::ResponseFormat::JSON_TO_RUBY
25
+ }
26
+ super(default_params.merge(params))
27
+ end
28
+
29
+ def to_yelp_params
30
+ params = {
31
+ :ywsid => yws_id
32
+ }
33
+
34
+ # if they specified anything other than a json variant, we
35
+ # need to tell yelp what we're looking for
36
+ case @response_format
37
+ when Yelp::ResponseFormat::PICKLE: params[:output] = 'pickle'
38
+ when Yelp::ResponseFormat::PHP: params[:output] = 'php'
39
+ end
40
+
41
+ params
42
+ end
43
+ end
44
+ end