rajkhanke commited on
Commit
d0b7346
·
verified ·
1 Parent(s): e1fee7e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +434 -41
app.py CHANGED
@@ -1,19 +1,38 @@
1
- from flask import Flask, render_template, request, jsonify, session, redirect
2
  import google.generativeai as genai
3
  import PyPDF2
4
  import os
5
  import re
 
6
  from datetime import datetime
 
 
 
 
 
 
 
 
 
7
 
8
  app = Flask(__name__)
9
 
10
- app.secret_key = '688ed745a74bdd7ac238f5b50f4104fb87d6774b8b0a4e06e7e18ac5ed0fa31c' # Add this for session management
11
- upload_base = os.getenv('UPLOAD_DIR')
12
  upload_folder = os.path.join(upload_base, 'uploads')
13
 
14
  app.config['UPLOAD_FOLDER'] = upload_folder
15
  os.makedirs(upload_folder, exist_ok=True)
16
 
 
 
 
 
 
 
 
 
 
17
  # Gemini API Configuration
18
  genai.configure(api_key="AIzaSyD54ejbjVIVa-F3aD_Urnp8m1EFLUGR__I")
19
 
@@ -29,8 +48,12 @@ model = genai.GenerativeModel(
29
  generation_config=generation_config,
30
  )
31
 
 
 
 
32
 
33
  def extract_text_from_pdf(pdf_file):
 
34
  try:
35
  pdf_reader = PyPDF2.PdfReader(pdf_file)
36
  text = ""
@@ -69,6 +92,238 @@ def extract_care_plan_format(pdf_text):
69
  return None
70
 
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  @app.route('/')
73
  def index():
74
  return render_template('index.html')
@@ -83,29 +338,41 @@ def switch_role():
83
 
84
  @app.route('/doctor_dashboard')
85
  def doctor_dashboard():
86
- if session.get('role') != 'doctor':
87
- return redirect('/')
88
  return render_template('doctor_dashboard.html')
89
 
90
 
 
 
 
 
 
 
 
 
91
  @app.route('/submit_feedback', methods=['POST'])
92
  def submit_feedback():
93
  try:
 
 
 
 
94
  feedback = request.form.get('feedback', '')
 
95
  care_plan_text = ""
96
  care_plan_format = None
97
-
98
  if 'care_plan_pdf' in request.files:
99
  pdf_file = request.files['care_plan_pdf']
100
  if pdf_file.filename != '':
101
  care_plan_text = extract_text_from_pdf(pdf_file)
102
  care_plan_format = extract_care_plan_format(care_plan_text)
103
-
104
  # If no format is found in the PDF, use a default format
105
  if not care_plan_format:
106
  care_plan_format = """
107
  ASSESSMENT:
108
- [Assessment details]
 
109
  DAILY CARE PLAN:
110
  Morning:
111
  - [Morning activities]
@@ -113,95 +380,221 @@ Afternoon:
113
  - [Afternoon activities]
114
  Evening:
115
  - [Evening activities]
 
116
  MEDICATIONS:
117
  - [Medication details]
 
118
  ADDITIONAL RECOMMENDATIONS:
119
  - [Recommendations]
 
120
  FOLLOW-UP:
121
- [Follow-up details]
122
  """
123
-
124
  # Define emergency keywords to check for severe symptoms
125
  emergency_keywords = [
126
  # Cardiovascular
127
  "severe chest pain", "heart attack", "shortness of breath",
128
  "dizziness", "loss of consciousness", "extreme pain",
129
-
130
  # Neurological
131
  "sudden weakness", "confusion", "slurred speech", "severe headache",
132
-
133
  # Respiratory
134
  "difficulty breathing", "severe shortness of breath", "wheezing", "respiratory distress",
135
-
136
  # Gastrointestinal
137
  "severe abdominal pain", "persistent vomiting", "uncontrolled bleeding",
138
-
139
  # Others
140
  "severe allergic reaction", "anaphylaxis"
141
  ]
142
-
143
  feedback_lower = feedback.lower()
