11import os
2- from flask import Flask , redirect , render_template , request , send_from_directory , url_for , jsonify
2+ from datetime import datetime
3+
4+ from flask import Flask , redirect , render_template , request , send_from_directory , url_for
35from flask_migrate import Migrate
46from flask_sqlalchemy import SQLAlchemy
57from flask_wtf .csrf import CSRFProtect
6- from datetime import datetime , timezone
7- # Main application
8+
9+
810app = Flask (__name__ , static_folder = 'static' )
911csrf = CSRFProtect (app )
1012
11- # Configuración según entorno
13+ # WEBSITE_HOSTNAME exists only in production environment
1214if 'WEBSITE_HOSTNAME' not in os .environ :
15+ # local development, where we'll use environment variables
1316 print ("Loading config.development and environment variables from .env file." )
1417 app .config .from_object ('azureproject.development' )
15- else :
18+ else :
19+ # production
1620 print ("Loading config.production." )
1721 app .config .from_object ('azureproject.production' )
1822
2125 SQLALCHEMY_TRACK_MODIFICATIONS = False ,
2226)
2327
24- # Inicializar base de datos
28+ # Initialize the database connection
2529db = SQLAlchemy (app )
30+
31+ # Enable Flask-Migrate commands "flask db init/migrate/upgrade" to work
2632migrate = Migrate (app , db )
2733
28- # Importar modelos después de inicializar db
29- from models import Restaurant , Review , ImageData
34+ # The import must be done after db initialization due to circular import issue
35+ from models import Restaurant , Review
3036
3137@app .route ('/' , methods = ['GET' ])
3238def index ():
3339 print ('Request for index page received' )
3440 restaurants = Restaurant .query .all ()
3541 return render_template ('index.html' , restaurants = restaurants )
3642
43+ @app .route ('/<int:id>' , methods = ['GET' ])
44+ def details (id ):
45+ restaurant = Restaurant .query .where (Restaurant .id == id ).first ()
46+ reviews = Review .query .where (Review .restaurant == id )
47+ return render_template ('details.html' , restaurant = restaurant , reviews = reviews )
3748
49+ @app .route ('/create' , methods = ['GET' ])
50+ def create_restaurant ():
51+ print ('Request for add restaurant page received' )
52+ return render_template ('create_restaurant.html' )
3853
54+ @app .route ('/add' , methods = ['POST' ])
55+ @csrf .exempt
56+ def add_restaurant ():
57+ try :
58+ name = request .values .get ('restaurant_name' )
59+ street_address = request .values .get ('street_address' )
60+ description = request .values .get ('description' )
61+ except (KeyError ):
62+ # Redisplay the question voting form.
63+ return render_template ('add_restaurant.html' , {
64+ 'error_message' : "You must include a restaurant name, address, and description" ,
65+ })
66+ else :
67+ restaurant = Restaurant ()
68+ restaurant .name = name
69+ restaurant .street_address = street_address
70+ restaurant .description = description
71+ db .session .add (restaurant )
72+ db .session .commit ()
3973
40- @app .route ('/images' , methods = ['GET' ])
41- def image_table ():
42- print ('Request for image table page received' )
43- images = ImageData .query .order_by (ImageData .upload_time .desc ()).all ()
44- return render_template ('index.html' , images = images )
74+ return redirect (url_for ('details' , id = restaurant .id ))
4575
76+ @app .route ('/review/<int:id>' , methods = ['POST' ])
4677@csrf .exempt
47- @app .route ('/upload_image' , methods = ['POST' ])
48- def upload_image ():
49- print ('Request to upload image received' )
50- if not request .is_json :
51- return jsonify ({"error" : "Request must be JSON" }), 400
52-
53- data = request .get_json ()
54- filename = data .get ('filename' )
55- pixel_red = data .get ('pixel_red' )
56- pixel_green = data .get ('pixel_green' )
57- pixel_blue = data .get ('pixel_blue' )
58- username = data .get ('username' )
59-
60-
61- if not all ([filename , pixel_red , pixel_green , pixel_blue , username ]):
62- return jsonify ({"error" : "All fields ('filename', 'pixel_red', 'pixel_green', 'pixel_blue', 'username') are required" }), 400
63-
78+ def add_review (id ):
6479 try :
65- new_image = ImageData (
66- filename = filename ,
67- pixel_red = pixel_red ,
68- pixel_green = pixel_green ,
69- pixel_blue = pixel_blue ,
70- username = username ,
71- upload_time = datetime .now (timezone .utc )
72-
73- )
74- #db.session.create_all()
75- #db.session.commit()
76- db .session .add (new_image )
80+ user_name = request .values .get ('user_name' )
81+ rating = request .values .get ('rating' )
82+ review_text = request .values .get ('review_text' )
83+ except (KeyError ):
84+ #Redisplay the question voting form.
85+ return render_template ('add_review.html' , {
86+ 'error_message' : "Error adding review" ,
87+ })
88+ else :
89+ review = Review ()
90+ review .restaurant = id
91+ review .review_date = datetime .now ()
92+ review .user_name = user_name
93+ review .rating = int (rating )
94+ review .review_text = review_text
95+ db .session .add (review )
7796 db .session .commit ()
78- return jsonify ({"message" : "Image uploaded successfully" }), 201
79- except Exception as e :
80- db .session .rollback ()
81- return jsonify ({"error" : str (e )}), 500
97+
98+ return redirect (url_for ('details' , id = id ))
99+
100+ @app .context_processor
101+ def utility_processor ():
102+ def star_rating (id ):
103+ reviews = Review .query .where (Review .restaurant == id )
104+
105+ ratings = []
106+ review_count = 0
107+ for review in reviews :
108+ ratings += [review .rating ]
109+ review_count += 1
110+
111+ avg_rating = sum (ratings ) / len (ratings ) if ratings else 0
112+ stars_percent = round ((avg_rating / 5.0 ) * 100 ) if review_count > 0 else 0
113+ return {'avg_rating' : avg_rating , 'review_count' : review_count , 'stars_percent' : stars_percent }
114+
115+ return dict (star_rating = star_rating )
82116
83117@app .route ('/favicon.ico' )
84118def favicon ():
85119 return send_from_directory (os .path .join (app .root_path , 'static' ),
86120 'favicon.ico' , mimetype = 'image/vnd.microsoft.icon' )
87121
88-
89122if __name__ == '__main__' :
90- app .run ()
123+ app .run ()
0 commit comments