41
41
)
42
42
from app .models .user_template import UserTemplateCreate , UserTemplateModify
43
43
from app .utils .helpers import calculate_expiration_days , calculate_usage_percent
44
- from app .utils .notification import Notification
45
44
from config import NOTIFY_DAYS_LEFT , NOTIFY_REACHED_USAGE_PERCENT , USERS_AUTODELETE_DAYS
46
45
47
46
@@ -455,8 +454,8 @@ def update_user(db: Session, dbuser: User, modify: UserModify) -> User:
455
454
if modify .inbounds :
456
455
for proxy_type , tags in modify .excluded_inbounds .items ():
457
456
dbproxy = db .query (Proxy ) \
458
- .where (Proxy .user == dbuser , Proxy .type == proxy_type ) \
459
- .first () or added_proxies .get (proxy_type )
457
+ .where (Proxy .user == dbuser , Proxy .type == proxy_type ) \
458
+ .first () or added_proxies .get (proxy_type )
460
459
if dbproxy :
461
460
dbproxy .excluded_inbounds = [get_or_create_inbound (db , tag ) for tag in tags ]
462
461
@@ -470,9 +469,13 @@ def update_user(db: Session, dbuser: User, modify: UserModify) -> User:
470
469
if dbuser .status != UserStatus .on_hold :
471
470
dbuser .status = UserStatus .active
472
471
473
- if not dbuser .data_limit or (calculate_usage_percent (
474
- dbuser .used_traffic , dbuser .data_limit ) < NOTIFY_REACHED_USAGE_PERCENT ):
475
- delete_notification_reminder_by_type (db , dbuser .id , ReminderType .data_usage )
472
+ for percent in sorted (NOTIFY_REACHED_USAGE_PERCENT , reverse = True ):
473
+ if not dbuser .data_limit or (calculate_usage_percent (
474
+ dbuser .used_traffic , dbuser .data_limit ) < percent ):
475
+ reminder = get_notification_reminder (db , dbuser .id , ReminderType .data_usage , threshold = percent )
476
+ if reminder :
477
+ delete_notification_reminder (db , reminder )
478
+
476
479
else :
477
480
dbuser .status = UserStatus .limited
478
481
@@ -481,9 +484,12 @@ def update_user(db: Session, dbuser: User, modify: UserModify) -> User:
481
484
if dbuser .status in (UserStatus .active , UserStatus .expired ):
482
485
if not dbuser .expire or dbuser .expire > datetime .utcnow ().timestamp ():
483
486
dbuser .status = UserStatus .active
484
- if not dbuser .expire or (calculate_expiration_days (
485
- dbuser .expire ) > NOTIFY_DAYS_LEFT ):
486
- delete_notification_reminder_by_type (db , dbuser .id , ReminderType .expiration_date )
487
+ for days_left in sorted (NOTIFY_DAYS_LEFT ):
488
+ if not dbuser .expire or (calculate_expiration_days (
489
+ dbuser .expire ) > days_left ):
490
+ reminder = get_notification_reminder (db , dbuser .id , ReminderType .expiration_date , threshold = days_left )
491
+ if reminder :
492
+ delete_notification_reminder (db , reminder )
487
493
else :
488
494
dbuser .status = UserStatus .expired
489
495
@@ -1254,7 +1260,7 @@ def update_node_status(db: Session, dbnode: Node, status: NodeStatus, message: s
1254
1260
1255
1261
1256
1262
def create_notification_reminder (
1257
- db : Session , reminder_type : ReminderType , expires_at : datetime , user_id : int ) -> NotificationReminder :
1263
+ db : Session , reminder_type : ReminderType , expires_at : datetime , user_id : int , threshold : Optional [ int ] = None ) -> NotificationReminder :
1258
1264
"""
1259
1265
Creates a new notification reminder.
1260
1266
@@ -1263,19 +1269,22 @@ def create_notification_reminder(
1263
1269
reminder_type (ReminderType): The type of reminder.
1264
1270
expires_at (datetime): The expiration time of the reminder.
1265
1271
user_id (int): The ID of the user associated with the reminder.
1272
+ threshold (Optional[int]): The threshold value to check for (e.g., days left or usage percent).
1266
1273
1267
1274
Returns:
1268
1275
NotificationReminder: The newly created NotificationReminder object.
1269
1276
"""
1270
1277
reminder = NotificationReminder (type = reminder_type , expires_at = expires_at , user_id = user_id )
1278
+ if threshold is not None :
1279
+ reminder .threshold = threshold
1271
1280
db .add (reminder )
1272
1281
db .commit ()
1273
1282
db .refresh (reminder )
1274
1283
return reminder
1275
1284
1276
1285
1277
1286
def get_notification_reminder (
1278
- db : Session , user_id : int , reminder_type : ReminderType ,
1287
+ db : Session , user_id : int , reminder_type : ReminderType , threshold : Optional [ int ] = None
1279
1288
) -> Union [NotificationReminder , None ]:
1280
1289
"""
1281
1290
Retrieves a notification reminder for a user.
@@ -1284,38 +1293,57 @@ def get_notification_reminder(
1284
1293
db (Session): The database session.
1285
1294
user_id (int): The ID of the user.
1286
1295
reminder_type (ReminderType): The type of reminder to retrieve.
1296
+ threshold (Optional[int]): The threshold value to check for (e.g., days left or usage percent).
1287
1297
1288
1298
Returns:
1289
1299
Union[NotificationReminder, None]: The NotificationReminder object if found and not expired, None otherwise.
1290
1300
"""
1291
- reminder = db .query (NotificationReminder ).filter (
1292
- NotificationReminder .user_id == user_id ).filter (
1293
- NotificationReminder .type == reminder_type ).first ()
1301
+ query = db .query (NotificationReminder ).filter (
1302
+ NotificationReminder .user_id == user_id ,
1303
+ NotificationReminder .type == reminder_type
1304
+ )
1305
+
1306
+ # If a threshold is provided, filter for reminders with this threshold
1307
+ if threshold is not None :
1308
+ query = query .filter (NotificationReminder .threshold == threshold )
1309
+
1310
+ reminder = query .first ()
1311
+
1294
1312
if reminder is None :
1295
- return
1313
+ return None
1314
+
1315
+ # Check if the reminder has expired
1296
1316
if reminder .expires_at and reminder .expires_at < datetime .utcnow ():
1297
1317
db .delete (reminder )
1298
1318
db .commit ()
1299
- return
1319
+ return None
1320
+
1300
1321
return reminder
1301
1322
1302
1323
1303
- def delete_notification_reminder_by_type (db : Session , user_id : int , reminder_type : ReminderType ) -> None :
1324
+ def delete_notification_reminder_by_type (
1325
+ db : Session , user_id : int , reminder_type : ReminderType , threshold : Optional [int ] = None
1326
+ ) -> None :
1304
1327
"""
1305
- Deletes a notification reminder for a user based on the reminder type.
1328
+ Deletes a notification reminder for a user based on the reminder type and optional threshold .
1306
1329
1307
1330
Args:
1308
1331
db (Session): The database session.
1309
1332
user_id (int): The ID of the user.
1310
1333
reminder_type (ReminderType): The type of reminder to delete.
1334
+ threshold (Optional[int]): The threshold to delete (e.g., days left or usage percent). If not provided, deletes all reminders of that type.
1311
1335
"""
1312
1336
stmt = delete (NotificationReminder ).where (
1313
1337
NotificationReminder .user_id == user_id ,
1314
- NotificationReminder .type == reminder_type ,
1338
+ NotificationReminder .type == reminder_type
1315
1339
)
1340
+
1341
+ # If a threshold is provided, include it in the filter
1342
+ if threshold is not None :
1343
+ stmt = stmt .where (NotificationReminder .threshold == threshold )
1344
+
1316
1345
db .execute (stmt )
1317
1346
db .commit ()
1318
- return
1319
1347
1320
1348
1321
1349
def delete_notification_reminder (db : Session , dbreminder : NotificationReminder ) -> None :
0 commit comments