144
  is_emergency = any(keyword in feedback_lower for keyword in emergency_keywords)
145
-
146
  if is_emergency:
147
- # Store emergency notification
148
- emergency_data = {
149
- 'patient_feedback': feedback,
150
- 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
151
- 'status': 'urgent'
152
- }
153
- # In a real application, you would store this in a database
154
- # For now, we'll use a global variable (not recommended for production)
155
- if not hasattr(app, 'emergency_notifications'):
156
- app.emergency_notifications = []
157
- app.emergency_notifications.append(emergency_data)
158
-
159
  # If emergency symptoms are detected, instruct immediate emergency response
160
  emergency_message = (
161
- "Emergency symptoms detected. Please call emergency services immediately at 104/108/109/112."
 
 
 
 
 
 
 
 
162
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  return jsonify({
164
  'success': True,
165
- 'updated_plan': emergency_message
 
 
 
166
  })
167
-
168
  # Prepare a prompt for Gemini AI for a perfect, attractively formatted day care plan.
169
  prompt = f"""
 
 
 
 
 
170
  Patient Care Plan Update Request:
171
  Current Symptoms and Feedback: {feedback}
172
  Current Care Plan (extracted from PDF): {care_plan_text}
 
173
  Based on the patient's feedback and current care plan, please provide an updated, perfect daily care plan in the exact following format:
174
  {care_plan_format}
 
175
  Please ensure the following:
176
  - The response is well-structured with clear section headings.
177
- - Use bullet points for list items without including any asterisk (*) symbols.
178
  - Format the text attractively and professionally.
179
- - Remove any extraneous symbols.
 
 
180
  """
181
  # Get response from Gemini AI
182
  response = model.generate_content(prompt)
183
  # Remove any asterisk symbols from the response text
184
  updated_plan = response.text.replace("*", "")
185
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  return jsonify({
187
  'success': True,
188
- 'updated_plan': updated_plan
 
 
 
 
189
  })
190
-
191
  except Exception as e:
 
192
  return jsonify({
193
  'success': False,
194
  'error': str(e)
195
  })
196
 
197
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  @app.route('/get_emergency_notifications')
199
  def get_emergency_notifications():
200
- if session.get('role') != 'doctor':
201
- return jsonify({'success': False, 'error': 'Unauthorized'})
202
-
203
- notifications = getattr(app, 'emergency_notifications', [])
204
- return jsonify({'success': True, 'notifications': notifications})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
 
206
 
207
  if __name__ == '__main__':
 
1
+ from flask import Flask, render_template, request, jsonify, session, redirect, url_for, send_file
2
  import google.generativeai as genai
3
  import PyPDF2
4
  import os
5
  import re
6
+ import json
7
  from datetime import datetime
8
+ import io
9
+ from twilio.rest import Client
10
+ import base64
11
+ import uuid
12
+ from reportlab.lib.pagesizes import letter
13
+ from reportlab.pdfgen import canvas
14
+ from reportlab.lib import colors
15
+ from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
16
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
17
 
18
  app = Flask(__name__)
19
 
20
+ app.secret_key = '688ed745a74bdd7ac238f5b50f4104fb87d6774b8b0a4e06e7e18ac5ed0fa31c'
21
+ upload_base = os.getenv('UPLOAD_DIR', './uploads')
22
  upload_folder = os.path.join(upload_base, 'uploads')
23
 
24
  app.config['UPLOAD_FOLDER'] = upload_folder
25
  os.makedirs(upload_folder, exist_ok=True)
26
 
27
+ # Twilio Configuration
28
+ ACCOUNT_SID = 'AC490e071f8d01bf0df2f03d086c788d87'
29
+ AUTH_TOKEN = '224b23b950ad5a4052aba15893fdf083'
30
+ TWILIO_FROM = 'whatsapp:+14155238886'
31
+ TWILIO_TO = 'whatsapp:+917559355282' # Hardcoded number as requested
32
+
33
+ # Initialize Twilio client
34
+ twilio_client = Client(ACCOUNT_SID, AUTH_TOKEN)
35
+
36
  # Gemini API Configuration
37
  genai.configure(api_key="AIzaSyD54ejbjVIVa-F3aD_Urnp8m1EFLUGR__I")
38
 
 
48
  generation_config=generation_config,
49
  )
