-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
371 lines (296 loc) · 13.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
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
from flask import Flask, render_template, request, redirect, url_for, flash, session
import sqlite3
from werkzeug.security import generate_password_hash, check_password_hash
from functools import wraps
import os
from datetime import timedelta
from datetime import datetime
app = Flask(__name__)
# Secret key for session management (using environment variable for security)
app.secret_key = os.environ.get('SECRET_KEY', 'default_secret_key')
# Set session lifetime (optional for added security)
app.permanent_session_lifetime = timedelta(minutes=30)
# Helper function to get a connection to the users database
def get_db_connection():
conn = sqlite3.connect('data/user_data.db')
conn.row_factory = sqlite3.Row # Access columns by name
return conn
# Helper function to get a connection to the request data database
def get_request_db_connection():
conn = sqlite3.connect('data/request_data.db')
conn.row_factory = sqlite3.Row # Access columns by name
return conn
# Helper function to get a connection to the donar data database
def get_donor_db_connection():
conn = sqlite3.connect('data/donar_data.db')
conn.row_factory = sqlite3.Row # Access columns by name
return conn
# Decorator to protect routes that require user login
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if 'user_id' not in session:
flash('Please log in to access this page.', 'error')
return redirect(url_for('user_login'))
return f(*args, **kwargs)
return decorated_function
# Corrected Decorator to protect routes that require admin login
def admin_login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if 'admin_logged_in' not in session:
flash('Please log in as an admin to access this page.', 'error')
return redirect(url_for('admin_login'))
return f(*args, **kwargs)
return decorated_function
# Helper function to Hash Password
def hash_password(password):
return generate_password_hash(password)
# Route for the home page
@app.route('/')
def home():
return render_template('home.html')
# Route for admin login page
@app.route('/admin_login', methods=['GET', 'POST'])
def admin_login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
# Check if username and password match admin credentials (using environment variables)
admin_username = os.getenv('ADMIN_USERNAME', 'Adminbloodbank')
admin_password = os.getenv('ADMIN_PASSWORD', 'Admin@2024bloodbank')
if username == admin_username and password == admin_password:
session['admin_logged_in'] = True # Set admin session
flash('Admin login successful!', 'success')
return redirect(url_for('admin_dashboard'))
else:
flash('Invalid admin username or password. Please try again.', 'error')
return redirect(url_for('admin_login'))
return render_template('admin_login.html')
# Route for admin logout
@app.route('/admin_logout')
def admin_logout():
session.pop('admin_logged_in', None)
flash('You have been logged out.', 'success')
return redirect(url_for('home'))
# Route for user login page
@app.route('/user_login', methods=['GET', 'POST'])
def user_login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
conn = get_db_connection()
cursor = conn.cursor()
# Query the database to check if the user exists
cursor.execute('SELECT * FROM users WHERE username = ?', (username,))
user = cursor.fetchone()
conn.close()
if user and check_password_hash(user['password'], password):
session['user_id'] = user['id']
session['username'] = user['username']
session.permanent = True # Make session permanent (optional for session lifetime)
flash('Login successful!', 'success')
return redirect(url_for('user_dashboard'))
else:
flash('Invalid username or password. Please try again.', 'error')
return redirect(url_for('user_login'))
return render_template('login_page.html')
# Route for user logout
@app.route('/logout')
def logout():
session.clear()
flash('You have been logged out.', 'success')
return redirect(url_for('home'))
# Route for creating a new account
@app.route('/create_account', methods=['GET', 'POST'])
def create_account():
if request.method == 'POST':
full_name = request.form['full_name']
age = int(request.form['age'])
email = request.form['email']
phone = request.form['phone']
city = request.form['city']
blood_type = request.form['blood_type']
username = request.form['username']
password = request.form['password']
# Password hash for security
hashed_password = generate_password_hash(password)
# Age validation (must be 18 or older)
if age < 18:
flash('You must be 18 years or older to create an account.', 'error')
return redirect(url_for('create_account'))
conn = get_db_connection()
cursor = conn.cursor()
try:
cursor.execute('''
INSERT INTO users (full_name, age, email, phone, city, blood_type, username, password)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
''', (full_name, age, email, phone, city, blood_type, username, hashed_password))
conn.commit()
flash('Account created successfully!', 'success')
return redirect(url_for('user_login'))
except sqlite3.IntegrityError:
flash('Username already exists. Please choose another.', 'error')
finally:
conn.close()
return render_template('create_account.html')
# Protected route for user dashboard
@app.route('/user_dashboard')
@login_required
def user_dashboard():
username = session['username']
return render_template('dashboard.html', username=username)
@app.route('/donate_blood', methods=['GET', 'POST'])
@login_required
def donate_blood():
if request.method == 'POST':
donor_name = request.form['donar_name']
age = request.form['age']
date = request.form['date']
phone = request.form['phone']
city = request.form['city']
disease = request.form['disease']
blood_type = request.form['blood_type']
user_id = session['user_id']
conn = get_donor_db_connection()
cursor = conn.cursor()
try:
cursor.execute('''
INSERT INTO blood_donations (donar_name, age, phone, city, disease, blood_type, date, user_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
''', (donor_name, age, phone, city, disease, blood_type, date, user_id))
conn.commit()
flash('Blood donation submitted successfully!', 'success')
return redirect(url_for('user_donation_history'))
except sqlite3.Error as e:
flash(f'An error occurred: {e}', 'error')
finally:
conn.close()
return render_template('donate_blood.html')
@app.route('/request_blood', methods=['GET', 'POST'])
@login_required
def request_blood():
if request.method == 'POST':
patient_name = request.form['full_name']
age = int(request.form['age'])
phone = request.form['phone']
hospital = request.form['hospital']
city = request.form['city']
blood_type = request.form['blood_type']
units = request.form['units']
user_id = session['user_id'] # Get the logged-in user's ID
conn = get_request_db_connection()
cursor = conn.cursor()
try:
cursor.execute('''
INSERT INTO blood_requests (patient_name, age, phone, hospital, city, blood_type, units, user_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
''', (patient_name, age, phone, hospital, city, blood_type, units, user_id))
conn.commit()
flash('Blood request submitted successfully!', 'success')
return redirect(url_for('user_request_history'))
except sqlite3.Error as e:
flash(f'An error occurred: {e}', 'error')
finally:
conn.close()
return render_template('request_blood.html')
@app.route('/request_history')
@admin_login_required
def request_history():
conn = get_request_db_connection() # Connect to the request_data.db
cursor = conn.cursor()
# Fetch all blood requests from the database
cursor.execute('SELECT * FROM blood_requests ORDER BY request_date DESC')
requests = cursor.fetchall()
conn.close()
# Render the request_history template and pass the request data
return render_template('request_history.html', requests=requests)
@app.route('/donation_history')
@admin_login_required
def donation_history():
conn = get_donor_db_connection() # Add parentheses to call the function
cursor = conn.cursor()
# Ensure you're querying the correct table (likely 'blood_donations')
cursor.execute('SELECT * FROM blood_donations ORDER BY donation_date DESC')
donations = cursor.fetchall()
conn.close()
# Render the donation_history template and pass the donations data
return render_template('donation_history.html', donations=donations)
@app.route('/user_donation_history')
@login_required # Ensure only logged-in users can access this page
def user_donation_history():
user_id = session.get('user_id') # Assuming user ID is stored in the session when logged in
conn = get_donor_db_connection() # Assuming this returns a valid DB connection
cursor = conn.cursor()
# Query to fetch donation history for the specific user
cursor.execute('SELECT * FROM blood_donations WHERE user_id = ? ORDER BY donation_date DESC', (user_id,))
user_donations = cursor.fetchall() # Fetch the specific user's donation records
conn.close()
# Pass the donation data to the template
return render_template('user_donation_history.html', user_donations=user_donations)
@app.route('/user_request_history')
@login_required
def user_request_history():
user_id = session['user_id'] # Get the logged-in user's ID
conn = get_request_db_connection()
cursor = conn.cursor()
# Fetch blood requests made by the logged-in user
cursor.execute('''
SELECT * FROM blood_requests
WHERE user_id = ?
ORDER BY request_date DESC
''', (user_id,))
requests = cursor.fetchall()
conn.close()
return render_template('user_request_history.html', requests=requests)
# Route for admin dashboard
@app.route('/admin_dashboard')
def admin_dashboard():
if 'admin_logged_in' in session:
return render_template('admin_dashboard.html')
else:
flash('Please log in to access the admin dashboard.', 'error')
return redirect(url_for('admin_login'))
# Route for forgot password
@app.route('/forgot_password', methods=['GET', 'POST'])
def forgot_password():
if request.method == 'POST':
identifier = request.form['identifier'] # Username or email
conn = get_db_connection()
cursor = conn.cursor()
# Check if the identifier is an email
cursor.execute('SELECT * FROM users WHERE email = ? OR username = ?', (identifier, identifier))
user = cursor.fetchone()
conn.close()
if user:
# Redirect the user to a password reset form where they can reset their password
flash('User found. Please reset your password.', 'success')
return redirect(url_for('reset_password', user_id=user['id']))
else:
flash('The username or email is not registered.', 'error')
return render_template('forgot_password.html')
# Route for reset password
@app.route('/reset_password/<user_id>', methods=['GET', 'POST'])
def reset_password(user_id):
if request.method == 'POST':
new_password = request.form['password']
confirm_password = request.form['confirm_password']
if new_password == confirm_password:
hashed_password = generate_password_hash(new_password) # Hash the password for security
# Update the password in the database
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute('UPDATE users SET password = ? WHERE id = ?', (hashed_password, user_id))
conn.commit()
conn.close()
flash('Your password has been reset successfully. You can now log in.', 'success')
return redirect(url_for('user_login'))
else:
flash('Passwords do not match. Please try again.', 'error')
return render_template('reset_password.html', user_id=user_id)
# Route for contact us page
@app.route('/contact_us')
def contact_us():
return render_template('contact_us.html')
if __name__ == '__main__':
app.run(debug=True)