Skip to content

Commit 448a3bd

Browse files
committed
aaaaa
1 parent d392ffe commit 448a3bd

File tree

10 files changed

+388
-85
lines changed

10 files changed

+388
-85
lines changed

app.py

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
import os
22
from datetime import datetime
3-
from flask import Flask, redirect, render_template, request, send_from_directory, url_for, jsonify
3+
4+
from flask import Flask, redirect, render_template, request, send_from_directory, url_for
45
from flask_migrate import Migrate
56
from flask_sqlalchemy import SQLAlchemy
67
from flask_wtf.csrf import CSRFProtect
78

8-
# Main application
9+
910
app = Flask(__name__, static_folder='static')
1011
csrf = CSRFProtect(app)
1112

12-
# Configuración según entorno
13+
# WEBSITE_HOSTNAME exists only in production environment
1314
if 'WEBSITE_HOSTNAME' not in os.environ:
15+
# local development, where we'll use environment variables
1416
print("Loading config.development and environment variables from .env file.")
1517
app.config.from_object('azureproject.development')
16-
else:
18+
else:
19+
# production
1720
print("Loading config.production.")
1821
app.config.from_object('azureproject.production')
1922

@@ -22,18 +25,26 @@
2225
SQLALCHEMY_TRACK_MODIFICATIONS=False,
2326
)
2427

25-
# Inicializar base de datos
28+
# Initialize the database connection
2629
db = SQLAlchemy(app)
30+
31+
# Enable Flask-Migrate commands "flask db init/migrate/upgrade" to work
2732
migrate = Migrate(app, db)
2833

29-
# Importar modelos después de inicializar db
34+
# The import must be done after db initialization due to circular import issue
3035
from models import Restaurant, Review, ImageData
3136

37+
#@app.route('/', methods=['GET'])
38+
#def index():
39+
# print('Request for index page received')
40+
# restaurants = Restaurant.query.all()
41+
# return render_template('index.html', restaurants=restaurants)
42+
3243
@app.route('/', methods=['GET'])
3344
def index():
3445
print('Request for index page received')
35-
restaurants = Restaurant.query.all()
36-
return render_template('index.html', restaurants=restaurants)
46+
images = ImageData.query.all()
47+
return render_template('index.html', images=images)
3748

3849
@app.route('/<int:id>', methods=['GET'])
3950
def details(id):
@@ -54,6 +65,7 @@ def add_restaurant():
5465
street_address = request.values.get('street_address')
5566
description = request.values.get('description')
5667
except (KeyError):
68+
# Redisplay the question voting form.
5769
return render_template('add_restaurant.html', {
5870
'error_message': "You must include a restaurant name, address, and description",
5971
})
@@ -64,6 +76,7 @@ def add_restaurant():
6476
restaurant.description = description
6577
db.session.add(restaurant)
6678
db.session.commit()
79+
6780
return redirect(url_for('details', id=restaurant.id))
6881

6982
@app.route('/review/<int:id>', methods=['POST'])
@@ -74,6 +87,7 @@ def add_review(id):
7487
rating = request.values.get('rating')
7588
review_text = request.values.get('review_text')
7689
except (KeyError):
90+
#Redisplay the question voting form.
7791
return render_template('add_review.html', {
7892
'error_message': "Error adding review",
7993
})
@@ -93,38 +107,61 @@ def add_review(id):
93107
def utility_processor():
94108
def star_rating(id):
95109
reviews = Review.query.where(Review.restaurant == id)
110+
96111
ratings = []
97112
review_count = 0
98113
for review in reviews:
99-
ratings.append(review.rating)
114+
ratings += [review.rating]
100115
review_count += 1
116+
101117
avg_rating = sum(ratings) / len(ratings) if ratings else 0
102118
stars_percent = round((avg_rating / 5.0) * 100) if review_count > 0 else 0
103119
return {'avg_rating': avg_rating, 'review_count': review_count, 'stars_percent': stars_percent}
120+
104121
return dict(star_rating=star_rating)
105122