50
 
51
+ # Patient database (in-memory for demo, use a real database in production)
52
+ patients_db = {}
53
+
54
 
55
  def extract_text_from_pdf(pdf_file):
56
+ """Extract text from uploaded PDF file"""
57
  try:
58
  pdf_reader = PyPDF2.PdfReader(pdf_file)
59
  text = ""
 
92
  return None
93
 
94
 
95
+ def determine_patient_status(original_plan, updated_plan, feedback):
96
+ """Determine patient status based on care plan comparison and feedback"""
97
+ # Keywords indicating condition worsening
98
+ emergency_keywords = [
99
+ "severe chest pain", "heart attack", "shortness of breath",
100
+ "dizziness", "loss of consciousness", "extreme pain",
101
+ "sudden weakness", "confusion", "slurred speech", "severe headache",
102
+ "difficulty breathing", "severe shortness of breath", "wheezing",
103
+ "severe abdominal pain", "persistent vomiting", "uncontrolled bleeding",
104
+ "severe allergic reaction", "anaphylaxis", "immediate medical attention",
105
+ "emergency", "call 911", "urgent care", "hospital", "critical"
106
+ ]
107
+
108
+ deteriorating_keywords = [
109
+ "worsening", "increased pain", "not improving", "deteriorating",
110
+ "elevated", "higher", "more frequent", "concerning", "monitor closely",
111
+ "decline", "decreased function", "less able", "more difficult"
112
+ ]
113
+
114
+ improvement_keywords = [
115
+ "improving", "better", "reduced", "lower", "less pain", "increased function",
116
+ "healing", "recovery", "progress", "stable", "maintained", "consistent",
117
+ "well-controlled", "responsive", "good progress"
118
+ ]
119
+
120
+ original_plan_lower = original_plan.lower() if original_plan else ""
121
+ updated_plan_lower = updated_plan.lower()
122
+ feedback_lower = feedback.lower()
123
+
124
+ # Check for emergency keywords first - higher priority in feedback
125
+ if any(keyword in feedback_lower for keyword in emergency_keywords):
126
+ return "emergency"
127
+
128
+ # Check for emergency keywords in updated plan
129
+ if any(keyword in updated_plan_lower for keyword in emergency_keywords):
130
+ return "emergency"
131
+
132
+ # Check for deteriorating keywords
133
+ if any(keyword in feedback_lower for keyword in deteriorating_keywords) or \
134
+ any(keyword in updated_plan_lower for keyword in deteriorating_keywords):
135
+ return "deteriorating"
136
+
137
+ # Check for improvement keywords
138
+ if any(keyword in feedback_lower for keyword in improvement_keywords) or \
139
+ any(keyword in updated_plan_lower for keyword in improvement_keywords):
140
+ return "improving"
141
+
142
+ # Default to stable if no clear indicators
143
+ return "stable"
144
+
145
+
146
+ def generate_care_plan_pdf(patient_info, care_plan_text, status):
147
+ """Generate a PDF of the care plan with improved styling"""
148
+ buffer = io.BytesIO()
149
+
150
+ # Create a PDF document
151
+ doc = SimpleDocTemplate(buffer, pagesize=letter)
152
+ styles = getSampleStyleSheet()
153
+
154
+ # Create custom styles
155
+ title_style = ParagraphStyle(
156
+ 'Title',
157
+ parent=styles['Heading1'],
158
+ fontSize=20,
159
+ alignment=1, # Center alignment
160
+ spaceAfter=20,
161
+ textColor=colors.navy
162
+ )
163
+
164
+ heading_style = ParagraphStyle(
165
+ 'Heading',
166
+ parent=styles['Heading2'],
167
+ fontSize=14,
168
+ spaceAfter=10,
169
+ spaceBefore=15,
170
+ textColor=colors.darkblue
171
+ )
172
+
173
+ normal_style = ParagraphStyle(
174
+ 'Normal',
175
+ parent=styles['Normal'],
176
+ fontSize=11,
177
+ spaceAfter=5,
178
+ leading=14
179
+ )
180
+
181
+ bullet_style = ParagraphStyle(
182
+ 'Bullet',
183
+ parent=styles['Normal'],
184
+ fontSize=11,
185
+ spaceAfter=3,
186
+ leftIndent=20,
187
+ leading=14
188
+ )
189
+
190
+ # Status color mapping
191
+ status_colors = {
192
+ 'emergency': colors.red,
193
+ 'deteriorating': colors.orange,
194
+ 'improving': colors.green,
195
+ 'stable': colors.blue
196
+ }
197
+
198
+ status_style = ParagraphStyle(
199
+ 'Status',
200
+ parent=styles['Heading2'],
201
+ fontSize=14,
202
+ spaceBefore=10,
203
+ spaceAfter=10,
204
+ textColor=status_colors.get(status, colors.black)
205
+ )
206
+
207
+ # Build the document content
208
+ story = []
209
+
210
+ # Title
211
+ story.append(Paragraph("Patient Care Plan", title_style))
212
+ story.append(Spacer(1, 10))
213
+
214
+ # Status indicator
215
+ status_text = {
216
+ 'emergency': "EMERGENCY - IMMEDIATE ACTION REQUIRED",
217
+ 'deteriorating': "HIGH RISK - Condition Deteriorating",
218
+ 'improving': "LOW RISK - Condition Improving",
219
+ 'stable': "STABLE - Maintain Current Care"
220
+ }
221
+
222
+ story.append(Paragraph(status_text.get(status, "Status: Unknown"), status_style))
223
+ story.append(Spacer(1, 15))
224
+
225
+ # Patient Information Table
226
+ patient_data = [
227
+ ["Patient Name:", patient_info.get('name', 'N/A')],
228
+ ["Age:", patient_info.get('age', 'N/A')],
229
+ ["Gender:", patient_info.get('gender', 'N/A')],
230
+ ["Generated Date:", datetime.now().strftime("%Y-%m-%d %H:%M")]
231
+ ]
232
+
233
+ patient_table = Table(patient_data, colWidths=[120, 300])
234
+ patient_table.setStyle(TableStyle([
235
+ ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
236
+ ('BACKGROUND', (0, 0), (0, -1), colors.lightgrey),
237
+ ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'),
238
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
239
+ ('LEFTPADDING', (0, 0), (-1, -1), 6),
240
+ ('RIGHTPADDING', (0, 0), (-1, -1), 6),
241
+ ('TOPPADDING', (0, 0), (-1, -1), 4),
242
+ ('BOTTOMPADDING', (0, 0), (-1, -1), 4),
243
+ ]))
244
+
245
+ story.append(patient_table)
246
+ story.append(Spacer(1, 20))
247
+
248
+ # Care Plan Content
249
+ story.append(Paragraph("Care Plan Details:", heading_style))
250
+ story.append(Spacer(1, 10))
251
+
252
+ # Process care plan text by sections
253
+ sections = re.findall(r'([A-Z][A-Z\s]+):(.*?)(?=\n[A-Z][A-Z\s]+:|$)', care_plan_text, re.DOTALL)
254
+
255
+ for section_title, section_content in sections:
256
+ story.append(Paragraph(section_title + ":", heading_style))
257
+
258
+ # Process bullet points if they exist
259
+ bullet_points = re.findall(r'[-•]\s*(.*?)(?=[-•]|\n|$)', section_content.strip())
260
+
261
+ if bullet_points:
262
+ for point in bullet_points:
263
+ if point.strip():
264
+ story.append(Paragraph(f"• {point.strip()}", bullet_style))
265
+ else:
266
+ # If no bullet points, add the content as a paragraph
267
+ cleaned_content = section_content.strip()
268
+ if cleaned_content:
269
+ story.append(Paragraph(cleaned_content, normal_style))
270
+
271
+ story.append(Spacer(1, 5))
272
+
273
+ # Build the PDF
274
+ doc.build(story)
275
+ buffer.seek(0)
276
+ return buffer
277
+
278
+
279
+ def send_whatsapp_care_plan(patient_name, care_plan_text, status):
280
+ """Send care plan via WhatsApp using Twilio with improved formatting"""
281
+ try:
282
+ # Status emoji
283
+ status_emoji = {
284
+ 'emergency': "🚨 EMERGENCY",
285
+ 'deteriorating': "⚠️ HIGH RISK",
286
+ 'improving': "✅ IMPROVING",
287
+ 'stable': "🟦 STABLE"
288
+ }
289
+
290
+ # Format message for WhatsApp with improved structure
291
+ message = f"*Care Plan Update for {patient_name}*\n\n"
292
+ message += f"*Status: {status_emoji.get(status, 'Unknown')}*\n\n"
293
+
294
+ # Extract and format sections
295
+ sections = re.findall(r'([A-Z][A-Z\s]+):(.*?)(?=\n[A-Z][A-Z\s]+:|$)', care_plan_text, re.DOTALL)
296
+
297
+ for section_title, section_content in sections:
298
+ message += f"*{section_title}:*\n"
299
+
300
+ # Process bullet points if they exist
301
+ bullet_points = re.findall(r'[-•]\s*(.*?)(?=[-•]|\n|$)', section_content.strip())
302
+
303
+ if bullet_points:
304
+ for point in bullet_points:
305
+ if point.strip():
306
+ message += f"• {point.strip()}\n"
307
+ else:
308
+ # If no bullet points, add the content as a paragraph
309
+ cleaned_content = section_content.strip()
310
+ if cleaned_content:
311
+ message += f"{cleaned_content}\n"
312
+
313
+ message += "\n"
314
+
315
+ # Send WhatsApp message using hardcoded number
316
+ twilio_client.messages.create(
317
+ from_=TWILIO_FROM,
318
+ body=message,
319
+ to=TWILIO_TO
320
+ )
321
+ return True
322
+ except Exception as e:
323
+ print(f"Error sending WhatsApp message: {e}")
324
+ return False
325
+
326
+
327
  @app.route('/')
