-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.py
151 lines (125 loc) · 5.93 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
from flask import Flask, render_template, request, redirect, url_for, send_from_directory
from flask_wtf.csrf import CSRFProtect
from datetime import datetime
from bson import ObjectId
import os
import uuid
from azureproject import mongodb
from requests import RequestException
app = Flask(__name__, static_folder='static')
csrf = CSRFProtect(app)
# WEBSITE_HOSTNAME exists only in production environment
if not 'WEBSITE_HOSTNAME' in os.environ:
# local development, where we'll use environment variables
print("Loading config.development and environment variables from .env file.")
app.config.from_object('azureproject.development')
else:
# production
print("Loading config.production.")
app.config.from_object('azureproject.production')
@app.route('/', methods=['GET'])
def index():
print('Request for index page received')
collection = mongodb.get_collection()
results_restaurant_cursor = collection.find({"type" : "restaurant"})
# Get the list of restaurants
restaurants_annotated = []
for record in results_restaurant_cursor:
# For each restaurant record, get the list of reviews so we can calculate average rating
# print(record.get("name") + ", " + str(record.get("_id")))
review_count, avg_rating = get_review_stats(str(record.get("_id")))
new_record = record
new_record.update({"review_count" : review_count, "avg_rating" : avg_rating, "id" : str(record.get("_id"))})
restaurants_annotated.append(new_record)
return render_template('index.html', restaurants=restaurants_annotated)
def get_review_stats(id):
# print("Getting review stats for restaurant " + id)
collection = mongodb.get_collection()
review_count = collection.count_documents({"type" : "review", "restaurant" : ObjectId(id)})
if review_count > 0:
avg_rating_group = collection.aggregate([{"$match" : {"type" : "review", "restaurant" : ObjectId(id)}}, {"$group" : {"_id" : "$restaurant", "avg_rating" : {"$avg" : "$rating"}}}])
avg_rating = avg_rating_group.next().get("avg_rating")
else:
avg_rating = 0
return review_count, avg_rating
@app.route('/<string:id>', methods=['GET'])
def details(id):
return details(id,'')
def details(id, message):
collection = mongodb.get_collection()
print('Request for restaurant details page received')
cursor = collection.find({"type" : "restaurant", "_id" : ObjectId(id)})
restaurant = cursor.next()
if cursor.retrieved != 0:
review_count, avg_rating = get_review_stats(id)
restaurant_annotated = restaurant
restaurant_annotated.update({"review_count" : review_count, "avg_rating" : avg_rating, "id" : str(restaurant.get("_id"))})
# Get reviews for the restaurant.
reviews_cursor = collection.find({"type" : "review", "restaurant" : ObjectId(id)})
else:
raise Http404("Restaurant not found")
return render_template('details.html', restaurant=restaurant_annotated, reviews=reviews_cursor, message=message)
@app.route('/create', methods=['GET'])
def create_restaurant():
print('Request for add restaurant page received')
return render_template('create_restaurant.html')
@app.route('/add', methods=['POST'])
@csrf.exempt
def add_restaurant():
try:
name = request.values.get('restaurant_name')
street_address = request.values.get('street_address')
description = request.values.get('description')
if (name == "" or description == ""):
raise RequestException()
except (KeyError, RequestException) as e:
# Redisplay the restaurant entry form.
return render_template('create_restaurant.html',
message='Restaurant not added. Include at least a restaurant name and description.')
else:
collection = mongodb.get_collection()
restaurant = mongodb.create_restaurant_record(name, street_address, description)
id = collection.insert_one(restaurant).inserted_id
return redirect(url_for('details', id=id))
@app.route('/review/<string:id>', methods=['POST'])
@csrf.exempt
def add_review(id):
collection = mongodb.get_collection()
cursor = collection.find({"type" : "restaurant", "_id" : ObjectId(id)})
cursor.next()
if cursor.retrieved == 0:
raise Http404("Restaurant not found")
try:
user_name = request.values.get('user_name')
rating = request.values.get('rating')
review_text = request.values.get('review_text')
if (user_name == "" or rating == None):
raise RequestException()
except (KeyError, RequestException) as e:
# Redisplay the details page
return details(str(id), 'Review not added. Include at least a name and rating for review.')
else:
review_record = mongodb.create_review_record(id, user_name, rating, review_text)
document_id_review = collection.insert_one(review_record).inserted_id
print("Inserted review document with _id {}".format(document_id_review))
return redirect(url_for('details', id=id))
@app.context_processor
def utility_processor():
def star_rating(id):
collection = mongodb.get_collection()
results_reviews_cursor = collection.find({"type" : "review", "restaurant" : ObjectId(id)})
ratings = []
review_count = 0;
for review in results_reviews_cursor:
ratings += [review.get("rating")]
review_count += 1
avg_rating = round(sum(ratings)/len(ratings), 2) if ratings else 0
stars_percent = round((avg_rating / 5.0) * 100) if review_count > 0 else 0
return {'avg_rating': avg_rating, 'review_count': review_count, 'stars_percent': stars_percent}
return dict(star_rating=star_rating)
@app.route('/favicon.ico')
def favicon():
return send_from_directory(os.path.join(app.root_path, 'static'),
'favicon.ico', mimetype='image/vnd.microsoft.icon')
if __name__ == '__main__':
app.run()