106123
@app.route('/images', methods=['GET'])
107124
def image_table():
108125
print('Request for image table page received')
109126
images = ImageData.query.order_by(ImageData.upload_time.desc()).all()
110-
return render_template('image_table.html', images=images)
127+
return render_template('index.html', images=images)
111128

112-
@app.route('/api/images', methods=['GET'])
113-
def image_json():
114-
images = ImageData.query.order_by(ImageData.upload_time.desc()).all()
115-
data = [
116-
{
117-
"id": img.id,
118-
"filename": img.filename,
119-
"username": img.username,
120-
"upload_time": img.upload_time.isoformat(),
121-
"pixel_rojo": img.pixel_rojo,
122-
"pixel_verde": img.pixel_verde,
123-
"pixel_azul": img.pixel_azul
124-
}
125-
for img in images
126-
]
127-
return jsonify(data)
129+
@csrf.exempt
130+
@app.route('/upload_image', methods=['POST'])
131+
def upload_image():
132+
print('Request to upload image received')
133+
if not request.is_json:
134+
return jsonify({"error": "Request must be JSON"}), 400
135+
136+
data = request.get_json()
137+
filename = data.get('filename')
138+
pixel_red = data.get('pixel_red')
139+
pixel_green = data.get('pixel_green')
140+
pixel_blue = data.get('pixel_blue')
141+
username = data.get('username')
142+
143+
144+
if not all([filename, pixel_red, pixel_green, pixel_blue, username]):
145+
return jsonify({"error": "All fields ('filename', 'pixel_red', 'pixel_green', 'pixel_blue', 'username') are required"}), 400
146+
147+
try:
148+
new_image = ImageData(
149+
filename=filename,
150+
pixel_red=pixel_red,
151+
pixel_green=pixel_green,
152+
pixel_blue=pixel_blue,
153+
username=username,
154+
upload_time=datetime.now(timezone.utc)
155+
156+
)
157+
#db.session.create_all()
158+
#db.session.commit()
159+
db.session.add(new_image)
160+
db.session.commit()
161+
return jsonify({"message": "Image uploaded successfully"}), 201
162+
except Exception as e:
163+
db.session.rollback()
164+
return jsonify({"error": str(e)}), 500
128165

129166
@app.route('/favicon.ico')
130167
def favicon():