328
  def index():
329
  return render_template('index.html')
 
338
 
339
  @app.route('/doctor_dashboard')
340
  def doctor_dashboard():
 
 
341
  return render_template('doctor_dashboard.html')
342
 
343
 
344
+ @app.route('/patient_details/<patient_id>')
345
+ def patient_details(patient_id):
346
+ patient = patients_db.get(patient_id)
347
+ if not patient:
348
+ return redirect('/doctor_dashboard')
349
+ return render_template('doctor_dashboard.html', selected_patient=patient)
350
+
351
+
352
  @app.route('/submit_feedback', methods=['POST'])
353
  def submit_feedback():
354
  try:
355
+ # Get patient information
356
+ name = request.form.get('name', '')
357
+ age = request.form.get('age', '')
358
+ gender = request.form.get('gender', '')
359
  feedback = request.form.get('feedback', '')
360
+
361
  care_plan_text = ""
362
  care_plan_format = None
363
+
364
  if 'care_plan_pdf' in request.files:
365
  pdf_file = request.files['care_plan_pdf']
366
  if pdf_file.filename != '':
367
  care_plan_text = extract_text_from_pdf(pdf_file)
368
  care_plan_format = extract_care_plan_format(care_plan_text)
369
+
370
  # If no format is found in the PDF, use a default format
