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