azureproject/production.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
dbpass=os.getenv('AZURE_POSTGRESQL_PASSWORD'),
66
dbhost=os.getenv('AZURE_POSTGRESQL_HOST'),
77
dbname=os.getenv('AZURE_POSTGRESQL_NAME')
8-
)
8+
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""Recrear migración perdida
2+
3+
Revision ID: 1920d7e9c1dc
4+
Revises:
5+
Create Date: 2025-05-08 17:10:57.001491
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = '1920d7e9c1dc'
14+
down_revision = None
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
pass
21+
22+
23+
def downgrade():
24+
pass
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""Unify heads
2+
3+
Revision ID: 1c80845faa01
4+
Revises: 7d50f8ce1dd1, e95f32cb7145
5+
Create Date: 2025-05-08 22:28:42.064772
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = '1c80845faa01'
14+
down_revision = ('7d50f8ce1dd1', 'e95f32cb7145')
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
pass
21+
22+
23+
def downgrade():
24+
pass
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""a
2+
3+
Revision ID: 2b81d0790f10
4+
Revises: f7006424e5cd
5+
Create Date: 2025-05-08 21:56:08.485113
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
from sqlalchemy.dialects import postgresql
11+
12+
# revision identifiers, used by Alembic.
13+
revision = '2b81d0790f10'
14+
down_revision = 'f7006424e5cd'
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.drop_table('image_data')
22+
# ### end Alembic commands ###
23+
24+
25+
def downgrade():
26+
# ### commands auto generated by Alembic - please adjust! ###
27+
op.create_table('image_data',
28+
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
29+
sa.Column('filename', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
30+
sa.Column('pixel_red', sa.INTEGER(), autoincrement=False, nullable=False),
31+
sa.Column('pixel_green', sa.INTEGER(), autoincrement=False, nullable=False),
32+
sa.Column('pixel_blue', sa.INTEGER(), autoincrement=False, nullable=False),
33+
sa.Column('username', sa.VARCHAR(length=100), autoincrement=False, nullable=False),
34+
sa.Column('upload_time', postgresql.TIMESTAMP(), autoincrement=False, nullable=False),
35+
sa.PrimaryKeyConstraint('id', name='image_data_pkey')
36+
)
37+
# ### end Alembic commands ###
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""Regenerar migraciones
2+
3+
Revision ID: 7d50f8ce1dd1
4+
Revises: 1920d7e9c1dc
5+
Create Date: 2025-05-08 17:11:06.789172
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
from sqlalchemy.dialects import postgresql
11+
12+
# revision identifiers, used by Alembic.
13+
revision = '7d50f8ce1dd1'
14+
down_revision = '1920d7e9c1dc'
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
with op.batch_alter_table('image_data', schema=None) as batch_op:
22+
batch_op.add_column(sa.Column('pixel_red', sa.String(), nullable=False))
23+
batch_op.add_column(sa.Column('pixel_green', sa.String(), nullable=False))
24+
batch_op.add_column(sa.Column('pixel_blue', sa.String(), nullable=False))
25+
batch_op.add_column(sa.Column('upload_time', sa.DateTime(), nullable=False))
26+
batch_op.alter_column('username',
27+
existing_type=sa.VARCHAR(length=50),
28+
type_=sa.String(length=100),
29+
existing_nullable=False)
30+
batch_op.drop_column('pixel_data')
31+
batch_op.drop_column('upload_datetime')
32+
33+
# ### end Alembic commands ###
34+
35+
36+
def downgrade():
37+
# ### commands auto generated by Alembic - please adjust! ###
38+
with op.batch_alter_table('image_data', schema=None) as batch_op:
39+
batch_op.add_column(sa.Column('upload_datetime', postgresql.TIMESTAMP(), autoincrement=False, nullable=True))
40+
batch_op.add_column(sa.Column('pixel_data', sa.TEXT(), autoincrement=False, nullable=False))
41+
batch_op.alter_column('username',
42+
existing_type=sa.String(length=100),
43+
type_=sa.VARCHAR(length=50),
44+
existing_nullable=False)
45+
batch_op.drop_column('upload_time')
46+
batch_op.drop_column('pixel_blue')
47+
batch_op.drop_column('pixel_green')
48+
batch_op.drop_column('pixel_red')
49+
50+
# ### end Alembic commands ###
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""b
2+
3+
Revision ID: e95f32cb7145
4+
Revises: 2b81d0790f10
5+
Create Date: 2025-05-08 22:07:14.980769
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
11+
12+
# revision identifiers, used by Alembic.
13+
revision = 'e95f32cb7145'
14+
down_revision = '2b81d0790f10'
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.create_table('image_data',
22+
sa.Column('id', sa.Integer(), nullable=False),
23+
sa.Column('filename', sa.String(length=255), nullable=False),
24+
sa.Column('pixel_red', sa.Integer(), nullable=False),
25+
sa.Column('pixel_green', sa.Integer(), nullable=False),
26+
sa.Column('pixel_blue', sa.Integer(), nullable=False),
27+
sa.Column('username', sa.String(length=100), nullable=False),
28+
sa.Column('upload_time', sa.DateTime(), nullable=False),
29+
sa.PrimaryKeyConstraint('id')
30+
)
31+
# ### end Alembic commands ###
32+
33+
34+
def downgrade():
35+
# ### commands auto generated by Alembic - please adjust! ###
36+
op.drop_table('image_data')
37+
# ### end Alembic commands ###

0 commit comments

Comments
 (0)