gitscope
https://dev.kronoz.win/r/marzneshin.git
app/tasks/review_users.py · v0.3.0-alpha3
Source
1 9a6b0fa Dawsh 2y ago import asyncio
2 f7af2b3 Dawsh 2y ago import logging
3 a47eb4c Dawsh 2y ago from datetime import datetime
4 a47eb4c Dawsh 2y ago from typing import TYPE_CHECKING
5 a47eb4c Dawsh 2y ago
6 a47eb4c Dawsh 2y ago from sqlalchemy.orm import Session
7 a47eb4c Dawsh 2y ago
8 f7af2b3 Dawsh 2y ago from app import marznode
9 01cdf2e Dawsh 2y ago from app.db import (
10 01cdf2e Dawsh 2y ago GetDB,
11 01cdf2e Dawsh 2y ago get_notification_reminder,
12 01cdf2e Dawsh 2y ago get_users,
13 01cdf2e Dawsh 2y ago start_user_expire,
14 01cdf2e Dawsh 2y ago update_user_status,
15 01cdf2e Dawsh 2y ago )
16 a47eb4c Dawsh 2y ago from app.models.user import ReminderType, UserResponse, UserStatus
17 a47eb4c Dawsh 2y ago from app.utils import report
18 01cdf2e Dawsh 2y ago from app.utils.helpers import calculate_expiration_days, calculate_usage_percent
19 01cdf2e Dawsh 2y ago from config import NOTIFY_DAYS_LEFT, NOTIFY_REACHED_USAGE_PERCENT, WEBHOOK_ADDRESS
20 a47eb4c Dawsh 2y ago
21 a47eb4c Dawsh 2y ago if TYPE_CHECKING:
22 a47eb4c Dawsh 2y ago from app.db.models import User
23 a47eb4c Dawsh 2y ago
24 a47eb4c Dawsh 2y ago
25 f7af2b3 Dawsh 2y ago logger = logging.getLogger(__name__)
26 f7af2b3 Dawsh 2y ago
27 f7af2b3 Dawsh 2y ago
28 01cdf2e Dawsh 2y ago def add_notification_reminders(
29 01cdf2e Dawsh 2y ago db: Session, user: "User", now: datetime = datetime.utcnow()
30 01cdf2e Dawsh 2y ago ) -> None:
31 a47eb4c Dawsh 2y ago if user.data_limit:
32 01cdf2e Dawsh 2y ago usage_percent = calculate_usage_percent(user.used_traffic, user.data_limit)
33 01cdf2e Dawsh 2y ago if (usage_percent >= NOTIFY_REACHED_USAGE_PERCENT) and (
34 01cdf2e Dawsh 2y ago not get_notification_reminder(db, user.id, ReminderType.data_usage)
35 01cdf2e Dawsh 2y ago ):
36 a47eb4c Dawsh 2y ago report.data_usage_percent_reached(
37 01cdf2e Dawsh 2y ago db,
38 01cdf2e Dawsh 2y ago usage_percent,
39 01cdf2e Dawsh 2y ago UserResponse.model_validate(user),
40 01cdf2e Dawsh 2y ago user.id,
41 01cdf2e Dawsh 2y ago user.expire,
42 01cdf2e Dawsh 2y ago )
43 a47eb4c Dawsh 2y ago
44 a47eb4c Dawsh 2y ago if user.expire and ((now - user.created_at).days >= NOTIFY_DAYS_LEFT):
45 a47eb4c Dawsh 2y ago expire_days = calculate_expiration_days(user.expire)
46 01cdf2e Dawsh 2y ago if (expire_days <= NOTIFY_DAYS_LEFT) and (
47 01cdf2e Dawsh 2y ago not get_notification_reminder(db, user.id, ReminderType.expiration_date)
48 01cdf2e Dawsh 2y ago ):
49 a47eb4c Dawsh 2y ago report.expire_days_reached(
50 01cdf2e Dawsh 2y ago db, expire_days, UserResponse.model_validate(user), user.id, user.expire
51 01cdf2e Dawsh 2y ago )
52 a47eb4c Dawsh 2y ago
53 a47eb4c Dawsh 2y ago
54 f7af2b3 Dawsh 2y ago async def review_users():
55 a47eb4c Dawsh 2y ago now = datetime.utcnow()
56 9a6b0fa Dawsh 2y ago with GetDB() as db:
57 a47eb4c Dawsh 2y ago for user in get_users(db, status=UserStatus.active):
58 a47eb4c Dawsh 2y ago
59 a47eb4c Dawsh 2y ago limited = user.data_limit and user.used_traffic >= user.data_limit
60 f446990 Dawsh 2y ago expired = user.expire and user.expire <= now
61 a47eb4c Dawsh 2y ago if limited:
62 a47eb4c Dawsh 2y ago status = UserStatus.limited
63 a47eb4c Dawsh 2y ago elif expired:
64 a47eb4c Dawsh 2y ago status = UserStatus.expired
65 a47eb4c Dawsh 2y ago else:
66 a47eb4c Dawsh 2y ago if WEBHOOK_ADDRESS:
67 a47eb4c Dawsh 2y ago add_notification_reminders(db, user, now)
68 a47eb4c Dawsh 2y ago continue
69 a47eb4c Dawsh 2y ago
70 9a6b0fa Dawsh 2y ago await marznode.operations.remove_user(user)
71 a47eb4c Dawsh 2y ago update_user_status(db, user, status)
72 a47eb4c Dawsh 2y ago
73 01cdf2e Dawsh 2y ago asyncio.create_task(
74 01cdf2e Dawsh 2y ago report.status_change(
75 01cdf2e Dawsh 2y ago user.username, user.status, UserResponse.model_validate(user)
76 01cdf2e Dawsh 2y ago )
77 01cdf2e Dawsh 2y ago )
78 a47eb4c Dawsh 2y ago
79 01cdf2e Dawsh 2y ago logger.info(f'User "{user.username}" status changed to {status}')
80 a47eb4c Dawsh 2y ago
81 a47eb4c Dawsh 2y ago for user in get_users(db, status=UserStatus.on_hold):
82 a47eb4c Dawsh 2y ago
83 a47eb4c Dawsh 2y ago if user.edit_at:
84 f446990 Dawsh 2y ago base_time = user.edit_at
85 a47eb4c Dawsh 2y ago else:
86 f446990 Dawsh 2y ago base_time = user.created_at
87 a47eb4c Dawsh 2y ago
88 a47eb4c Dawsh 2y ago # Check if the user is online After or at 'base_time'
89 f446990 Dawsh 2y ago if user.online_at and base_time <= user.online_at:
90 a47eb4c Dawsh 2y ago status = UserStatus.active
91 a47eb4c Dawsh 2y ago
92 f446990 Dawsh 2y ago elif user.on_hold_timeout and (user.on_hold_timeout <= now):
93 a47eb4c Dawsh 2y ago # If the user didn't connect within the timeout period, change status to "Active"
94 a47eb4c Dawsh 2y ago status = UserStatus.active
95 a47eb4c Dawsh 2y ago
96 a47eb4c Dawsh 2y ago else:
97 a47eb4c Dawsh 2y ago continue
98 a47eb4c Dawsh 2y ago
99 a47eb4c Dawsh 2y ago update_user_status(db, user, status)
100 a47eb4c Dawsh 2y ago start_user_expire(db, user)
101 01cdf2e Dawsh 2y ago asyncio.create_task(
102 01cdf2e Dawsh 2y ago report.status_change(
103 01cdf2e Dawsh 2y ago user.username, user.status, UserResponse.model_validate(user)
104 01cdf2e Dawsh 2y ago )
105 01cdf2e Dawsh 2y ago )
106 9a6b0fa Dawsh 2y ago logger.info(f"on hold user `{user.username}` has been activated")