17
17
Label ,
18
18
Model ,
19
19
Training ,
20
+ UserNotification ,
20
21
)
21
22
from core .serializers import (
22
23
AOISerializer ,
29
30
from django .conf import settings
30
31
from django .contrib .gis .db .models .aggregates import Extent
31
32
from django .contrib .gis .geos import GEOSGeometry
33
+ from django .core .mail import send_mail
32
34
from django .shortcuts import get_object_or_404
33
35
from django .utils import timezone
34
36
@@ -514,14 +516,15 @@ def train_model(
514
516
515
517
training_instance = get_object_or_404 (Training , id = training_id )
516
518
model_instance = get_object_or_404 (Model , id = training_instance .model .id )
519
+
520
+ send_notification (training_instance ,"Started" )
517
521
518
522
training_instance .status = "RUNNING"
519
523
training_instance .started_at = timezone .now ()
524
+ training_instance .task_id = train_model .request .id
525
+
520
526
training_instance .save ()
521
527
os .makedirs (settings .LOG_PATH , exist_ok = True )
522
- if training_instance .task_id is None or training_instance .task_id .strip () == "" :
523
- training_instance .task_id = train_model .request .id
524
- training_instance .save ()
525
528
log_file = os .path .join (settings .LOG_PATH , f"run_{ train_model .request .id } .log" )
526
529
527
530
if model_instance .base_model == "YOLO_V8_V1" and settings .YOLO_HOME is None :
@@ -567,10 +570,55 @@ def train_model(
567
570
)
568
571
569
572
logging .info (f"Training task { training_id } completed successfully" )
573
+ send_notification (training_instance , "Completed" )
570
574
return response
571
575
572
576
except Exception as ex :
573
577
training_instance .status = "FAILED"
574
578
training_instance .finished_at = timezone .now ()
575
579
training_instance .save ()
580
+ send_notification (training_instance , "Failed" )
576
581
raise ex
582
+
583
+ def get_email_message (training_instance ,status ):
584
+
585
+ hostname = settings .FRONTEND_URL
586
+ training_model_url = f"{ hostname } /ai-models/{ training_instance .model .id } "
587
+
588
+ message_template = (
589
+ "Hi {username},\n \n "
590
+ "Your training task (ID: {training_id}) of model {model_name} has {status}. You can view the details here:\n "
591
+ "{training_model_url}\n \n "
592
+ "Thank you for using fAIr - AI Assisted Mapping Tool.\n \n "
593
+ "Best regards,\n "
594
+ "The fAIr Dev Team\n \n "
595
+ "Get Involved : https://www.hotosm.org/get-involved/\n "
596
+ "https://github.com/hotosm/fAIr/"
597
+ )
598
+
599
+ message = message_template .format (
600
+ username = training_instance .user .username ,
601
+ training_id = training_instance .id ,
602
+ model_name = training_instance .model .name ,
603
+ status = status .lower (),
604
+ training_model_url = training_model_url ,
605
+ hostname = hostname ,
606
+
607
+ )
608
+ subject = f"fAIr : Training { training_instance .id } { status .capitalize ()} "
609
+ return message , subject
610
+
611
+
612
+ def send_notification (training_instance ,status ):
613
+ if any (method in training_instance .user .notifications_delivery_methods for method in ["web" , "email" ]):
614
+ UserNotification .objects .create (user = training_instance .user , message = f"Training { training_instance .id } has { status } ." )
615
+ if "email" in training_instance .user .notifications_delivery_methods :
616
+ if training_instance .user .email and training_instance .user .email != '' :
617
+ message ,subject = get_email_message (training_instance ,status )
618
+ send_mail (
619
+ subject = subject ,
620
+ message = message ,
621
+ from_email = settings .DEFAULT_FROM_EMAIL ,
622
+ recipient_list = [training_instance .user .email ],
623
+ fail_silently = False ,
624
+ )
0 commit comments