371
  if not care_plan_format:
372
  care_plan_format = """
373
  ASSESSMENT:
374
+ - [Assessment details]
375
+
376
  DAILY CARE PLAN:
377
  Morning:
378
  - [Morning activities]
 
380
  - [Afternoon activities]
381
  Evening:
382
  - [Evening activities]
383
+
384
  MEDICATIONS:
385
  - [Medication details]
386
+
387
  ADDITIONAL RECOMMENDATIONS:
388
  - [Recommendations]
389
+
390
  FOLLOW-UP:
391
+ - [Follow-up details]
392
  """
393
+
394
  # Define emergency keywords to check for severe symptoms
395
  emergency_keywords = [
396
  # Cardiovascular
397
  "severe chest pain", "heart attack", "shortness of breath",
398
  "dizziness", "loss of consciousness", "extreme pain",
399
+
400
  # Neurological
401
  "sudden weakness", "confusion", "slurred speech", "severe headache",
402
+
403
  # Respiratory
404
  "difficulty breathing", "severe shortness of breath", "wheezing", "respiratory distress",
405
+
406
  # Gastrointestinal
407
  "severe abdominal pain", "persistent vomiting", "uncontrolled bleeding",
408
+
409
  # Others
410
  "severe allergic reaction", "anaphylaxis"
411
  ]
