├── Zomato.csv ├── database.db ├── Country_Code.csv ├── data_loader.py ├── app.py └── templates ├── restaurant_detail.html └── restaurant_list.html /Zomato.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kvcops/Zomato-Web-app/main/Zomato.csv -------------------------------------------------------------------------------- /database.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kvcops/Zomato-Web-app/main/database.db -------------------------------------------------------------------------------- /Country_Code.csv: -------------------------------------------------------------------------------- 1 | Country Code,Country 2 | 1,India 3 | 14,Australia 4 | 30,Brazil 5 | 37,Canada 6 | 94,Indonesia 7 | 148,New Zealand 8 | 162,Phillipines 9 | 166,Qatar 10 | 184,Singapore 11 | 189,South Africa 12 | 191,Sri Lanka 13 | 208,Turkey 14 | 214,UAE 15 | 215,United Kingdom 16 | 216,United States 17 | -------------------------------------------------------------------------------- /data_loader.py: -------------------------------------------------------------------------------- 1 | import csv 2 | import sqlite3 3 | 4 | def load_data(): 5 | conn = sqlite3.connect('database.db') 6 | cursor = conn.cursor() 7 | 8 | cursor.execute(''' 9 | CREATE TABLE IF NOT EXISTS restaurants ( 10 | id INTEGER PRIMARY KEY, 11 | name TEXT, 12 | country_code TEXT, 13 | city TEXT, 14 | address TEXT, 15 | locality TEXT, 16 | cuisines TEXT, 17 | average_cost_for_two REAL, 18 | currency TEXT, 19 | has_table_booking TEXT, 20 | has_online_delivery TEXT, 21 | is_delivering_now TEXT, 22 | price_range INTEGER, 23 | aggregate_rating REAL, 24 | rating_color TEXT, 25 | rating_text TEXT, 26 | votes INTEGER 27 | ) 28 | ''') 29 | 30 | encodings = ['utf-8-sig', 'latin-1'] 31 | 32 | for encoding in encodings: 33 | try: 34 | with open('Zomato.csv', 'r', encoding=encoding) as file: 35 | csv_reader = csv.DictReader(file) 36 | for row in csv_reader: 37 | cursor.execute(''' 38 | INSERT OR IGNORE INTO restaurants (id, name, country_code, city, address, locality, cuisines, 39 | average_cost_for_two, currency, has_table_booking, 40 | has_online_delivery, is_delivering_now, price_range, 41 | aggregate_rating, rating_color, rating_text, votes) 42 | VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 43 | ''', ( 44 | row['Restaurant ID'], row['Restaurant Name'], row['Country Code'], 45 | row['City'], row['Address'], row['Locality'], row['Cuisines'], 46 | row['Average Cost for two'], row['Currency'], row['Has Table booking'], 47 | row['Has Online delivery'], row['Is delivering now'], row['Price range'], 48 | row['Aggregate rating'], row['Rating color'], row['Rating text'], 49 | row['Votes'] 50 | )) 51 | print(f"Data loaded successfully using {encoding} encoding.") 52 | break 53 | except UnicodeDecodeError: 54 | pass 55 | except Exception as e: 56 | print(f"An error occurred: {e}") 57 | conn.close() 58 | return 59 | 60 | conn.commit() 61 | conn.close() 62 | 63 | if __name__ == '__main__': 64 | load_data() -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, jsonify, render_template, request 2 | import sqlite3 3 | import csv 4 | 5 | app = Flask(__name__) 6 | 7 | def get_db_connection(): 8 | conn = sqlite3.connect('database.db') 9 | conn.row_factory = sqlite3.Row 10 | return conn 11 | 12 | def load_country_codes(filename='Country_code.csv'): 13 | country_codes = {} 14 | with open(filename, 'r', encoding='utf-8') as file: 15 | reader = csv.DictReader(file) 16 | for row in reader: 17 | country_codes[row['Country Code']] = row['Country'] 18 | return country_codes 19 | 20 | @app.route('/api/restaurant/') 21 | def get_restaurant(id): 22 | conn = get_db_connection() 23 | restaurant = conn.execute('SELECT * FROM restaurants WHERE id = ?', (id,)).fetchone() 24 | conn.close() 25 | if restaurant is None: 26 | return jsonify({"error": "Restaurant not found"}), 404 27 | return jsonify(dict(restaurant)) 28 | 29 | @app.route('/api/restaurants') 30 | def get_restaurants(): 31 | page = request.args.get('page', 1, type=int) 32 | per_page = 10 33 | conn = get_db_connection() 34 | offset = (page - 1) * per_page 35 | restaurants = conn.execute('SELECT * FROM restaurants LIMIT ? OFFSET ?', 36 | (per_page, offset)).fetchall() 37 | total = conn.execute('SELECT COUNT(*) FROM restaurants').fetchone()[0] 38 | conn.close() 39 | return jsonify({ 40 | "restaurants": [dict(r) for r in restaurants], 41 | "total": total, 42 | "page": page, 43 | "per_page": per_page 44 | }) 45 | 46 | @app.route('/') 47 | def restaurant_list(): 48 | conn = get_db_connection() 49 | country_codes = load_country_codes() 50 | 51 | country = request.args.get('country', '') 52 | min_cost = request.args.get('min_cost', type=float) 53 | max_cost = request.args.get('max_cost', type=float) 54 | cuisines = request.args.get('cuisines', '') 55 | search = request.args.get('search', '') 56 | 57 | query = 'SELECT * FROM restaurants WHERE 1=1' 58 | params = [] 59 | 60 | if country: 61 | query += ' AND country_code = ?' 62 | params.append(country) 63 | if min_cost is not None: 64 | query += ' AND average_cost_for_two >= ?' 65 | params.append(min_cost) 66 | if max_cost is not None: 67 | query += ' AND average_cost_for_two <= ?' 68 | params.append(max_cost) 69 | if cuisines: 70 | query += ' AND cuisines LIKE ?' 71 | params.append(f'%{cuisines}%') 72 | if search: 73 | query += ' AND (name LIKE ? OR cuisines LIKE ?)' 74 | params.extend([f'%{search}%', f'%{search}%']) 75 | 76 | page = request.args.get('page', 1, type=int) 77 | per_page = 12 78 | offset = (page - 1) * per_page 79 | query += ' LIMIT ? OFFSET ?' 80 | params.extend([per_page, offset]) 81 | 82 | restaurants = conn.execute(query, params).fetchall() 83 | 84 | count_query = f'SELECT COUNT(*) FROM ({query.replace("LIMIT ? OFFSET ?", "")})' 85 | total = conn.execute(count_query, params[:-2]).fetchone()[0] 86 | 87 | all_cuisines = set() 88 | for row in conn.execute('SELECT cuisines FROM restaurants'): 89 | all_cuisines.update(cuisine.strip() for cuisine in row[0].split(',')) 90 | 91 | conn.close() 92 | 93 | return render_template('restaurant_list.html', 94 | restaurants=restaurants, 95 | page=page, 96 | per_page=per_page, 97 | total=total, 98 | countries=sorted(country_codes.items()), 99 | cuisines=sorted(all_cuisines), 100 | current_filters={ 101 | 'country': country, 102 | 'min_cost': min_cost, 103 | 'max_cost': max_cost, 104 | 'cuisines': cuisines, 105 | 'search': search 106 | }) 107 | 108 | @app.route('/restaurant/') 109 | def restaurant_detail(id): 110 | conn = get_db_connection() 111 | restaurant = conn.execute('SELECT * FROM restaurants WHERE id = ?', (id,)).fetchone() 112 | conn.close() 113 | if restaurant is None: 114 | return "Restaurant not found", 404 115 | return render_template('restaurant_detail.html', restaurant=restaurant) 116 | 117 | if __name__ == '__main__': 118 | app.run(debug=True) -------------------------------------------------------------------------------- /templates/restaurant_detail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {{ restaurant['name'] }} - Details 7 | 8 | 103 | 104 | 105 |
106 |

