11"""
22Django management command to send daily calendar email summaries.
33
4- This command should be run via cron job daily at the user's preferred time.
4+ This command checks if it's the user's preferred time (within 1 minute window)
5+ before sending emails. It respects the email_time and timezone settings from
6+ NotificationSettings.
57
6- Example cron job (runs at 7:00 AM daily):
7- 0 7 * * * cd /path/to/project && python manage.py send_daily_calendar_email
8+ This should be run via cron job every minute, and it will only send emails
9+ at the user's configured preferred time:
10+ * * * * * cd /path/to/project && python manage.py send_daily_calendar_email
811
912"""
1013from django .core .management .base import BaseCommand
1114from django .utils import timezone
1215from success .calendar_service import CalendarService
1316from success .models import NotificationSettings
17+ import datetime
18+ import pytz
1419
1520
1621class Command (BaseCommand ):
1722 help = 'Send daily calendar email summary if enabled'
1823
19- def add_arguments (self , parser ):
20- parser .add_argument (
21- '--force' ,
22- action = 'store_true' ,
23- help = 'Force send email even if already sent today' ,
24- )
25- parser .add_argument (
26- '--test' ,
27- action = 'store_true' ,
28- help = 'Send test email for today (ignores normal scheduling)' ,
29- )
3024
3125 def handle (self , * args , ** options ):
3226 self .stdout .write (
@@ -51,47 +45,26 @@ def handle(self, *args, **options):
5145 )
5246 return
5347
54- # Initialize calendar service
55- calendar_service = CalendarService ()
56-
57- if options ['test' ]:
58- # Send test email for today's events
59- self .stdout .write ('Sending test email...' )
60- events , date = calendar_service .get_tomorrow_events ()
61-
62- # For test, use today's events instead
63- import datetime
64- import pytz
65- local_timezone = pytz .timezone (notification_settings .timezone )
66- today = datetime .datetime .now (local_timezone ).date ()
67-
68- # Override the date for test
69- events , _ = calendar_service .get_tomorrow_events ()
70- text_summary = calendar_service .create_text_summary (events , today )
71- self .stdout .write (f'Found { len (events )} events for { today } ' )
72-
73- if calendar_service .send_daily_email ():
74- self .stdout .write (
75- self .style .SUCCESS ('Test email sent successfully!' )
76- )
77- else :
78- self .stdout .write (
79- self .style .ERROR ('Failed to send test email' )
48+ # Check if it's the preferred time to send email
49+ local_timezone = pytz .timezone (notification_settings .timezone )
50+ current_time = datetime .datetime .now (local_timezone ).time ()
51+ preferred_time = notification_settings .email_time
52+
53+ # Allow a 1-minute window around the preferred time
54+ preferred_datetime = datetime .datetime .combine (datetime .date .today (), preferred_time )
55+ current_datetime = datetime .datetime .combine (datetime .date .today (), current_time )
56+ time_diff = abs ((current_datetime - preferred_datetime ).total_seconds ())
57+
58+ if time_diff > 60 : # More than 1 minute difference
59+ self .stdout .write (
60+ self .style .WARNING (
61+ f'Current time ({ current_time .strftime ("%H:%M" )} ) is not within 1 minute of preferred time ({ preferred_time .strftime ("%H:%M" )} ). Skipping email send.'
8062 )
63+ )
8164 return
8265
83- # Normal daily email flow
84- if options ['force' ]:
85- self .stdout .write ('Forcing email send (ignoring previous sends)...' )
86- # Temporarily remove existing log to force send
87- events , tomorrow_date = calendar_service .get_tomorrow_events ()
88- from success .models import CalendarEmailLog
89- CalendarEmailLog .objects .filter (
90- email_date = tomorrow_date ,
91- email_address = notification_settings .email_address
92- ).delete ()
93-
94- # Send daily email
66+ # Initialize calendar service and send daily email
67+ calendar_service = CalendarService ()
9568 success = calendar_service .send_daily_email ()
9669
9770 if success :
0 commit comments