412
+
413
  feedback_lower = feedback.lower()
414
  is_emergency = any(keyword in feedback_lower for keyword in emergency_keywords)
415
+
416
  if is_emergency:
 
 
 
 
 
 
 
 
 
 
 
 
417
  # If emergency symptoms are detected, instruct immediate emergency response
418
  emergency_message = (
419
+ "ASSESSMENT:\n"
420
+ "- Emergency symptoms detected. Immediate medical attention required.\n\n"
421
+ "EMERGENCY ACTION PLAN:\n"
422
+ "- Call emergency services immediately at 104/108/109/112.\n"
423
+ "- Do not delay seeking medical help.\n"
424
+ "- Do not eat or drink anything until evaluated by medical professionals.\n\n"
425
+ "FOLLOW-UP:\n"
426
+ "- Immediate hospitalization may be required.\n"
427
+ "- Contact your primary physician as soon as possible.\n"
428
  )
429
+
430
+ # Create a patient record with emergency status
431
+ patient_id = str(uuid.uuid4())
432
+ patients_db[patient_id] = {
433
+ 'id': patient_id,
434
+ 'name': name,
435
+ 'age': age,
436
+ 'gender': gender,
437
+ 'feedback': feedback,
438
+ 'original_plan': care_plan_text,
439
+ 'updated_plan': emergency_message,
440
+ 'status': 'emergency',
441
+ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
442
+ }
443
+
444
+ # Generate PDF for emergency instructions
445
+ patient_info = {
446
+ 'name': name,
447
+ 'age': age,
448
+ 'gender': gender
449
+ }
450
+ pdf_buffer = generate_care_plan_pdf(patient_info, emergency_message, 'emergency')
451
+ pdf_base64 = base64.b64encode(pdf_buffer.getvalue()).decode('utf-8')
452
+
453
+ # Send emergency WhatsApp message
454
+ send_whatsapp_care_plan(name, emergency_message, 'emergency')
455
+
456
  return jsonify({
457
  'success': True,
458
+ 'updated_plan': emergency_message,
459
+ 'patient_id': patient_id,
460
+ 'status': 'emergency',
461
+ 'pdf_data': pdf_base64
462
  })
463
+
464
  # Prepare a prompt for Gemini AI for a perfect, attractively formatted day care plan.
465
  prompt = f"""
466
+ Patient Information:
467
+ Name: {name}
468
+ Age: {age}
469
+ Gender: {gender}
470
+
471
  Patient Care Plan Update Request:
472
  Current Symptoms and Feedback: {feedback}
473
  Current Care Plan (extracted from PDF): {care_plan_text}
474
+
475
  Based on the patient's feedback and current care plan, please provide an updated, perfect daily care plan in the exact following format:
476
  {care_plan_format}
477
+
478
  Please ensure the following:
479
  - The response is well-structured with clear section headings.
480
+ - Use bullet points for list items.
481
  - Format the text attractively and professionally.
482
+ - Be specific with recommendations based on the patient's feedback.
483
+ - Include specific times for medications if applicable.
484
+ - Provide clear follow-up instructions.
485
  """
