zomato 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ .redcar
2
+ Gemfile.lock
3
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source :rubygems
2
+ gem 'httparty'
3
+ gem 'fakeweb'
4
+ gem 'rspec'
5
+
6
+
@@ -0,0 +1,22 @@
1
+ == extended_attributes
2
+
3
+ Copyright (c) 2011 Chirantan Rajhans.
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.
@@ -0,0 +1,59 @@
1
+ # Zomato
2
+ _Ruby gem that wraps [Zomato API](http://www.zomato.com/api/documentation)_
3
+
4
+ In your Gemfile
5
+
6
+ ```ruby
7
+ gem 'zomato'
8
+ ```
9
+
10
+ ```bash
11
+ $ bundle install
12
+ ```
13
+
14
+ and...
15
+
16
+ ```ruby
17
+ require 'rubygems'
18
+ require 'zomato'
19
+
20
+ zomato = Zomato::Base.new('your_key_here')
21
+ delhi = zomato.cities.first
22
+ #<Zomato::City:0x8ffe080 @id=1, @name="Delhi NCR", @longitude="77.210276", @latitude="28.625789", @has_nightlife=true, @show_zones=true>
23
+ noida = delhi.zones.first
24
+ #<Zomato::Zone:0x9b6d8bc @id=1, @name="Noida", @city_id=1>
25
+ alaknanda = delhi.localities.first
26
+ #<Zomato::Subzone:0x8c67020 @id=316, @name="Alaknanda", @zone_id=3, @city_id=1>
27
+ american = delhi.cuisines.first
28
+ #<Zomato::Cuisine:0x94c0c58 @id=1, @name="American", @city_id=1>
29
+ restaurants = american.restaurants
30
+ restaurants.results_found # 100
31
+ restaurants.results_start # 0
32
+ restaurants.results_shown # 10
33
+ underdogs = restaurants.restaurants.first # or
34
+ underdogs = restaurants.first
35
+ #<Zomato::Restaurant:0x8e90694 @id=3384, @name="Underdoggs Sports Bar & Grill", @address="F 38, Level 1, Ambience Mall, Vasant Kunj, New Delhi", @locality="Vasant Kunj", @city="Delhi", @cuisines="American, Mediterranean, Italian", @rating_editor_overall=3.5, @cost_for_two=1500, @has_discount=false, @has_citibank_discount=false>
36
+
37
+ noida.restaurants
38
+ alaknanda.restaurants
39
+ # Like for cuisines, fetches restaurants in "Noida" zone and "Alaknanda" subzone respectively
40
+
41
+ underdogs.details
42
+ underdogs.reviews
43
+ # Returns details and reviews as a hash, check zomato documentation for details as the response is returned as is.
44
+
45
+ underdogs.report_error("This is a test, please ignore.", "Chirantan Rajhans") # true or false based on success or failure.
46
+
47
+ searched_underdogs = Zomato::Restaurant.search(delhi.id, 'underdog').restaurants.first
48
+ # Check zomato documentation for more search options (to be passed as a hash to Zomato::Restaurant.search
49
+ searched_underdogs.id == underdogs.id # true
50
+
51
+ Zomato::Restaurant.near('28.557706', '77.205879')
52
+ # Finds a random restaurant near given geocodes.
53
+ ```
54
+
55
+ ### Note
56
+
57
+ * Some methods accept optional parameters (e.g. searches). Pass them as a hash. Refer zomato's documentation to know their names and datatypes.
58
+ * Also, this gem could use some more specs.
59
+
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup :default, :development
4
+
5
+ desc 'Default: run specs'
6
+ task :default => :spec
7
+
8
+ require 'rspec/core/rake_task'
9
+ RSpec::Core::RakeTask.new do |t|
10
+ t.pattern = "spec/**/*_spec.rb"
11
+ end
12
+
13
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,8 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/zomato/api.rb')
2
+ require File.expand_path(File.dirname(__FILE__) + '/zomato/city.rb')
3
+ require File.expand_path(File.dirname(__FILE__) + '/zomato/locality.rb')
4
+ require File.expand_path(File.dirname(__FILE__) + '/zomato/zone.rb')
5
+ require File.expand_path(File.dirname(__FILE__) + '/zomato/subzone.rb')
6
+ require File.expand_path(File.dirname(__FILE__) + '/zomato/restaurant.rb')
7
+ require File.expand_path(File.dirname(__FILE__) + '/zomato/cuisine.rb')
8
+ require File.expand_path(File.dirname(__FILE__) + '/zomato/base.rb')
@@ -0,0 +1,14 @@
1
+ require 'httparty'
2
+
3
+ module Zomato
4
+
5
+ class Api
6
+
7
+ include HTTParty
8
+ format :json
9
+ base_uri 'https://api.zomato.com/v1/'
10
+ default_params :format => 'json'
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,20 @@
1
+
2
+ module Zomato
3
+ class Base
4
+
5
+ def initialize(key)
6
+ @key = key
7
+ Api.headers 'X-Zomato-API-Key' => key
8
+ end
9
+
10
+ def cities
11
+ @cities ||= City.build(Api.get('/cities').parsed_response)
12
+ end
13
+
14
+ def locality(lat, lon)
15
+ response = Api.get('/geocodes', :query => {:lat => lat, :lon => lon}).parsed_response
16
+ Locality.new(response['locality'])
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,51 @@
1
+ module Zomato
2
+ class City
3
+
4
+ attr_reader :id, :name, :longitude, :latitude, :has_nightlife, :show_zones
5
+
6
+ class << self
7
+
8
+ def build(response)
9
+ @cities ||=
10
+ response['cities'].collect do |city|
11
+ City.new(city['city'])
12
+ end
13
+ end
14
+
15
+ end
16
+
17
+ def initialize(attributes)
18
+ @id = attributes['id']
19
+ @name = attributes['name']
20
+ @longitude = attributes['longitude']
21
+ @latitude = attributes['latitude']
22
+ @has_nightlife = attributes['has_nightlife'] == 1
23
+ @show_zones = attributes['show_zones'] == 1
24
+ end
25
+
26
+ def zones
27
+ response = Api.get(
28
+ '/zones',
29
+ :query => {:city_id => id}
30
+ ).parsed_response
31
+ Zone.build(response)
32
+ end
33
+
34
+ def localities
35
+ response = Api.get(
36
+ '/subzones',
37
+ :query => {:city_id => id}
38
+ ).parsed_response
39
+ Subzone.build(response, id)
40
+ end
41
+
42
+ def cuisines
43
+ response = Api.get(
44
+ '/cuisines',
45
+ :query => {:city_id => id}
46
+ ).parsed_response
47
+ Cuisine.build(response, id)
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,30 @@
1
+ module Zomato
2
+ class Cuisine
3
+
4
+ attr_reader :id, :name, :city_id
5
+
6
+ class << self
7
+ def build(response, city_id)
8
+ response["cuisines"].collect do |cuisine|
9
+ Cuisine.new(cuisine['cuisine'].merge({'city_id' => city_id}))
10
+ end
11
+ end
12
+ end
13
+
14
+ def initialize(attributes)
15
+ @id = attributes['cuisine_id'].to_i
16
+ @name = attributes['cuisine_name']
17
+ @city_id = attributes['city_id'].to_i
18
+ end
19
+
20
+ def restaurants(query = {})
21
+ query = {
22
+ :city_id => city_id,
23
+ :cuisine_id => id
24
+ }.merge(query)
25
+ response = Api.get('/search', :query => query).parsed_response
26
+ Restaurant.build(response, query)
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ module Zomato
2
+ class Locality
3
+
4
+ attr_reader :name, :city_name, :city_id
5
+
6
+ def initialize(attributes)
7
+ @name = attributes['name']
8
+ @city_name = attributes['city_name']
9
+ @city_id = attributes['city_id']
10
+
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,151 @@
1
+ module Zomato
2
+ class Restaurant
3
+
4
+ class Collection
5
+ attr_reader :results_found, :results_start, :results_shown, :restaurants
6
+
7
+ def initialize(response, query)
8
+ load(response, query)
9
+ end
10
+
11
+ def total_pages
12
+ (results_found.to_i / results_shown.to_f).ceil
13
+ end
14
+
15
+ def next_page!
16
+ return self unless has_next_page?
17
+ @results_start = next_page_result_start
18
+ @query.merge({:start => results_start, :count => results_shown})
19
+ response = Api.get('/search', :query => @query).parsed_response
20
+ load(response, @query)
21
+ end
22
+
23
+ def previous_page!
24
+ return self unless has_previous_page?
25
+ @results_start = previous_page_result_start
26
+ @query.merge({:start => results_start, :count => results_shown})
27
+ response = Api.get('/search', :query => query).parsed_response
28
+ load(response, @query)
29
+ end
30
+
31
+ def has_next_page?
32
+ next_page_result_start <= results_found.to_i
33
+ end
34
+
35
+ def has_previous_page?
36
+ previous_page_result_start >= 0
37
+ end
38
+
39
+ def attributes
40
+ {
41
+ :results_found => @results_found,
42
+ :results_start => @results_start,
43
+ :results_shown => @results_shown,
44
+ :resturants => @restaurants,
45
+ :query => @query
46
+ }
47
+ end
48
+
49
+ def first; restaurants.first end
50
+ def last; restaurants.last end
51
+
52
+ private
53
+
54
+ def previous_page_result_start
55
+ results_start.to_i - results_shown.to_i - 1
56
+ end
57
+
58
+ def next_page_result_start
59
+ results_start.to_i + results_shown.to_i + 1
60
+ end
61
+
62
+ def load(response, query)
63
+ @query = query || {}
64
+ @results_found = response['resultsFound']
65
+ @results_start = response['resultsStart']
66
+ @results_shown = response['resultsShown']
67
+ @restaurants = response['results'].collect do |restaurant|
68
+ Restaurant.new(restaurant['result'])
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ attr_reader :id, :name, :address, :locality, :city, :cuisines, :rating_editor_overall, :cost_for_two, :has_discount, :has_citibank_discount
75
+
76
+ def initialize(attributes)
77
+ @id = attributes['id'].to_i
78
+ @name = attributes['name']
79
+ @address = attributes['address']
80
+ @locality = attributes['locality']
81
+ @city = attributes['city']
82
+ @cuisines = attributes['cuisines']
83
+ @rating_editor_overall = attributes['rating_editor_overall']
84
+ @cost_for_two = attributes['cost_for_two']
85
+ @has_discount = attributes['has_discount'] == 1
86
+ @has_citibank_discount = attributes['has_citibank_discount'] == 1
87
+ @details = attributes['details'] if attributes['details']
88
+ end
89
+
90
+ def details
91
+ @details ||= Api.get("/restaurant/#{id}").parsed_response
92
+ end
93
+
94
+ def reviews(query = {})
95
+ query = {
96
+ :start => 1,
97
+ :count => 10
98
+ }.merge(query)
99
+ Api.get("/reviews/#{id}/user", :query => query).parsed_response
100
+ end
101
+
102
+ def report_error(data, name = nil)
103
+ query = {:res_id => id, :data => data}
104
+ query.store(:name, name) if name
105
+ Api.post('/contact', :query => query).parsed_response['status'] == 1
106
+ end
107
+
108
+ class << self
109
+ def build(response, query)
110
+ Collection.new(response, query)
111
+ end
112
+
113
+ def create_by_details(details)
114
+ attributes = {
115
+ 'details' => details,
116
+ 'name' => details['name'],
117
+ 'id' => details['id'],
118
+ 'address' => details['location']['address'],
119
+ 'locality' => details['location']['locality'],
120
+ 'city' => details['location']['city'],
121
+ 'cuisines' => details['cuisines'],
122
+ 'rating_editor_overall' => details['editorRating']['overall'],
123
+ 'cost_for_two' => details['avgCostForTwo']
124
+ }
125
+ Restaurant.new(attributes)
126
+ end
127
+
128
+ def search(city_id, search_term, query = {})
129
+ query = {
130
+ :city_id => city_id,
131
+ :q => search_term
132
+ }.merge(query)
133
+ response = Api.get("/search", :query => query).parsed_response
134
+ Restaurant.build(response, query)
135
+ end
136
+
137
+ def near(lat, lon, query = {})
138
+ query = {
139
+ :lat => lat,
140
+ :lon => lon,
141
+ :random => true
142
+ }.merge(query)
143
+ create_by_details(Api.get("/search/near", :query => query).parsed_response)
144
+ end
145
+
146
+ end
147
+
148
+ end
149
+ end
150
+
151
+
@@ -0,0 +1,32 @@
1
+ module Zomato
2
+ class Subzone
3
+
4
+ attr_reader :id, :name, :zone_id, :city_id
5
+
6
+ class << self
7
+
8
+ def build(response, city_id)
9
+ @subzones ||=
10
+ response['subzones'].collect do |subzone|
11
+ Subzone.new(subzone['subzone'], city_id)
12
+ end
13
+ end
14
+
15
+ end
16
+
17
+ def initialize(attributes, city_id)
18
+ @id = attributes['subzone_id']
19
+ @name = attributes['name']
20
+ @zone_id = attributes['zone_id'].to_i
21
+ @city_id = city_id.to_i
22
+ end
23
+
24
+ def restaurants
25
+ query = {:city_id => city_id, :subzone_id => id}
26
+ response = Api.get('/search', :query => query).parsed_response
27
+ Restaurant.build(response, query)
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,30 @@
1
+ module Zomato
2
+ class Zone
3
+
4
+ attr_reader :id, :name, :city_id
5
+
6
+ def self.build(response)
7
+ response['zones'].collect do |zone|
8
+ Zone.new(zone['zone'])
9
+ end
10
+ end
11
+
12
+ def initialize(attributes)
13
+ @id = attributes['zone_id']
14
+ @name = attributes['name']
15
+ @city_id = attributes['city_id'].to_i
16
+ end
17
+
18
+ def subzones
19
+ response = Api.get('/subzones', :query => {:zone_id => id}).parsed_response
20
+ Subzone.build(response, city_id)
21
+ end
22
+
23
+ def restaurants
24
+ query = {:city_id => city_id, :zone_id => id}
25
+ response = Api.get('/search', :query => query).parsed_response
26
+ Restaurant.build(response, query)
27
+ end
28
+
29
+ end
30
+ end