55All emails include a "Continue the Chat" button with the session ID for seamless conversation continuation.
66"""
77
8+ import os
89import re
910from datetime import datetime
1011from typing import Any , Dict , List , Optional
1314from app .email .service import email_service
1415from app .email .templates_manager import template_manager
1516
16- # Base URL for frontend
17- FRONTEND_BASE_URL = "http://collegepathfinder.vercel.app"
17+ FRONTEND_BASE_URL = os .getenv ("FRONTEND_BASE_URL" )
18+ if not FRONTEND_BASE_URL :
19+ raise ValueError ("FRONTEND_BASE_URL is not set" )
1820
19- # Thread-safe session context (set by execute_tool before calling email functions)
2021_current_session : Optional [ChatSession ] = None
2122
2223
@@ -38,13 +39,8 @@ def _get_chat_url(session_id: str) -> str:
3839
3940def _extract_name_from_email (email : str ) -> str :
4041 """Extract name from email address"""
41- # Get part before @
4242 local_part = email .split ("@" )[0 ]
43-
44- # Remove numbers and special chars
4543 name = re .sub (r"[0-9._-]" , " " , local_part )
46-
47- # Capitalize first letter of each word
4844 name = " " .join (word .capitalize () for word in name .split () if word )
4945
5046 return name if name else "Student"
@@ -60,29 +56,24 @@ def _analyze_conversation_history(session: ChatSession) -> Dict[str, Any]:
6056 "conversation_summary" : [],
6157 }
6258
63- # Analyze messages
6459 for msg in session .messages :
6560 content = msg .content .lower ()
6661
67- # Extract rank
6862 if "rank" in content :
6963 rank_match = re .search (r"\b(\d{1,6})\b" , content )
7064 if rank_match and not analysis ["rank" ]:
7165 analysis ["rank" ] = int (rank_match .group (1 ))
7266
73- # Extract category
7467 categories = ["gm" , "sc" , "st" , "2a" , "2b" , "3a" , "3b" , "obc" ]
7568 for cat in categories :
7669 if cat in content :
7770 analysis ["category" ] = cat .upper ()
7871 break
7972
80- # Track discussion points
8173 if msg .role == "user" :
82- if len (content ) > 20 : # Meaningful message
74+ if len (content ) > 20 :
8375 analysis ["conversation_summary" ].append (content [:100 ])
8476
85- # Limit summary to 5 points
8677 analysis ["conversation_summary" ] = analysis ["conversation_summary" ][:5 ]
8778
8879 return analysis
@@ -120,11 +111,9 @@ def send_comprehensive_report_email(
120111 """
121112 from app .services import CollegeService
122113
123- # Try to get email from session context if not provided
124114 session = _get_session_context ()
125115
126116 if not email and session :
127- # Try to extract email from session user data
128117 if hasattr (session , "user_email" ) and session .user_email :
129118 email = session .user_email
130119
@@ -135,19 +124,16 @@ def send_comprehensive_report_email(
135124 "message" : "Please provide an email address. Say 'email me' to use your account email, or provide a specific address like 'send to friend@email.com'" ,
136125 }
137126
138- # Validate email
139127 if not _validate_email (email ):
140128 return {
141129 "success" : False ,
142130 "error" : "Invalid email format" ,
143131 "message" : "Please provide a valid email address." ,
144132 }
145133
146- # Extract name from email if not provided
147134 if not student_name :
148135 student_name = _extract_name_from_email (email )
149136
150- # Analyze conversation history if session available in context
151137 conversation_data = {}
152138 session = _get_session_context ()
153139 if session :
@@ -157,16 +143,13 @@ def send_comprehensive_report_email(
157143 if not category :
158144 category = conversation_data .get ("category" , "GM" )
159145
160- # Default values
161146 rank = rank or 50000
162147 category = category or "GM"
163148
164- # Create conversation summary
165149 conversation_summary = " " .join (conversation_data .get ("conversation_summary" , []))
166150 if not conversation_summary :
167151 conversation_summary = f"Analysis for rank { rank } in { category } category"
168152
169- # EXECUTE ACTUAL TOOLS TO GET REAL DATA
170153 round1_colleges = []
171154 round2_colleges = []
172155 stats = {
@@ -177,7 +160,6 @@ def send_comprehensive_report_email(
177160 }
178161
179162 try :
180- # Get Round 1 colleges (top 15) - NOTE: CollegeService doesn't accept 'category' param
181163 print (f"[EMAIL DEBUG] Fetching Round 1 colleges for rank { rank } " )
182164 try :
183165 colleges_r1_raw = CollegeService .get_colleges_by_rank (
@@ -192,7 +174,6 @@ def send_comprehensive_report_email(
192174
193175 if colleges_r1_raw and len (colleges_r1_raw ) > 0 :
194176 for college in colleges_r1_raw :
195- # Calculate admission chance
196177 cutoff = college .get ("cutoff_rank" , rank )
197178 if rank <= cutoff :
198179 admission_chance = "High"
@@ -211,7 +192,6 @@ def send_comprehensive_report_email(
211192 else :
212193 print ("[EMAIL DEBUG] No Round 1 colleges found" )
213194
214- # Get Round 2 colleges (top 15)
215195 print (f"[EMAIL DEBUG] Fetching Round 2 colleges for rank { rank } " )
216196 try :
217197 colleges_r2_raw = CollegeService .get_colleges_by_rank (
@@ -226,7 +206,6 @@ def send_comprehensive_report_email(
226206
227207 if colleges_r2_raw and len (colleges_r2_raw ) > 0 :
228208 for college in colleges_r2_raw :
229- # Calculate admission chance
230209 cutoff = college .get ("cutoff_rank" , rank )
231210 if rank <= cutoff :
232211 admission_chance = "High"
@@ -245,7 +224,6 @@ def send_comprehensive_report_email(
245224 else :
246225 print ("[EMAIL DEBUG] No Round 2 colleges found" )
247226
248- # Calculate total stats
249227 stats ["total_colleges" ] = stats ["round1_colleges" ] + stats ["round2_colleges" ]
250228 all_branches = set ()
251229 for college in round1_colleges + round2_colleges :
@@ -258,13 +236,11 @@ def send_comprehensive_report_email(
258236 )
259237
260238 except Exception as e :
261- # Log error but continue with empty data
262239 print (f"[EMAIL ERROR] Error fetching college data: { e } " )
263240 import traceback
264241
265242 traceback .print_exc ()
266243
267- # Prepare context for template
268244 context = {
269245 "student_name" : student_name ,
270246 "rank" : rank ,
@@ -336,15 +312,13 @@ def send_prediction_summary_email(
336312 Returns:
337313 Dict with success status and message
338314 """
339- # Validate email format
340315 if not _validate_email (email ):
341316 return {
342317 "success" : False ,
343318 "error" : "Invalid email format" ,
344319 "message" : "Please provide a valid email address." ,
345320 }
346321
347- # Prepare context
348322 context = {
349323 "student_name" : student_name ,
350324 "rank" : rank ,
@@ -354,7 +328,7 @@ def send_prediction_summary_email(
354328 "rank_year" : "2024" ,
355329 "analysis_date" : datetime .now (),
356330 "total_colleges" : len (colleges ),
357- "colleges" : colleges [:10 ], # Top 10 for email
331+ "colleges" : colleges [:30 ],
358332 "chat_url" : _get_chat_url (session_id ),
359333 }
360334
@@ -370,8 +344,8 @@ def send_prediction_summary_email(
370344 if success :
371345 return {
372346 "success" : True ,
373- "message" : f"✅ Prediction summary sent to { email } ! Check your inbox." ,
374- "colleges_sent" : len (colleges [:10 ]),
347+ "message" : f"Prediction summary sent to { email } ! Check your inbox." ,
348+ "colleges_sent" : len (colleges [:30 ]),
375349 }
376350 else :
377351 return {
@@ -421,7 +395,6 @@ def send_detailed_analysis_email(
421395 "message" : "Please provide a valid email address." ,
422396 }
423397
424- # Calculate statistics
425398 high_chance = sum (1 for c in colleges if c .get ("admission_chance" ) == "High" )
426399 branches = set (c .get ("branch" , "" ) for c in colleges )
427400
0 commit comments