486
  # Get response from Gemini AI
487
  response = model.generate_content(prompt)
488
  # Remove any asterisk symbols from the response text
489
  updated_plan = response.text.replace("*", "")
490
+
491
+ # Determine patient status
492
+ status = determine_patient_status(care_plan_text, updated_plan, feedback)
493
+
494
+ # Generate PDF for downloading
495
+ patient_info = {
496
+ 'name': name,
497
+ 'age': age,
498
+ 'gender': gender
499
+ }
500
+ pdf_buffer = generate_care_plan_pdf(patient_info, updated_plan, status)
501
+ pdf_base64 = base64.b64encode(pdf_buffer.getvalue()).decode('utf-8')
502
+
503
+ # Create a new patient record or update existing
504
+ patient_id = str(uuid.uuid4())
505
+ patients_db[patient_id] = {
506
+ 'id': patient_id,
507
+ 'name': name,
508
+ 'age': age,
509
+ 'gender': gender,
510
+ 'feedback': feedback,
511
+ 'original_plan': care_plan_text,
512
+ 'updated_plan': updated_plan,
513
+ 'status': status,
514
+ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
515
+ }
516
+
517
+ # Send care plan via WhatsApp
518
+ whatsapp_sent = send_whatsapp_care_plan(name, updated_plan, status)
519
+
520
  return jsonify({
521
  'success': True,
522
+ 'updated_plan': updated_plan,
523
+ 'pdf_data': pdf_base64,
524
+ 'patient_id': patient_id,
525
+ 'status': status,
526
+ 'whatsapp_sent': whatsapp_sent
527
  })
528
+
529
  except Exception as e:
530
+ print(f"Error: {str(e)}")
531
  return jsonify({
532
  'success': False,
533
  'error': str(e)
534
  })
535
 
536
 
537
+ @app.route('/download_pdf/<patient_id>')
538
+ def download_pdf(patient_id):
539
+ if patient_id not in patients_db:
540
+ return "Patient not found", 404
541
+
542
+ patient = patients_db[patient_id]
543
+ pdf_buffer = generate_care_plan_pdf({
544
+ 'name': patient['name'],
545
+ 'age': patient['age'],
546
+ 'gender': patient['gender']
547
+ }, patient['updated_plan'], patient['status'])
548
+
549
+ return send_file(
550
+ pdf_buffer,
551
+ as_attachment=True,
552
+ download_name=f"care_plan_{patient['name'].replace(' ', '_')}.pdf",
553
+ mimetype='application/pdf'
554
+ )
555
+
556
+
557
  @app.route('/get_emergency_notifications')
558
  def get_emergency_notifications():
559
+ # Filter patients with emergency status
560
+ emergency_patients = [p for p in patients_db.values() if p['status'] == 'emergency']
561
+
562
+ notifications = []
563
+ for patient in emergency_patients:
564
+ notifications.append({
565
+ 'patient_id': patient['id'],
566
+ 'patient_name': patient['name'],
567
+ 'patient_age': patient['age'],
568
+ 'patient_gender': patient['gender'],
569
+ 'patient_feedback': patient['feedback'],
570
+ 'timestamp': patient['timestamp'],
571
+ 'status': patient['status']
572
+ })
573
+
574
+ return jsonify({
575
+ 'success': True,
576
+ 'notifications': notifications
577
+ })
578
+
579
+
580
+ @app.route('/get_patients')
581
+ def get_patients():
582
+ # Return all patients for the doctor dashboard
583
+ return jsonify({
584
+ 'success': True,
585
+ 'patients': list(patients_db.values())
586
+ })
587
+
588
+
589
+ @app.route('/get_patient/<patient_id>')
590
+ def get_patient(patient_id):
591
+ if patient_id not in patients_db:
592
+ return jsonify({'success': False, 'error': 'Patient not found'})
593
+
594
+ return jsonify({
595
+ 'success': True,
596
+ 'patient': patients_db[patient_id]
597
+ })
598
 
599
 
600
  if __name__ == '__main__':