Files
Marzban/app/utils/notification.py
Mohammad ea6a3d2eb6 Migrate to Pydantic V2 (#1495)
* chore: update pydantic to version 2.10.2 and refactor model validators

* refactor: simplify field validators by removing unnecessary pre and always flags

* remove typing_extensions==4.9.0 from requirements.txt

* refactor: remove allow_reuse flag from status field validator

* refactor: simplify field validators by removing pre and always flags

* refactor: update user model imports and enhance account class with abstract method

* refactor: update model_config to use dictionary format in Admin and SubscriptionUserResponse classes

* fix typo in UserDataResetByNext

* change pre=True to mode="before"

* refactor: update validation methods and model configuration in User and Proxy classes

* change pre=False with mode="after"

* Migrated to Pydantic V2

* fix: custom subscriptions not workong

* some small changes

* add missing properties to example schema

* replace from_orm with model_validate

---------

Co-authored-by: MahdiButcher <madibutchercoding@gmail.com>
Co-authored-by: Mahdi Butcher <MahdiButcherCoding@gmail.com>
2024-12-09 21:56:24 +03:30

112 lines
2.8 KiB
Python

from collections import deque
from datetime import datetime as dt
from enum import Enum
from typing import Type
from pydantic import BaseModel
from config import WEBHOOK_ADDRESS
from app.models.admin import Admin
from app.models.user import UserResponse
queue = deque()
class Notification(BaseModel):
class Type(str, Enum):
user_created = "user_created"
user_updated = "user_updated"
user_deleted = "user_deleted"
user_limited = "user_limited"
user_expired = "user_expired"
user_enabled = "user_enabled"
user_disabled = "user_disabled"
data_usage_reset = "data_usage_reset"
data_reset_by_next = "data_reset_by_next"
subscription_revoked = "subscription_revoked"
reached_usage_percent = "reached_usage_percent"
reached_days_left = "reached_days_left"
enqueued_at: float = dt.utcnow().timestamp()
send_at: float = dt.utcnow().timestamp()
tries: int = 0
class UserNotification(Notification):
username: str
class ReachedUsagePercent(UserNotification):
action: Notification.Type = Notification.Type.reached_usage_percent
user: UserResponse
used_percent: float
class ReachedDaysLeft(UserNotification):
action: Notification.Type = Notification.Type.reached_days_left
user: UserResponse
days_left: int
class UserCreated(UserNotification):
action: Notification.Type = Notification.Type.user_created
by: Admin
user: UserResponse
class UserUpdated(UserNotification):
action: Notification.Type = Notification.Type.user_updated
by: Admin
user: UserResponse
class UserDeleted(UserNotification):
action: Notification.Type = Notification.Type.user_deleted
by: Admin
class UserLimited(UserNotification):
action: Notification.Type = Notification.Type.user_limited
user: UserResponse
class UserExpired(UserNotification):
action: Notification.Type = Notification.Type.user_expired
user: UserResponse
class UserEnabled(UserNotification):
action: Notification.Type = Notification.Type.user_enabled
by: Admin = None
user: UserResponse
class UserDisabled(UserNotification):
action: Notification.Type = Notification.Type.user_disabled
by: Admin
user: UserResponse
reason: str = None
class UserDataUsageReset(UserNotification):
action: Notification.Type = Notification.Type.data_usage_reset
by: Admin
user: UserResponse
class UserDataResetByNext(UserNotification):
action: Notification.Type = Notification.Type.data_usage_reset
user: UserResponse
class UserSubscriptionRevoked(UserNotification):
action: Notification.Type = Notification.Type.subscription_revoked
by: Admin
user: UserResponse
def notify(message: Type[Notification]) -> None:
if WEBHOOK_ADDRESS:
queue.append(message)