@@ -176,9 +176,12 @@ def send_expiry_notification(app, user, subscriptions):
176176 print ("📨 Sending email..." )
177177 server .send_message (msg )
178178
179- # Update last notification date for all subscriptions
180- for subscription in subscriptions :
181- subscription .last_notification = datetime .now ().date ()
179+ # Update last notification date for the user (not individual subscriptions)
180+ user_settings = user .settings or UserSettings ()
181+ user_settings .last_notification_sent = datetime .now ().date ()
182+ if not user .settings :
183+ user_settings .user_id = user .id
184+ db .session .add (user_settings )
182185 db .session .commit ()
183186
184187 print (f"✅ Notification sent to { user .username } for { len (subscriptions )} subscriptions" )
@@ -202,7 +205,9 @@ def send_expiry_notification(app, user, subscriptions):
202205def check_expiring_subscriptions (app ):
203206 """Check for expiring subscriptions and send notifications"""
204207 with app .app_context ():
205- print (f"🔍 Checking expiring subscriptions at { datetime .now ()} " )
208+ current_time = datetime .now ()
209+ current_hour = current_time .hour
210+ print (f"🔍 Checking expiring subscriptions at { current_time } (hour: { current_hour } )" )
206211
207212 # Get all users with notification settings
208213 users = User .query .all ()
@@ -215,62 +220,62 @@ def check_expiring_subscriptions(app):
215220 if not user_settings .email_notifications :
216221 print (f"⏭️ Skipping { user .username } - notifications disabled" )
217222 continue
218-
219- days_before = user_settings .notification_days
220- check_date = datetime .now ().date () + timedelta (days = days_before )
223+
224+ # Check if we already sent a notification today for this user
225+ today = current_time .date ()
226+ if user_settings .last_notification_sent == today :
227+ print (f"⏭️ Skipping { user .username } - already notified today" )
228+ continue
229+
230+ # Check if it's the user's preferred notification time (±1 hour window)
231+ preferred_hour = user_settings .notification_time or 9
232+ if not (preferred_hour - 1 <= current_hour <= preferred_hour + 1 ):
233+ print (f"⏭️ Skipping { user .username } - not their notification time (prefers { preferred_hour } :00, current: { current_hour } :00)" )
234+ continue
221235
222- # Find subscriptions that are:
223- # 1. Expiring within the notification window
224- # 2. Haven't been notified today
225- # 3. Are still active
226- subscriptions = Subscription .query .filter (
227- Subscription .user_id == user .id ,
228- Subscription .is_active == True ,
229- Subscription .end_date .isnot (None ),
230- Subscription .end_date <= check_date ,
231- Subscription .end_date >= datetime .now ().date (),
232- (Subscription .last_notification == None ) |
233- (Subscription .last_notification < datetime .now ().date ())
234- ).all ()
236+ # Find subscriptions expiring based on their individual or default notification days
237+ expiring_subscriptions = []
238+
239+ for subscription in user .subscriptions :
240+ if not subscription .is_active or not subscription .end_date :
241+ continue
242+
243+ # Get notification days for this specific subscription
244+ notification_days = subscription .get_notification_days (user_settings )
245+ check_date = today + timedelta (days = notification_days )
246+
247+ # Check if this subscription is expiring within its notification window
248+ if subscription .end_date <= check_date and subscription .end_date >= today :
249+ expiring_subscriptions .append (subscription )
235250
236- if subscriptions :
237- print (f"📧 Sending notification to { user .username } for { len (subscriptions )} subscriptions" )
238- success = send_expiry_notification (app , user , subscriptions )
251+ if expiring_subscriptions :
252+ print (f"📧 Sending notification to { user .username } for { len (expiring_subscriptions )} subscriptions at preferred time { preferred_hour } :00 " )
253+ success = send_expiry_notification (app , user , expiring_subscriptions )
239254 if success :
240255 total_notifications += 1
241256 else :
242257 print (f"❌ Failed to send notification to { user .username } " )
243258 else :
244- print (f"✅ No notifications needed for { user .username } " )
259+ print (f"✅ No expiring subscriptions for { user .username } " )
245260
246261 print (f"📊 Notification check completed. Sent { total_notifications } notifications." )
247262
248263def start_scheduler (app ):
249264 """Start the background scheduler for checking expiring subscriptions"""
250265 scheduler = BackgroundScheduler ()
251266
252- # Check every 6 hours instead of daily for more timely notifications
267+ # Check every hour to respect user-specific notification times
253268 scheduler .add_job (
254269 func = lambda : check_expiring_subscriptions (app ),
255270 trigger = "interval" ,
256- hours = 6 ,
271+ hours = 1 ,
257272 id = 'check_subscriptions' ,
258273 replace_existing = True
259274 )
260275
261- # Also add a daily job at 9 AM for primary notifications
262- scheduler .add_job (
263- func = lambda : check_expiring_subscriptions (app ),
264- trigger = "cron" ,
265- hour = 9 ,
266- minute = 0 ,
267- id = 'daily_check_subscriptions' ,
268- replace_existing = True
269- )
270-
271276 scheduler .start ()
272277 atexit .register (lambda : scheduler .shutdown ())
273- print ("Email notification scheduler started" )
278+ print ("Email notification scheduler started (checking hourly) " )
274279
275280def send_test_email (app , user ):
276281 """Send a test email to verify email configuration"""
0 commit comments