-
Notifications
You must be signed in to change notification settings - Fork 1
/
app.py
305 lines (273 loc) · 11.2 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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
import os,io
import psycopg
from flask import Flask, request, render_template, redirect, jsonify, session, abort, url_for, send_from_directory, current_app, send_file
import json
from datetime import datetime, date
from datetime import datetime, date
from lib.database_connection import get_flask_database_connection
from lib.repositories.user_repository import UserRepository
from lib.models.property import Property
from lib.models.booking import Booking
from lib.models.my_booking import MyBooking
from lib.models.user import User
from lib.models.image import Image
from lib.repositories.property_repository import PropertyRepository
from lib.repositories.booking_repository import BookingRepository
from lib.repositories.image_repository import ImageRepository
from lib.repositories.my_booking_repo import MyBookingRepo
app = Flask(__name__)
app.config['SECRET_KEY']='1b973299943650f6c7daf012'
# Route for the sign up page
@app.route('/signup', methods=['GET', 'POST'])
def signup():
"""
Route for the homepage.
:return: Renders the index.html template.
"""
if request.method == 'POST':
name = request.form['name']
email = request.form['email']
pass_1 = request.form['pass']
pass_2 = request.form['confpass']
if pass_1 != pass_2:
error = "The passwords dont match."
return render_template('sighnup.html', error=error)
else:
connection = get_flask_database_connection(app)
repository = UserRepository(connection)
new_user = User(None, email=email, name=name, password=pass_1)
repository.create(new_user)
return redirect(url_for('login'))
return render_template('signup.html')
@app.route('/', methods=['GET'])
def dashboard():
"""
Route for the homepage.
:return: Renders the index.html template.
"""
return render_template('Home.html')
# Route for login (temporary, replace with actual logic)
@app.route('/login', methods=['GET', 'POST'])
def login():
"""
Route for login.
:return: Renders the login.html template on GET, processes login on POST.
"""
if request.method == 'POST':
connection = get_flask_database_connection(app)
repository = UserRepository(connection)
user = repository.login (request.form['email'],request.form['password'])
if user:
session['logged_in']=True
session['email']=user.email
session['user_id']=user.id
# return f"You are logged in as: {session['email']} with id: {user.id}"
return redirect(url_for('dashboard'))
else:
error = "User email or password is incorrect."
return render_template('login.html', error=error)
return render_template('login.html')
# Route for logging out
@app.route('/logout')
def logout():
"""
Route for logging out.
:return: Redirects to the homepage.
"""
session.pop('logged_in', None)
session.pop('email', None)
session.pop('user_id',None)
return redirect(url_for('dashboard'))
# App fake login endpoint. To be replaced by a real one later.
@app.route("/fake_login",methods = ['GET'])
def fake_login():
connection = get_flask_database_connection(app)
repository = UserRepository(connection)
user = repository.login('[email protected]','mypssword') #To be replaced by values from html form.
if user:
session['logged_in']=True
session['email']=user.email
session['user_id']=user.id
return f"You are logged in as: {session['email']} with id: {user.id}"
else:
error = "User email or password is incorrect."
return error
# App fake logout endpoint. To be replaced by a real one later.
@app.route("/fake_logout", methods = ['GET'])
def fake_logout():
if 'logged_in' in session:
session.pop('logged_in')
return redirect("/index")
# GET /properties
# to see a list of all properties
# Route for fetching all properties from the database
@app.route("/properties", methods=['GET'])
def get_all_properties():
"""
Route for fetching all properties from the database.
:return: Renders the list_all_properties.html template with the list of properties.
"""
connection = get_flask_database_connection(app)
repository = PropertyRepository(connection)
properties = repository.all()
return render_template("list_all_properties.html", properties=properties)
# Route for fetching a specific property detail
@app.route('/property/<int:property_id>', methods=['GET'])
def property_detail(property_id):
"""
Route for the property detail page.
:param property_id: ID of the property to display.
:return: Renders the property_detail.html template with the property details and user information.
"""
connection = get_flask_database_connection(app)
property_repository = PropertyRepository(connection)
user_repository = UserRepository(connection)
# Find the property by ID
property = property_repository.find(property_id)
if property:
# Find the user by ID
user = user_repository.find_by_id(property.owner_id)
return render_template('property_detail.html', property=property, user=user)
else:
return "Property not found", 404
# GET /properties/new
# displays a form to create a new property
@app.route('/properties/new', methods=['GET'])
def new_property():
if 'user_id' not in session:
return redirect(url_for('login'))
return render_template('new_property.html')
# POST /properties
# creates a new property
@app.route('/properties/created', methods=['POST'])
def create_property():
if 'user_id' not in session:
abort(403)
owner_id = session['user_id']
connection = get_flask_database_connection(app)
repository = PropertyRepository(connection)
property = Property(None, request.form['name'], request.form['description'],request.form['price'], request.form['available_from'],request.form['available_to'], owner_id)
if not property.is_valid():
return render_template('properties/new_property.html',
property=property, errors=property.generate_errors()), 400
property = repository.add(property)
if 'file' not in request.files:
return 'No file or property ID provided', 400
file = request.files['file']
if file.filename == '':
return 'No selected file', 400
# Read the file data
image_data = file.read()
repository = ImageRepository(connection)
repository.insert_image(property.id, image_data)
return redirect(f"/property/{property.id}")
# List properties owned by a specific user (owner)
@app.route("/properties/owner/<int:owner_id>", methods = ['GET'])
def get_properties_by_owner(owner_id):
if 'logged_in' not in session:
return redirect(url_for('login'))
connection = get_flask_database_connection(app)
repository = PropertyRepository(connection)
properties = repository.find_by_owner_id(owner_id)
if properties:
if owner_id==session['user_id']:
return render_template('properties_by_owner.html', properties = properties)
else:
return f"<h3> Sorry, but you can see detail of your properties only. </h3>"
"""
Bookings endpoints section
"""
# Add new booking for the specific property
@app.route("/bookings/new", methods = ['POST'])
def new_booking():
if 'logged_in' not in session:
return redirect(url_for('login'))
property_id = request.form['property_id']
user_id = session['user_id']
requested_from = request.form['startDate']
requested_to = request.form['endDate']
title = request.form['title']
price = request.form['price']
if property_id!="" and user_id!="" and requested_from!="" and requested_to!="" and title!="":
connection = get_flask_database_connection(app)
booking_repository = BookingRepository(connection)
days = datetime.strptime(requested_to, '%Y-%m-%d').date() - datetime.strptime(requested_from, '%Y-%m-%d').date()
total_price = float(price) * float(days.days)
booking = Booking(None,property_id=property_id, user_id=user_id, requested_from=requested_from, requested_to=requested_to, is_confirmed=False, total_price=total_price,created_at=datetime.now())
booking_repository.create(booking)
else:
error = "It seems you haven't specified the dates of your booking request."
return f"<h3>{error}</h3>"
return redirect(url_for('my_bookings'))
# List booking requests created by me as a user (guest)
@app.route("/bookings/my", methods = ['GET'])
def my_bookings():
if 'logged_in' not in session:
return redirect(url_for('login'))
connection = get_flask_database_connection(app)
my_booking_repository = MyBookingRepo(connection)
my_requests = my_booking_repository.all_my_bookings(session['user_id'])
return render_template("my_bookings.html", my_requests = my_requests)
"""
Upload images prototype
FOR SAHRA TO INTEGRATE TO ADD PROPERY
"""
# Display upload form
@app.route('/upload')
def upload_form():
return render_template('upload.html')
# Upload image to database
@app.route('/upload', methods=['POST'])
def upload_image():
if 'file' not in request.files or 'property_id' not in request.form:
return 'No file or property ID provided', 400
file = request.files['file']
property_id = request.form['property_id']
if file.filename == '':
return 'No selected file', 400
# Read the file data
image_data = file.read()
connection = get_flask_database_connection(app)
image_repository = ImageRepository(connection)
# Insert image into the database
image_repository.insert_image(property_id, image_data)
return redirect(url_for('upload_form'))
# Display image by property_id
@app.route("/image/<int:property_id>", methods = ['GET'])
def get_image_by_property_id(property_id):
connection = get_flask_database_connection(app)
image_repository = ImageRepository(connection)
image = image_repository.find_by_property_id(property_id)
return send_file(io.BytesIO(image.image), mimetype='image/jpeg')
# Route for adding a booking
# @app.route('/add_booking', methods=['POST'])
# def add_booking():
# """
# Route for adding a booking.
# :return: JSON response indicating success or failure.
# """
# data = request.get_json()
# start_date = data['startDate']
# end_date = data['endDate']
# title = data['title']
# connection = get_flask_database_connection(app)
# booking_repository = BookingRepository(connection)
# # Create a new booking object
# booking = Booking(
# property_id=1, # Replace with actual property_id
# user_id=1, # Replace with actual user_id
# requested_from=start_date,
# requested_to=end_date,
# is_confirmed=False,
# total_price=100, # Replace with actual price calculation
# created_at=datetime.now()
# )
# try:
# booking_repository.create(booking)
# return jsonify({'status': 'success'})
# except Exception as e:
# print(e)
# return jsonify({'status': 'failure'}), 500
if __name__ == '__main__':
# Run the Flask application
app.run(debug=True, port=int(os.environ.get('PORT', 5001)))