{{ restaurant['name'] }}

107 |
108 |
109 |
Address
110 |
{{ restaurant['address'] }}
111 |
112 |
113 |
City
114 |
{{ restaurant['city'] }}
115 |
116 |
117 |
Cuisines
118 |
{{ restaurant['cuisines'] }}
119 |
120 |
121 |
Average Cost for Two
122 |
{{ restaurant['average_cost_for_two'] }} {{ restaurant['currency'] }}
123 |
124 |
125 |
Rating
126 |
127 | 128 | {% for i in range(5) %} 129 | {% if i < restaurant['aggregate_rating'] %} 130 | 131 | {% else %} 132 | 133 | {% endif %} 134 | {% endfor %} 135 | {{ restaurant['aggregate_rating'] }} 136 | 137 | ({{ restaurant['rating_text'] }}) 138 |
139 |
140 |
141 |
Table Booking
142 |
143 | {% if restaurant['has_table_booking'] == 'Yes' %} 144 | Available 145 | {% else %} 146 | Not Available 147 | {% endif %} 148 |
149 |
150 |
151 |
Online Delivery
152 |
153 | {% if restaurant['has_online_delivery'] == 'Yes' %} 154 | Available 155 | {% else %} 156 | Not Available 157 | {% endif %} 158 |
159 |
160 |
161 | Back to List 162 |
163 | 164 | -------------------------------------------------------------------------------- /templates/restaurant_list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Zomato Restaurants 7 | 8 | 228 | 229 | 230 |
231 |

Zomato Restaurants

232 | 233 |
234 |
235 |
236 | 237 | 245 |
246 |
247 | 248 | 249 |
250 |
251 | 252 | 253 |
254 |
255 | 256 | 262 |
263 |
264 | 265 | 266 |
267 | 268 |
269 |
270 | 271 |
272 | {% for key, value in current_filters.items() %} 273 | {% if value %} 274 | 275 | {{ key }}: {{ value }} 276 | 277 | 278 | 279 | 280 | {% endif %} 281 | {% endfor %} 282 |
283 | 284 | 308 | 309 | 318 |
319 | 320 | 321 | --------------------------------------------------------------------------------