| 1 |
12b255b |
Dawsh |
2y ago |
import secrets |
| 2 |
a47eb4c |
Dawsh |
2y ago |
from datetime import datetime |
| 3 |
a47eb4c |
Dawsh |
2y ago |
from enum import Enum |
| 4 |
d377c4c |
Dawsh |
2y ago |
from typing import Annotated |
| 5 |
a47eb4c |
Dawsh |
2y ago |
|
| 6 |
01cdf2e |
Dawsh |
2y ago |
from pydantic import ( |
| 7 |
01cdf2e |
Dawsh |
2y ago |
ConfigDict, |
| 8 |
01cdf2e |
Dawsh |
2y ago |
BaseModel, |
| 9 |
01cdf2e |
Dawsh |
2y ago |
Field, |
| 10 |
01cdf2e |
Dawsh |
2y ago |
StringConstraints, |
| 11 |
857e289 |
Mrdn |
2y ago |
model_validator, |
| 12 |
01cdf2e |
Dawsh |
2y ago |
) |
| 13 |
a47eb4c |
Dawsh |
2y ago |
|
| 14 |
f446990 |
Dawsh |
2y ago |
USERNAME_REGEXP = r"^\w{3,32}$" |
| 15 |
a47eb4c |
Dawsh |
2y ago |
|
| 16 |
a47eb4c |
Dawsh |
2y ago |
|
| 17 |
a47eb4c |
Dawsh |
2y ago |
class ReminderType(str, Enum): |
| 18 |
a47eb4c |
Dawsh |
2y ago |
expiration_date = "expiration_date" |
| 19 |
a47eb4c |
Dawsh |
2y ago |
data_usage = "data_usage" |
| 20 |
a47eb4c |
Dawsh |
2y ago |
|
| 21 |
a47eb4c |
Dawsh |
2y ago |
|
| 22 |
a47eb4c |
Dawsh |
2y ago |
class UserStatus(str, Enum): |
| 23 |
d377c4c |
Dawsh |
2y ago |
ACTIVE = "active" |
| 24 |
d377c4c |
Dawsh |
2y ago |
INACTIVE = "inactive" |
| 25 |
a47eb4c |
Dawsh |
2y ago |
|
| 26 |
12b255b |
Dawsh |
2y ago |
|
| 27 |
d377c4c |
Dawsh |
2y ago |
class UserDataUsageResetStrategy(str, Enum): |
| 28 |
a47eb4c |
Dawsh |
2y ago |
no_reset = "no_reset" |
| 29 |
a47eb4c |
Dawsh |
2y ago |
day = "day" |
| 30 |
a47eb4c |
Dawsh |
2y ago |
week = "week" |
| 31 |
a47eb4c |
Dawsh |
2y ago |
month = "month" |
| 32 |
a47eb4c |
Dawsh |
2y ago |
year = "year" |
| 33 |
a47eb4c |
Dawsh |
2y ago |
|
| 34 |
a47eb4c |
Dawsh |
2y ago |
|
| 35 |
d377c4c |
Dawsh |
2y ago |
class UserExpireStrategy(str, Enum): |
| 36 |
d377c4c |
Dawsh |
2y ago |
NEVER = "never" |
| 37 |
d377c4c |
Dawsh |
2y ago |
FIXED_DATE = "fixed_date" |
| 38 |
d377c4c |
Dawsh |
2y ago |
START_ON_FIRST_USE = "start_on_first_use" |
| 39 |
d377c4c |
Dawsh |
2y ago |
|
| 40 |
d377c4c |
Dawsh |
2y ago |
|
| 41 |
db68a58 |
Dawsh |
2y ago |
class User(BaseModel): |
| 42 |
db68a58 |
Dawsh |
2y ago |
id: int | None = None |
| 43 |
f1ab16c |
Dawsh |
2y ago |
username: Annotated[ |
| 44 |
f1ab16c |
Dawsh |
2y ago |
str, StringConstraints(to_lower=True, pattern=USERNAME_REGEXP) |
| 45 |
f1ab16c |
Dawsh |
2y ago |
] |
| 46 |
d377c4c |
Dawsh |
2y ago |
expire_strategy: UserExpireStrategy |
| 47 |
d377c4c |
Dawsh |
2y ago |
expire_date: datetime | None = Field(None) |
| 48 |
d377c4c |
Dawsh |
2y ago |
usage_duration: int | None = Field(None) |
| 49 |
d377c4c |
Dawsh |
2y ago |
activation_deadline: datetime | None = Field(None) |
| 50 |
a47eb4c |
Dawsh |
2y ago |
key: str = Field(default_factory=lambda: secrets.token_hex(16)) |
| 51 |
db68a58 |
Dawsh |
2y ago |
data_limit: int | None = Field( |
| 52 |
a47eb4c |
Dawsh |
2y ago |
ge=0, default=None, description="data_limit can be 0 or greater" |
| 53 |
a47eb4c |
Dawsh |
2y ago |
) |
| 54 |
d377c4c |
Dawsh |
2y ago |
data_limit_reset_strategy: UserDataUsageResetStrategy = ( |
| 55 |
d377c4c |
Dawsh |
2y ago |
UserDataUsageResetStrategy.no_reset |
| 56 |
a47eb4c |
Dawsh |
2y ago |
) |
| 57 |
db68a58 |
Dawsh |
2y ago |
note: Annotated[str, Field(max_length=500)] | None = None |
| 58 |
db68a58 |
Dawsh |
2y ago |
sub_updated_at: datetime | None = Field(None) |
| 59 |
db68a58 |
Dawsh |
2y ago |
sub_last_user_agent: str | None = Field(None) |
| 60 |
db68a58 |
Dawsh |
2y ago |
online_at: datetime | None = Field(None) |
| 61 |
a47eb4c |
Dawsh |
2y ago |
|
| 62 |
a47eb4c |
Dawsh |
2y ago |
model_config = ConfigDict(from_attributes=True) |
| 63 |
a47eb4c |
Dawsh |
2y ago |
|
| 64 |
4442e87 |
mahdim10 |
2y ago |
@model_validator(mode="after") |
| 65 |
4442e87 |
mahdim10 |
2y ago |
def validate_expiry(self): |
| 66 |
4442e87 |
mahdim10 |
2y ago |
if self.expire_strategy == UserExpireStrategy.START_ON_FIRST_USE: |
| 67 |
4442e87 |
mahdim10 |
2y ago |
if not self.usage_duration: |
| 68 |
4442e87 |
mahdim10 |
2y ago |
raise ValueError( |
| 69 |
4442e87 |
mahdim10 |
2y ago |
"User expire_strategy cannot be start_on_first_use without a valid usage_duration." |
| 70 |
4442e87 |
mahdim10 |
2y ago |
) |
| 71 |
4442e87 |
mahdim10 |
2y ago |
|
| 72 |
4442e87 |
mahdim10 |
2y ago |
# Set expire_date to None if expire_strategy is START_ON_FIRST_USE |
| 73 |
4442e87 |
mahdim10 |
2y ago |
self.expire_date = None |
| 74 |
4442e87 |
mahdim10 |
2y ago |
|
| 75 |
4442e87 |
mahdim10 |
2y ago |
elif self.expire_strategy == UserExpireStrategy.FIXED_DATE: |
| 76 |
4442e87 |
mahdim10 |
2y ago |
if not self.expire_date: |
| 77 |
4442e87 |
mahdim10 |
2y ago |
raise ValueError( |
| 78 |
4442e87 |
mahdim10 |
2y ago |
"User expire_strategy cannot be fixed_date without a valid expire date." |
| 79 |
4442e87 |
mahdim10 |
2y ago |
) |
| 80 |
4442e87 |
mahdim10 |
2y ago |
|
| 81 |
4442e87 |
mahdim10 |
2y ago |
# Set usage_duration and activation_deadline to None if expire_strategy is START_ON_FIRST_USE |
| 82 |
4442e87 |
mahdim10 |
2y ago |
self.usage_duration = None |
| 83 |
4442e87 |
mahdim10 |
2y ago |
self.activation_deadline = None |
| 84 |
4442e87 |
mahdim10 |
2y ago |
|
| 85 |
4442e87 |
mahdim10 |
2y ago |
elif self.expire_strategy == UserExpireStrategy.NEVER: |
| 86 |
4442e87 |
mahdim10 |
2y ago |
# Set expire_date, usage_duration and activation_deadline to None if expire_strategy is NEVER |
| 87 |
4442e87 |
mahdim10 |
2y ago |
self.expire_date = None |
| 88 |
4442e87 |
mahdim10 |
2y ago |
self.usage_duration = None |
| 89 |
4442e87 |
mahdim10 |
2y ago |
self.activation_deadline = None |
| 90 |
4442e87 |
mahdim10 |
2y ago |
|
| 91 |
4442e87 |
mahdim10 |
2y ago |
return self |
| 92 |
4442e87 |
mahdim10 |
2y ago |
|
| 93 |
4d647dd |
Dawsh |
2y ago |
|
| 94 |
a47eb4c |
Dawsh |
2y ago |
class UserCreate(User): |
| 95 |
db68a58 |
Dawsh |
2y ago |
service_ids: list[int] = Field([]) |
| 96 |
01cdf2e |
Dawsh |
2y ago |
model_config = ConfigDict( |
| 97 |
01cdf2e |
Dawsh |
2y ago |
json_schema_extra={ |
| 98 |
01cdf2e |
Dawsh |
2y ago |
"example": { |
| 99 |
01cdf2e |
Dawsh |
2y ago |
"username": "user1234", |
| 100 |
a44fd3b |
mahdim10 |
2y ago |
"service_ids": [1, 2, 3], |
| 101 |
d377c4c |
Dawsh |
2y ago |
"expire_strategy": "start_on_first_use", |
| 102 |
d377c4c |
Dawsh |
2y ago |
"usage_duration": 86400 * 14, |
| 103 |
d377c4c |
Dawsh |
2y ago |
"activation_deadline": "2024-11-03T20:30:00", |
| 104 |
01cdf2e |
Dawsh |
2y ago |
"data_limit": 0, |
| 105 |
01cdf2e |
Dawsh |
2y ago |
"data_limit_reset_strategy": "no_reset", |
| 106 |
01cdf2e |
Dawsh |
2y ago |
"note": "", |
| 107 |
01cdf2e |
Dawsh |
2y ago |
} |
| 108 |
a47eb4c |
Dawsh |
2y ago |
} |
| 109 |
01cdf2e |
Dawsh |
2y ago |
) |
| 110 |
a47eb4c |
Dawsh |
2y ago |
|
| 111 |
a47eb4c |
Dawsh |
2y ago |
|
| 112 |
d377c4c |
Dawsh |
2y ago |
class UserModify(UserCreate): |
| 113 |
db68a58 |
Dawsh |
2y ago |
service_ids: list[int] | None = Field(None) |
| 114 |
d377c4c |
Dawsh |
2y ago |
data_limit_reset_strategy: UserDataUsageResetStrategy | None = Field(None) |
| 115 |
01cdf2e |
Dawsh |
2y ago |
model_config = ConfigDict( |
| 116 |
01cdf2e |
Dawsh |
2y ago |
json_schema_extra={ |
| 117 |
01cdf2e |
Dawsh |
2y ago |
"example": { |
| 118 |
01cdf2e |
Dawsh |
2y ago |
"username": "mammad1234", |
| 119 |
d377c4c |
Dawsh |
2y ago |
"service_ids": [1, 2, 3], |
| 120 |
d377c4c |
Dawsh |
2y ago |
"expire_strategy": "fixed_date", |
| 121 |
d377c4c |
Dawsh |
2y ago |
"expire_date": "2023-11-03T20:30:00", |
| 122 |
01cdf2e |
Dawsh |
2y ago |
"data_limit": 0, |
| 123 |
01cdf2e |
Dawsh |
2y ago |
"data_limit_reset_strategy": "no_reset", |
| 124 |
01cdf2e |
Dawsh |
2y ago |
"note": "", |
| 125 |
01cdf2e |
Dawsh |
2y ago |
} |
| 126 |
a47eb4c |
Dawsh |
2y ago |
} |
| 127 |
01cdf2e |
Dawsh |
2y ago |
) |
| 128 |
a47eb4c |
Dawsh |
2y ago |
|
| 129 |
a47eb4c |
Dawsh |
2y ago |
|
| 130 |
a47eb4c |
Dawsh |
2y ago |
class UserResponse(User): |
| 131 |
a47eb4c |
Dawsh |
2y ago |
id: int |
| 132 |
d377c4c |
Dawsh |
2y ago |
activated: bool |
| 133 |
d377c4c |
Dawsh |
2y ago |
is_active: bool |
| 134 |
d377c4c |
Dawsh |
2y ago |
expired: bool |
| 135 |
d377c4c |
Dawsh |
2y ago |
data_limit_reached: bool |
| 136 |
d377c4c |
Dawsh |
2y ago |
enabled: bool |
| 137 |
a47eb4c |
Dawsh |
2y ago |
used_traffic: int |
| 138 |
d377c4c |
Dawsh |
2y ago |
lifetime_used_traffic: int |
| 139 |
00d6be5 |
Erfan |
2y ago |
sub_revoked_at: datetime | None |
| 140 |
a47eb4c |
Dawsh |
2y ago |
created_at: datetime |
| 141 |
db68a58 |
Dawsh |
2y ago |
service_ids: list[int] |
| 142 |
4708fcb |
Dawsh |
2y ago |
subscription_url: str |
| 143 |
b4ec790 |
Dawsh |
2y ago |
owner_username: str | None |
| 144 |
c778675 |
Mardin |
2y ago |
traffic_reset_at: datetime | None |
| 145 |
9bfa731 |
Dawsh |
2y ago |
|
| 146 |
a47eb4c |
Dawsh |
2y ago |
model_config = ConfigDict(from_attributes=True) |
| 147 |
9bfa731 |
Dawsh |
2y ago |
|
| 148 |
a47eb4c |
Dawsh |
2y ago |
|
| 149 |
e6e6467 |
Dawsh |
2y ago |
class UserNodeUsageSeries(BaseModel): |
| 150 |
d377c4c |
Dawsh |
2y ago |
node_id: int | None = None |
| 151 |
a47eb4c |
Dawsh |
2y ago |
node_name: str |
| 152 |
e6e6467 |
Dawsh |
2y ago |
usages: list[tuple[int, int]] # list[UserUsage] |
| 153 |
a47eb4c |
Dawsh |
2y ago |
|
| 154 |
a47eb4c |
Dawsh |
2y ago |
|
| 155 |
e6e6467 |
Dawsh |
2y ago |
class UserUsageSeriesResponse(BaseModel): |
| 156 |
a47eb4c |
Dawsh |
2y ago |
username: str |
| 157 |
e6e6467 |
Dawsh |
2y ago |
node_usages: list[UserNodeUsageSeries] |
| 158 |
b15de9e |
Erfan |
2y ago |
total: int |