14
14
from django .conf import settings
15
15
from django .core import serializers
16
16
from django .core .files .temp import NamedTemporaryFile
17
+ from django .core .mail import EmailMultiAlternatives
18
+ from django .template .loader import render_to_string
19
+ from django .utils .html import strip_tags
17
20
18
21
from evalai .celery import app
19
22
@@ -2309,6 +2312,103 @@ def update_submission_retention_dates():
2309
2312
return {"updated_submissions" : updated_count , "errors" : errors }
2310
2313
2311
2314
2315
+ def send_template_email (
2316
+ recipient_email ,
2317
+ subject ,
2318
+ template_name ,
2319
+ template_context ,
2320
+ sender_email = None ,
2321
+ reply_to = None ,
2322
+ ):
2323
+ """
2324
+ Send an email using Django templates instead of SendGrid.
2325
+
2326
+ Args:
2327
+ recipient_email (str): Email address of the recipient
2328
+ subject (str): Email subject line
2329
+ template_name (str): Template name (e.g., 'challenges/retention_warning.html')
2330
+ template_context (dict): Context data for the template
2331
+ sender_email (str, optional): Sender email address. Defaults to CLOUDCV_TEAM_EMAIL
2332
+ reply_to (str, optional): Reply-to email address
2333
+
2334
+ Returns:
2335
+ bool: True if email was sent successfully, False otherwise
2336
+ """
2337
+ try :
2338
+ # Use default sender if not provided
2339
+ if not sender_email :
2340
+ sender_email = settings .CLOUDCV_TEAM_EMAIL
2341
+
2342
+ # Render the HTML template
2343
+ html_content = render_to_string (template_name , template_context )
2344
+
2345
+ # Create plain text version by stripping HTML tags
2346
+ text_content = strip_tags (html_content )
2347
+
2348
+ # Create email message
2349
+ email = EmailMultiAlternatives (
2350
+ subject = subject ,
2351
+ body = text_content ,
2352
+ from_email = sender_email ,
2353
+ to = [recipient_email ],
2354
+ reply_to = [reply_to ] if reply_to else None ,
2355
+ )
2356
+
2357
+ # Attach HTML version
2358
+ email .attach_alternative (html_content , "text/html" )
2359
+
2360
+ # Send the email
2361
+ email .send ()
2362
+
2363
+ logger .info (f"Email sent successfully to { recipient_email } " )
2364
+ return True
2365
+
2366
+ except Exception as e :
2367
+ logger .error (f"Failed to send email to { recipient_email } : { str (e )} " )
2368
+ return False
2369
+
2370
+
2371
+ def send_retention_warning_email (
2372
+ challenge , recipient_email , submission_count , warning_date
2373
+ ):
2374
+ """
2375
+ Send retention warning email using Django template.
2376
+
2377
+ Args:
2378
+ challenge: Challenge object
2379
+ recipient_email (str): Email address of the recipient
2380
+ submission_count (int): Number of submissions affected
2381
+ warning_date (datetime): Date when cleanup will occur
2382
+
2383
+ Returns:
2384
+ bool: True if email was sent successfully, False otherwise
2385
+ """
2386
+ # Prepare template context
2387
+ template_context = {
2388
+ "CHALLENGE_NAME" : challenge .title ,
2389
+ "CHALLENGE_URL" : f"{ settings .EVALAI_API_SERVER } /web/challenges/challenge-page/{ challenge .id } " ,
2390
+ "SUBMISSION_COUNT" : submission_count ,
2391
+ "RETENTION_DATE" : warning_date .strftime ("%B %d, %Y" ),
2392
+ "DAYS_REMAINING" : 14 ,
2393
+ }
2394
+
2395
+ # Add challenge image if available
2396
+ if challenge .image :
2397
+ template_context ["CHALLENGE_IMAGE_URL" ] = challenge .image .url
2398
+
2399
+ # Email subject
2400
+ subject = f"⚠️ Retention Warning: { challenge .title } - { submission_count } submissions will be deleted in 14 days"
2401
+
2402
+ # Send the email
2403
+ return send_template_email (
2404
+ recipient_email = recipient_email ,
2405
+ subject = subject ,
2406
+ template_name = "challenges/retention_warning.html" ,
2407
+ template_context = template_context ,
2408
+ sender_email = settings .CLOUDCV_TEAM_EMAIL ,
2409
+ )
2410
+
2411
+
2312
2412
@app .task
2313
2413
def send_retention_warning_notifications ():
2314
2414
"""
@@ -2372,30 +2472,6 @@ def send_retention_warning_notifications():
2372
2472
)
2373
2473
continue
2374
2474
2375
- challenge_url = f"{ settings .EVALAI_API_SERVER } /web/challenges/challenge-page/{ challenge .id } "
2376
-
2377
- template_data = {
2378
- "CHALLENGE_NAME" : challenge .title ,
2379
- "CHALLENGE_URL" : challenge_url ,
2380
- "SUBMISSION_COUNT" : submission_count ,
2381
- "RETENTION_DATE" : warning_date .strftime ("%B %d, %Y" ),
2382
- "DAYS_REMAINING" : 14 ,
2383
- }
2384
-
2385
- if challenge .image :
2386
- template_data ["CHALLENGE_IMAGE_URL" ] = challenge .image .url
2387
-
2388
- # Get template ID from settings
2389
- template_id = settings .SENDGRID_SETTINGS .get ("TEMPLATES" , {}).get (
2390
- "RETENTION_WARNING_EMAIL" , None
2391
- )
2392
-
2393
- if not template_id :
2394
- logger .error (
2395
- "RETENTION_WARNING_EMAIL template ID not configured in settings"
2396
- )
2397
- continue
2398
-
2399
2475
# Get challenge host emails
2400
2476
try :
2401
2477
emails = challenge .creator .get_all_challenge_host_email ()
@@ -2414,16 +2490,28 @@ def send_retention_warning_notifications():
2414
2490
email_sent = False
2415
2491
for email in emails :
2416
2492
try :
2417
- send_email (
2418
- sender = settings .CLOUDCV_TEAM_EMAIL ,
2419
- recipient = email ,
2420
- template_id = template_id ,
2421
- template_data = template_data ,
2422
- )
2423
- email_sent = True
2424
- logger .info (
2425
- f"Sent retention warning email to { email } for challenge { challenge .pk } "
2493
+ success = send_retention_warning_email (
2494
+ challenge = challenge ,
2495
+ recipient_email = email ,
2496
+ submission_count = submission_count ,
2497
+ warning_date = warning_date ,
2426
2498
)
2499
+ if success :
2500
+ email_sent = True
2501
+ logger .info (
2502
+ f"Sent retention warning email to { email } for challenge { challenge .pk } "
2503
+ )
2504
+ else :
2505
+ logger .error (
2506
+ f"Failed to send retention warning email to { email } for challenge { challenge .pk } "
2507
+ )
2508
+ notification_errors .append (
2509
+ {
2510
+ "challenge_id" : challenge .pk ,
2511
+ "email" : email ,
2512
+ "error" : "Email sending failed" ,
2513
+ }
2514
+ )
2427
2515
except Exception as e :
2428
2516
logger .error (
2429
2517
f"Failed to send retention warning email to { email } for challenge { challenge .pk } : { e } "
0 commit comments