gitscope
https://dev.kronoz.win/r/marzneshin.git
app/db/crud.py · v0.3.0-alpha6
Source
1 12b255b Dawsh 2y ago import json
2 34a7612 Dawsh 2y ago import secrets
3 f446990 Dawsh 2y ago from datetime import datetime, timedelta
4 a47eb4c Dawsh 2y ago from enum import Enum
5 2de9d72 Dawsh 2y ago from typing import List, Optional, Tuple, Union
6 a47eb4c Dawsh 2y ago
7 512d183 Mrdn 2y ago from sqlalchemy import and_, delete, update, select
8 a47eb4c Dawsh 2y ago from sqlalchemy.orm import Session
9 a47eb4c Dawsh 2y ago
10 01cdf2e Dawsh 2y ago from app.db.models import (
11 01cdf2e Dawsh 2y ago JWT,
12 01cdf2e Dawsh 2y ago TLS,
13 01cdf2e Dawsh 2y ago Admin,
14 01cdf2e Dawsh 2y ago Node,
15 01cdf2e Dawsh 2y ago NodeUsage,
16 01cdf2e Dawsh 2y ago NodeUserUsage,
17 01cdf2e Dawsh 2y ago NotificationReminder,
18 01cdf2e Dawsh 2y ago InboundHost,
19 01cdf2e Dawsh 2y ago Service,
20 01cdf2e Dawsh 2y ago Inbound,
21 01cdf2e Dawsh 2y ago System,
22 01cdf2e Dawsh 2y ago User,
23 01cdf2e Dawsh 2y ago UserUsageResetLogs,
24 01cdf2e Dawsh 2y ago )
25 a47eb4c Dawsh 2y ago from app.models.admin import AdminCreate, AdminModify, AdminPartialModify
26 01cdf2e Dawsh 2y ago from app.models.node import NodeCreate, NodeModify, NodeStatus, NodeUsageResponse
27 a47eb4c Dawsh 2y ago from app.models.proxy import InboundHost as InboundHostModify
28 2de9d72 Dawsh 2y ago from app.models.service import Service as ServiceModify, ServiceCreate
29 01cdf2e Dawsh 2y ago from app.models.user import (
30 01cdf2e Dawsh 2y ago ReminderType,
31 01cdf2e Dawsh 2y ago UserCreate,
32 01cdf2e Dawsh 2y ago UserDataLimitResetStrategy,
33 01cdf2e Dawsh 2y ago UserModify,
34 01cdf2e Dawsh 2y ago UserStatus,
35 01cdf2e Dawsh 2y ago UserUsageResponse,
36 01cdf2e Dawsh 2y ago )
37 01cdf2e Dawsh 2y ago from app.utils.helpers import calculate_expiration_days, calculate_usage_percent
38 a47eb4c Dawsh 2y ago from config import NOTIFY_DAYS_LEFT, NOTIFY_REACHED_USAGE_PERCENT
39 a47eb4c Dawsh 2y ago
40 a47eb4c Dawsh 2y ago
41 a47eb4c Dawsh 2y ago def add_default_hosts(db: Session, inbounds: List[Inbound]):
42 01cdf2e Dawsh 2y ago hosts = [
43 01cdf2e Dawsh 2y ago InboundHost(
44 01cdf2e Dawsh 2y ago remark="🚀 Marz ({USERNAME}) [{PROTOCOL} - {TRANSPORT}]",
45 01cdf2e Dawsh 2y ago address="{SERVER_IP}",
46 01cdf2e Dawsh 2y ago inbound=i,
47 01cdf2e Dawsh 2y ago )
48 01cdf2e Dawsh 2y ago for i in inbounds
49 01cdf2e Dawsh 2y ago ]
50 a47eb4c Dawsh 2y ago db.add_all(hosts)
51 a47eb4c Dawsh 2y ago db.commit()
52 a47eb4c Dawsh 2y ago
53 a47eb4c Dawsh 2y ago
54 a47eb4c Dawsh 2y ago def assure_node_inbounds(db: Session, inbounds: List[Inbound], node_id: int):
55 01cdf2e Dawsh 2y ago current_tags = [
56 01cdf2e Dawsh 2y ago i[0]
57 01cdf2e Dawsh 2y ago for i in db.execute(
58 01cdf2e Dawsh 2y ago select(Inbound.tag).filter(Inbound.node_id == node_id)
59 01cdf2e Dawsh 2y ago ).all()
60 01cdf2e Dawsh 2y ago ]
61 512d183 Mrdn 2y ago updated_tags = set(i.tag for i in list(inbounds))
62 512d183 Mrdn 2y ago inbound_additions, tag_deletions = list(), set()
63 512d183 Mrdn 2y ago for tag in current_tags:
64 512d183 Mrdn 2y ago if tag not in updated_tags:
65 512d183 Mrdn 2y ago tag_deletions.add(tag)
66 01cdf2e Dawsh 2y ago db_inbounds = db.query(Inbound).where(
67 01cdf2e Dawsh 2y ago and_(Inbound.node_id == node_id, Inbound.tag.in_(tag_deletions))
68 01cdf2e Dawsh 2y ago )
69 512d183 Mrdn 2y ago for i in db_inbounds:
70 512d183 Mrdn 2y ago db.delete(i)
71 512d183 Mrdn 2y ago
72 512d183 Mrdn 2y ago for inb in inbounds:
73 512d183 Mrdn 2y ago if inb.tag in current_tags:
74 01cdf2e Dawsh 2y ago stmt = (
75 01cdf2e Dawsh 2y ago update(Inbound)
76 01cdf2e Dawsh 2y ago .where(and_(Inbound.node_id == node_id, Inbound.tag == inb.tag))
77 01cdf2e Dawsh 2y ago .values(protocol=json.loads(inb.config)["protocol"], config=inb.config)
78 a47eb4c Dawsh 2y ago )
79 512d183 Mrdn 2y ago db.execute(stmt)
80 512d183 Mrdn 2y ago else:
81 512d183 Mrdn 2y ago inbound_additions.append(inb)
82 01cdf2e Dawsh 2y ago new_inbounds = [
83 01cdf2e Dawsh 2y ago Inbound(
84 01cdf2e Dawsh 2y ago tag=inb.tag,
85 01cdf2e Dawsh 2y ago protocol=json.loads(inb.config)["protocol"],
86 01cdf2e Dawsh 2y ago config=inb.config,
87 01cdf2e Dawsh 2y ago node_id=node_id,
88 01cdf2e Dawsh 2y ago )
89 01cdf2e Dawsh 2y ago for inb in inbound_additions
90 01cdf2e Dawsh 2y ago ]
91 a47eb4c Dawsh 2y ago db.add_all(new_inbounds)
92 a47eb4c Dawsh 2y ago db.flush()
93 a47eb4c Dawsh 2y ago for i in new_inbounds:
94 2de9d72 Dawsh 2y ago db.refresh(i)
95 a47eb4c Dawsh 2y ago add_default_hosts(db, new_inbounds)
96 a47eb4c Dawsh 2y ago db.commit()
97 a47eb4c Dawsh 2y ago
98 a47eb4c Dawsh 2y ago
99 01cdf2e Dawsh 2y ago def get_node_users(
100 01cdf2e Dawsh 2y ago db: Session, node_id: Optional[int], statuses: Optional[List[UserStatus]] = None
101 01cdf2e Dawsh 2y ago ):
102 01cdf2e Dawsh 2y ago query = (
103 01cdf2e Dawsh 2y ago db.query(User.id, User.username, User.key, Inbound)
104 01cdf2e Dawsh 2y ago .distinct()
105 cba9caa Dawsh 2y ago .where(User.enabled is True)
106 01cdf2e Dawsh 2y ago .join(Inbound.services)
107 01cdf2e Dawsh 2y ago .join(Service.users)
108 01cdf2e Dawsh 2y ago .filter(Inbound.node_id == node_id)
109 01cdf2e Dawsh 2y ago )
110 12b255b Dawsh 2y ago if isinstance(statuses, list):
111 a47eb4c Dawsh 2y ago query = query.filter(User.status.in_(statuses))
112 a47eb4c Dawsh 2y ago return query.all()
113 a47eb4c Dawsh 2y ago
114 12b255b Dawsh 2y ago
115 a47eb4c Dawsh 2y ago def get_user_hosts(db: Session, user_id: int):
116 01cdf2e Dawsh 2y ago return (
117 01cdf2e Dawsh 2y ago db.query(InboundHost)
118 01cdf2e Dawsh 2y ago .distinct()
119 01cdf2e Dawsh 2y ago .join(User.services)
120 01cdf2e Dawsh 2y ago .join(Service.inbounds)
121 01cdf2e Dawsh 2y ago .join(Inbound.hosts)
122 01cdf2e Dawsh 2y ago .filter(User.id == user_id)
123 01cdf2e Dawsh 2y ago .all()
124 01cdf2e Dawsh 2y ago )
125 a47eb4c Dawsh 2y ago
126 12b255b Dawsh 2y ago
127 a47eb4c Dawsh 2y ago def get_inbound_hosts(db: Session, inbound_id: int) -> List[InboundHost]:
128 a47eb4c Dawsh 2y ago return db.query(InboundHost).filter(InboundHost.inbound_id == inbound_id).all()
129 a47eb4c Dawsh 2y ago
130 12b255b Dawsh 2y ago
131 a47eb4c Dawsh 2y ago def get_all_inbounds(db: Session):
132 a47eb4c Dawsh 2y ago return db.query(Inbound).all()
133 a47eb4c Dawsh 2y ago
134 a47eb4c Dawsh 2y ago
135 2de9d72 Dawsh 2y ago def get_inbound(db: Session, inbound_id: int) -> Inbound | None:
136 2de9d72 Dawsh 2y ago return db.query(Inbound).filter(Inbound.id == inbound_id).first()
137 a47eb4c Dawsh 2y ago
138 a47eb4c Dawsh 2y ago
139 2de9d72 Dawsh 2y ago def get_host(db: Session, host_id) -> InboundHost:
140 2de9d72 Dawsh 2y ago return db.query(InboundHost).filter(InboundHost.id == host_id).first()
141 a47eb4c Dawsh 2y ago
142 a47eb4c Dawsh 2y ago
143 a47eb4c Dawsh 2y ago def add_host(db: Session, inbound: Inbound, host: InboundHostModify):
144 2de9d72 Dawsh 2y ago host = InboundHost(
145 2de9d72 Dawsh 2y ago remark=host.remark,
146 2de9d72 Dawsh 2y ago address=host.address,
147 2de9d72 Dawsh 2y ago port=host.port,
148 2de9d72 Dawsh 2y ago path=host.path,
149 2de9d72 Dawsh 2y ago sni=host.sni,
150 2de9d72 Dawsh 2y ago host=host.host,
151 2de9d72 Dawsh 2y ago inbound=inbound,
152 2de9d72 Dawsh 2y ago security=host.security,
153 2de9d72 Dawsh 2y ago alpn=host.alpn,
154 01cdf2e Dawsh 2y ago fingerprint=host.fingerprint,
155 a47eb4c Dawsh 2y ago )
156 2de9d72 Dawsh 2y ago inbound.hosts.append(host)
157 a47eb4c Dawsh 2y ago db.commit()
158 2de9d72 Dawsh 2y ago db.refresh(host)
159 2de9d72 Dawsh 2y ago return host
160 2de9d72 Dawsh 2y ago
161 2de9d72 Dawsh 2y ago
162 2de9d72 Dawsh 2y ago def update_host(db: Session, db_host: InboundHost, host: InboundHostModify):
163 2de9d72 Dawsh 2y ago db_host.remark = host.remark
164 2de9d72 Dawsh 2y ago db_host.address = host.address
165 2de9d72 Dawsh 2y ago db_host.port = host.port
166 2de9d72 Dawsh 2y ago db_host.path = host.path
167 2de9d72 Dawsh 2y ago db_host.sni = host.sni
168 2de9d72 Dawsh 2y ago db_host.host = host.host
169 2de9d72 Dawsh 2y ago db_host.security = host.security
170 2de9d72 Dawsh 2y ago db_host.alpn = host.alpn
171 2de9d72 Dawsh 2y ago db_host.fingerprint = host.fingerprint
172 2de9d72 Dawsh 2y ago db.commit()
173 2de9d72 Dawsh 2y ago db.refresh(db_host)
174 2de9d72 Dawsh 2y ago return db_host
175 a47eb4c Dawsh 2y ago
176 a47eb4c Dawsh 2y ago
177 a47eb4c Dawsh 2y ago def get_user(db: Session, username: str):
178 a47eb4c Dawsh 2y ago return db.query(User).filter(User.username == username).first()
179 a47eb4c Dawsh 2y ago
180 a47eb4c Dawsh 2y ago
181 a47eb4c Dawsh 2y ago def get_user_by_id(db: Session, user_id: int):
182 a47eb4c Dawsh 2y ago return db.query(User).filter(User.id == user_id).first()
183 a47eb4c Dawsh 2y ago
184 a47eb4c Dawsh 2y ago
185 01cdf2e Dawsh 2y ago UsersSortingOptions = Enum(
186 01cdf2e Dawsh 2y ago "UsersSortingOptions",
187 01cdf2e Dawsh 2y ago {
188 01cdf2e Dawsh 2y ago "username": User.username.asc(),
189 01cdf2e Dawsh 2y ago "used_traffic": User.used_traffic.asc(),
190 01cdf2e Dawsh 2y ago "data_limit": User.data_limit.asc(),
191 01cdf2e Dawsh 2y ago "expire": User.expire.asc(),
192 01cdf2e Dawsh 2y ago "created_at": User.created_at.asc(),
193 01cdf2e Dawsh 2y ago "-username": User.username.desc(),
194 01cdf2e Dawsh 2y ago "-used_traffic": User.used_traffic.desc(),
195 01cdf2e Dawsh 2y ago "-data_limit": User.data_limit.desc(),
196 01cdf2e Dawsh 2y ago "-expire": User.expire.desc(),
197 01cdf2e Dawsh 2y ago "-created_at": User.created_at.desc(),
198 01cdf2e Dawsh 2y ago },
199 01cdf2e Dawsh 2y ago )
200 01cdf2e Dawsh 2y ago
201 01cdf2e Dawsh 2y ago
202 01cdf2e Dawsh 2y ago def get_users(
203 01cdf2e Dawsh 2y ago db: Session,
204 01cdf2e Dawsh 2y ago offset: Optional[int] = None,
205 01cdf2e Dawsh 2y ago limit: Optional[int] = None,
206 01cdf2e Dawsh 2y ago usernames: Optional[List[str]] = None,
207 01cdf2e Dawsh 2y ago status: Optional[Union[UserStatus, list]] = None,
208 01cdf2e Dawsh 2y ago sort: Optional[List[UsersSortingOptions]] = None,
209 01cdf2e Dawsh 2y ago admin: Optional[Admin] = None,
210 01cdf2e Dawsh 2y ago reset_strategy: Optional[Union[UserDataLimitResetStrategy, list]] = None,
211 01cdf2e Dawsh 2y ago return_with_count: bool = False,
212 01cdf2e Dawsh 2y ago ) -> Union[List[User], Tuple[List[User], int]]:
213 a47eb4c Dawsh 2y ago query = db.query(User)
214 a47eb4c Dawsh 2y ago
215 a47eb4c Dawsh 2y ago if usernames:
216 a47eb4c Dawsh 2y ago if len(usernames) == 1:
217 a47eb4c Dawsh 2y ago query = query.filter(User.username.ilike(f"%{usernames[0]}%"))
218 a47eb4c Dawsh 2y ago else:
219 a47eb4c Dawsh 2y ago query = query.filter(User.username.in_(usernames))
220 a47eb4c Dawsh 2y ago
221 a47eb4c Dawsh 2y ago if status:
222 a47eb4c Dawsh 2y ago if isinstance(status, list):
223 a47eb4c Dawsh 2y ago query = query.filter(User.status.in_(status))
224 a47eb4c Dawsh 2y ago else:
225 a47eb4c Dawsh 2y ago query = query.filter(User.status == status)
226 a47eb4c Dawsh 2y ago
227 a47eb4c Dawsh 2y ago if reset_strategy:
228 a47eb4c Dawsh 2y ago if isinstance(reset_strategy, list):
229 a47eb4c Dawsh 2y ago query = query.filter(User.data_limit_reset_strategy.in_(reset_strategy))
230 a47eb4c Dawsh 2y ago else:
231 a47eb4c Dawsh 2y ago query = query.filter(User.data_limit_reset_strategy == reset_strategy)
232 a47eb4c Dawsh 2y ago
233 a47eb4c Dawsh 2y ago if admin:
234 a47eb4c Dawsh 2y ago query = query.filter(User.admin == admin)
235 a47eb4c Dawsh 2y ago
236 a47eb4c Dawsh 2y ago # count it before applying limit and offset
237 a47eb4c Dawsh 2y ago if return_with_count:
238 a47eb4c Dawsh 2y ago count = query.count()
239 a47eb4c Dawsh 2y ago
240 a47eb4c Dawsh 2y ago if sort:
241 a47eb4c Dawsh 2y ago query = query.order_by(*(opt.value for opt in sort))
242 a47eb4c Dawsh 2y ago
243 a47eb4c Dawsh 2y ago if offset:
244 a47eb4c Dawsh 2y ago query = query.offset(offset)
245 a47eb4c Dawsh 2y ago if limit:
246 a47eb4c Dawsh 2y ago query = query.limit(limit)
247 a47eb4c Dawsh 2y ago
248 a47eb4c Dawsh 2y ago if return_with_count:
249 a47eb4c Dawsh 2y ago return query.all(), count
250 a47eb4c Dawsh 2y ago
251 a47eb4c Dawsh 2y ago return query.all()
252 a47eb4c Dawsh 2y ago
253 a47eb4c Dawsh 2y ago
254 01cdf2e Dawsh 2y ago def get_user_usages(
255 01cdf2e Dawsh 2y ago db: Session,
256 01cdf2e Dawsh 2y ago dbuser: User,
257 01cdf2e Dawsh 2y ago start: datetime,
258 01cdf2e Dawsh 2y ago end: datetime,
259 01cdf2e Dawsh 2y ago ) -> List[UserUsageResponse]:
260 eb74041 Dawsh 2y ago usages = dict()
261 a47eb4c Dawsh 2y ago
262 a47eb4c Dawsh 2y ago for node in db.query(Node).all():
263 a47eb4c Dawsh 2y ago usages[node.id] = UserUsageResponse(
264 01cdf2e Dawsh 2y ago node_id=node.id, node_name=node.name, used_traffic=0
265 a47eb4c Dawsh 2y ago )
266 a47eb4c Dawsh 2y ago
267 01cdf2e Dawsh 2y ago cond = and_(
268 01cdf2e Dawsh 2y ago NodeUserUsage.user_id == dbuser.id,
269 01cdf2e Dawsh 2y ago NodeUserUsage.created_at >= start,
270 01cdf2e Dawsh 2y ago NodeUserUsage.created_at <= end,
271 01cdf2e Dawsh 2y ago )
272 a47eb4c Dawsh 2y ago
273 a47eb4c Dawsh 2y ago for v in db.query(NodeUserUsage).filter(cond):
274 a47eb4c Dawsh 2y ago try:
275 a47eb4c Dawsh 2y ago usages[v.node_id or 0].used_traffic += v.used_traffic
276 a47eb4c Dawsh 2y ago except KeyError:
277 a47eb4c Dawsh 2y ago pass
278 a47eb4c Dawsh 2y ago
279 a47eb4c Dawsh 2y ago return list(usages.values())
280 a47eb4c Dawsh 2y ago
281 a47eb4c Dawsh 2y ago
282 a47eb4c Dawsh 2y ago def get_users_count(db: Session, status: UserStatus = None, admin: Admin = None):
283 a47eb4c Dawsh 2y ago query = db.query(User.id)
284 a47eb4c Dawsh 2y ago if admin:
285 a47eb4c Dawsh 2y ago query = query.filter(User.admin == admin)
286 a47eb4c Dawsh 2y ago if status:
287 a47eb4c Dawsh 2y ago query = query.filter(User.status == status)
288 a47eb4c Dawsh 2y ago return query.count()
289 a47eb4c Dawsh 2y ago
290 a47eb4c Dawsh 2y ago
291 a47eb4c Dawsh 2y ago def create_user(db: Session, user: UserCreate, admin: Admin = None):
292 a47eb4c Dawsh 2y ago dbuser = User(
293 a47eb4c Dawsh 2y ago username=user.username,
294 a47eb4c Dawsh 2y ago # proxies=proxies,
295 a47eb4c Dawsh 2y ago key=user.key,
296 01cdf2e Dawsh 2y ago services=db.query(Service)
297 01cdf2e Dawsh 2y ago .filter(Service.id.in_(user.services))
298 01cdf2e Dawsh 2y ago .all(), # user.services,
299 a47eb4c Dawsh 2y ago status=user.status,
300 a47eb4c Dawsh 2y ago data_limit=(user.data_limit or None),
301 a47eb4c Dawsh 2y ago expire=(user.expire or None),
302 a47eb4c Dawsh 2y ago admin=admin,
303 a47eb4c Dawsh 2y ago data_limit_reset_strategy=user.data_limit_reset_strategy,
304 a47eb4c Dawsh 2y ago note=user.note,
305 a47eb4c Dawsh 2y ago on_hold_expire_duration=(user.on_hold_expire_duration or None),
306 a47eb4c Dawsh 2y ago on_hold_timeout=(user.on_hold_timeout or None),
307 a47eb4c Dawsh 2y ago )
308 a47eb4c Dawsh 2y ago db.add(dbuser)
309 a47eb4c Dawsh 2y ago db.commit()
310 a47eb4c Dawsh 2y ago db.refresh(dbuser)
311 a47eb4c Dawsh 2y ago return dbuser
312 a47eb4c Dawsh 2y ago
313 a47eb4c Dawsh 2y ago
314 a47eb4c Dawsh 2y ago def remove_user(db: Session, dbuser: User):
315 a47eb4c Dawsh 2y ago db.delete(dbuser)
316 a47eb4c Dawsh 2y ago # db.query(User).filter_by(id=user_id).delete()
317 a47eb4c Dawsh 2y ago db.commit()
318 a47eb4c Dawsh 2y ago
319 a47eb4c Dawsh 2y ago
320 a47eb4c Dawsh 2y ago def update_user(db: Session, dbuser: User, modify: UserModify):
321 a47eb4c Dawsh 2y ago if modify.status is not None:
322 a47eb4c Dawsh 2y ago dbuser.status = modify.status
323 a47eb4c Dawsh 2y ago
324 a47eb4c Dawsh 2y ago if modify.data_limit is not None:
325 a418d26 dawsh 2y ago # in case there is modification to a user's data limit
326 a418d26 dawsh 2y ago dbuser.data_limit = modify.data_limit or None # set it to the new limit
327 a418d26 dawsh 2y ago if dbuser.status is not UserStatus.expired:
328 a418d26 dawsh 2y ago # in case the user isn't already disabled/expired
329 a47eb4c Dawsh 2y ago if not dbuser.data_limit or dbuser.used_traffic < dbuser.data_limit:
330 a418d26 dawsh 2y ago # in case the user is unlimited or hasn't reached the limit already
331 a47eb4c Dawsh 2y ago if dbuser.status != UserStatus.on_hold:
332 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.active
333 a47eb4c Dawsh 2y ago
334 01cdf2e Dawsh 2y ago if not dbuser.data_limit or (
335 01cdf2e Dawsh 2y ago calculate_usage_percent(dbuser.used_traffic, dbuser.data_limit)
336 01cdf2e Dawsh 2y ago < NOTIFY_REACHED_USAGE_PERCENT
337 01cdf2e Dawsh 2y ago ):
338 01cdf2e Dawsh 2y ago delete_notification_reminder_by_type(
339 01cdf2e Dawsh 2y ago db, dbuser.id, ReminderType.data_usage
340 01cdf2e Dawsh 2y ago )
341 a47eb4c Dawsh 2y ago else:
342 a418d26 dawsh 2y ago # the user has reached the new data limit
343 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.limited
344 a47eb4c Dawsh 2y ago
345 a47eb4c Dawsh 2y ago if modify.expire is not None:
346 01cdf2e Dawsh 2y ago dbuser.expire = modify.expire or None
347 a47eb4c Dawsh 2y ago if dbuser.status in (UserStatus.active, UserStatus.expired):
348 3b7feef Mrdn 2y ago if not dbuser.expire or dbuser.expire > datetime.utcnow():
349 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.active
350 01cdf2e Dawsh 2y ago if not dbuser.expire or (
351 01cdf2e Dawsh 2y ago calculate_expiration_days(dbuser.expire) > NOTIFY_DAYS_LEFT
352 01cdf2e Dawsh 2y ago ):
353 01cdf2e Dawsh 2y ago delete_notification_reminder_by_type(
354 01cdf2e Dawsh 2y ago db, dbuser.id, ReminderType.expiration_date
355 01cdf2e Dawsh 2y ago )
356 a47eb4c Dawsh 2y ago else:
357 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.expired
358 a47eb4c Dawsh 2y ago
359 a47eb4c Dawsh 2y ago if modify.note is not None:
360 a47eb4c Dawsh 2y ago dbuser.note = modify.note or None
361 a47eb4c Dawsh 2y ago
362 a47eb4c Dawsh 2y ago if modify.data_limit_reset_strategy is not None:
363 a47eb4c Dawsh 2y ago dbuser.data_limit_reset_strategy = modify.data_limit_reset_strategy.value
364 a47eb4c Dawsh 2y ago
365 a47eb4c Dawsh 2y ago if modify.on_hold_timeout is not None:
366 a47eb4c Dawsh 2y ago dbuser.on_hold_timeout = modify.on_hold_timeout
367 a47eb4c Dawsh 2y ago
368 a47eb4c Dawsh 2y ago if modify.on_hold_expire_duration is not None:
369 a47eb4c Dawsh 2y ago dbuser.on_hold_expire_duration = modify.on_hold_expire_duration
370 2de9d72 Dawsh 2y ago
371 a47eb4c Dawsh 2y ago if modify.services is not None:
372 01cdf2e Dawsh 2y ago dbuser.services = (
373 01cdf2e Dawsh 2y ago db.query(Service).filter(Service.id.in_(modify.services)).all()
374 01cdf2e Dawsh 2y ago )
375 a47eb4c Dawsh 2y ago dbuser.edit_at = datetime.utcnow()
376 a47eb4c Dawsh 2y ago
377 a47eb4c Dawsh 2y ago db.commit()
378 a47eb4c Dawsh 2y ago db.refresh(dbuser)
379 a47eb4c Dawsh 2y ago return dbuser
380 a47eb4c Dawsh 2y ago
381 a47eb4c Dawsh 2y ago
382 a47eb4c Dawsh 2y ago def reset_user_data_usage(db: Session, dbuser: User):
383 a47eb4c Dawsh 2y ago usage_log = UserUsageResetLogs(
384 a47eb4c Dawsh 2y ago user=dbuser,
385 a47eb4c Dawsh 2y ago used_traffic_at_reset=dbuser.used_traffic,
386 a47eb4c Dawsh 2y ago )
387 a47eb4c Dawsh 2y ago db.add(usage_log)
388 a47eb4c Dawsh 2y ago
389 a47eb4c Dawsh 2y ago dbuser.used_traffic = 0
390 a47eb4c Dawsh 2y ago dbuser.node_usages.clear()
391 6da1b8a Dawsh 2y ago if dbuser.status == UserStatus.limited:
392 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.active.value
393 a47eb4c Dawsh 2y ago db.add(dbuser)
394 a47eb4c Dawsh 2y ago
395 a47eb4c Dawsh 2y ago db.commit()
396 a47eb4c Dawsh 2y ago db.refresh(dbuser)
397 a47eb4c Dawsh 2y ago return dbuser
398 a47eb4c Dawsh 2y ago
399 a47eb4c Dawsh 2y ago
400 a47eb4c Dawsh 2y ago def revoke_user_sub(db: Session, dbuser: User):
401 34a7612 Dawsh 2y ago dbuser.key = secrets.token_hex(16)
402 a47eb4c Dawsh 2y ago db.commit()
403 a47eb4c Dawsh 2y ago db.refresh(dbuser)
404 a47eb4c Dawsh 2y ago return dbuser
405 a47eb4c Dawsh 2y ago
406 a47eb4c Dawsh 2y ago
407 a47eb4c Dawsh 2y ago def update_user_sub(db: Session, dbuser: User, user_agent: str):
408 a47eb4c Dawsh 2y ago dbuser.sub_updated_at = datetime.utcnow()
409 a47eb4c Dawsh 2y ago dbuser.sub_last_user_agent = user_agent
410 a47eb4c Dawsh 2y ago
411 a47eb4c Dawsh 2y ago db.commit()
412 a47eb4c Dawsh 2y ago db.refresh(dbuser)
413 a47eb4c Dawsh 2y ago return dbuser
414 a47eb4c Dawsh 2y ago
415 a47eb4c Dawsh 2y ago
416 a47eb4c Dawsh 2y ago def reset_all_users_data_usage(db: Session, admin: Optional[Admin] = None):
417 a47eb4c Dawsh 2y ago query = db.query(User)
418 a47eb4c Dawsh 2y ago
419 a47eb4c Dawsh 2y ago if admin:
420 a47eb4c Dawsh 2y ago query = query.filter(User.admin == admin)
421 a47eb4c Dawsh 2y ago
422 a47eb4c Dawsh 2y ago for dbuser in query.all():
423 a47eb4c Dawsh 2y ago dbuser.used_traffic = 0
424 01cdf2e Dawsh 2y ago if dbuser.status not in [
425 01cdf2e Dawsh 2y ago UserStatus.on_hold,
426 01cdf2e Dawsh 2y ago UserStatus.expired,
427 01cdf2e Dawsh 2y ago ]:
428 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.active
429 a47eb4c Dawsh 2y ago dbuser.usage_logs.clear()
430 a47eb4c Dawsh 2y ago dbuser.node_usages.clear()
431 a47eb4c Dawsh 2y ago db.add(dbuser)
432 a47eb4c Dawsh 2y ago
433 a47eb4c Dawsh 2y ago db.commit()
434 a47eb4c Dawsh 2y ago
435 a47eb4c Dawsh 2y ago
436 a47eb4c Dawsh 2y ago def update_user_status(db: Session, dbuser: User, status: UserStatus):
437 a47eb4c Dawsh 2y ago dbuser.status = status
438 a47eb4c Dawsh 2y ago db.commit()
439 a47eb4c Dawsh 2y ago db.refresh(dbuser)
440 a47eb4c Dawsh 2y ago return dbuser
441 a47eb4c Dawsh 2y ago
442 a47eb4c Dawsh 2y ago
443 a47eb4c Dawsh 2y ago def set_owner(db: Session, dbuser: User, admin: Admin):
444 a47eb4c Dawsh 2y ago dbuser.admin = admin
445 a47eb4c Dawsh 2y ago db.commit()
446 a47eb4c Dawsh 2y ago db.refresh(dbuser)
447 a47eb4c Dawsh 2y ago return dbuser
448 a47eb4c Dawsh 2y ago
449 a47eb4c Dawsh 2y ago
450 a47eb4c Dawsh 2y ago def start_user_expire(db: Session, dbuser: User):
451 f446990 Dawsh 2y ago expire = datetime.utcnow() + timedelta(seconds=dbuser.on_hold_expire_duration)
452 a47eb4c Dawsh 2y ago dbuser.expire = expire
453 a47eb4c Dawsh 2y ago db.commit()
454 a47eb4c Dawsh 2y ago db.refresh(dbuser)
455 a47eb4c Dawsh 2y ago return dbuser
456 a47eb4c Dawsh 2y ago
457 a47eb4c Dawsh 2y ago
458 a47eb4c Dawsh 2y ago def get_system_usage(db: Session):
459 a47eb4c Dawsh 2y ago return db.query(System).first()
460 a47eb4c Dawsh 2y ago
461 a47eb4c Dawsh 2y ago
462 a47eb4c Dawsh 2y ago def get_jwt_secret_key(db: Session):
463 a47eb4c Dawsh 2y ago return db.query(JWT).first().secret_key
464 a47eb4c Dawsh 2y ago
465 a47eb4c Dawsh 2y ago
466 a47eb4c Dawsh 2y ago def get_tls_certificate(db: Session):
467 a47eb4c Dawsh 2y ago return db.query(TLS).first()
468 a47eb4c Dawsh 2y ago
469 a47eb4c Dawsh 2y ago
470 a47eb4c Dawsh 2y ago def get_admin(db: Session, username: str):
471 a47eb4c Dawsh 2y ago return db.query(Admin).filter(Admin.username == username).first()
472 a47eb4c Dawsh 2y ago
473 a47eb4c Dawsh 2y ago
474 a47eb4c Dawsh 2y ago def create_admin(db: Session, admin: AdminCreate):
475 a47eb4c Dawsh 2y ago dbadmin = Admin(
476 a47eb4c Dawsh 2y ago username=admin.username,
477 a47eb4c Dawsh 2y ago hashed_password=admin.hashed_password,
478 01cdf2e Dawsh 2y ago is_sudo=admin.is_sudo,
479 a47eb4c Dawsh 2y ago )
480 a47eb4c Dawsh 2y ago db.add(dbadmin)
481 a47eb4c Dawsh 2y ago db.commit()
482 a47eb4c Dawsh 2y ago db.refresh(dbadmin)
483 a47eb4c Dawsh 2y ago return dbadmin
484 a47eb4c Dawsh 2y ago
485 a47eb4c Dawsh 2y ago
486 a47eb4c Dawsh 2y ago def update_admin(db: Session, dbadmin: Admin, modified_admin: AdminModify):
487 a47eb4c Dawsh 2y ago dbadmin.is_sudo = modified_admin.is_sudo
488 a47eb4c Dawsh 2y ago if dbadmin.hashed_password != modified_admin.hashed_password:
489 a47eb4c Dawsh 2y ago dbadmin.hashed_password = modified_admin.hashed_password
490 a47eb4c Dawsh 2y ago dbadmin.password_reset_at = datetime.utcnow()
491 a47eb4c Dawsh 2y ago db.commit()
492 a47eb4c Dawsh 2y ago db.refresh(dbadmin)
493 2de9d72 Dawsh 2y ago return dbadmin
494 a47eb4c Dawsh 2y ago
495 a47eb4c Dawsh 2y ago
496 01cdf2e Dawsh 2y ago def partial_update_admin(
497 01cdf2e Dawsh 2y ago db: Session, dbadmin: Admin, modified_admin: AdminPartialModify
498 01cdf2e Dawsh 2y ago ):
499 a47eb4c Dawsh 2y ago if modified_admin.is_sudo is not None:
500 a47eb4c Dawsh 2y ago dbadmin.is_sudo = modified_admin.is_sudo
501 01cdf2e Dawsh 2y ago if (
502 01cdf2e Dawsh 2y ago modified_admin.password is not None
503 01cdf2e Dawsh 2y ago and dbadmin.hashed_password != modified_admin.hashed_password
504 01cdf2e Dawsh 2y ago ):
505 a47eb4c Dawsh 2y ago dbadmin.hashed_password = modified_admin.hashed_password
506 a47eb4c Dawsh 2y ago dbadmin.password_reset_at = datetime.utcnow()
507 a47eb4c Dawsh 2y ago
508 a47eb4c Dawsh 2y ago db.commit()
509 a47eb4c Dawsh 2y ago db.refresh(dbadmin)
510 a47eb4c Dawsh 2y ago return dbadmin
511 a47eb4c Dawsh 2y ago
512 a47eb4c Dawsh 2y ago
513 a47eb4c Dawsh 2y ago def remove_admin(db: Session, dbadmin: Admin):
514 a47eb4c Dawsh 2y ago db.delete(dbadmin)
515 a47eb4c Dawsh 2y ago db.commit()
516 a47eb4c Dawsh 2y ago return dbadmin
517 a47eb4c Dawsh 2y ago
518 a47eb4c Dawsh 2y ago
519 01cdf2e Dawsh 2y ago def get_admins(
520 01cdf2e Dawsh 2y ago db: Session,
521 01cdf2e Dawsh 2y ago offset: Optional[int] = None,
522 01cdf2e Dawsh 2y ago limit: Optional[int] = None,
523 01cdf2e Dawsh 2y ago username: Optional[str] = None,
524 01cdf2e Dawsh 2y ago ):
525 a47eb4c Dawsh 2y ago query = db.query(Admin)
526 a47eb4c Dawsh 2y ago if username:
527 01cdf2e Dawsh 2y ago query = query.filter(Admin.username.ilike(f"%{username}%"))
528 a47eb4c Dawsh 2y ago if offset:
529 a47eb4c Dawsh 2y ago query = query.offset(offset)
530 a47eb4c Dawsh 2y ago if limit:
531 a47eb4c Dawsh 2y ago query = query.limit(limit)
532 a47eb4c Dawsh 2y ago return query.all()
533 a47eb4c Dawsh 2y ago
534 a47eb4c Dawsh 2y ago
535 ee1351a Dawsh 2y ago def create_service(db: Session, service: ServiceCreate) -> Service:
536 a47eb4c Dawsh 2y ago dbservice = Service(
537 a47eb4c Dawsh 2y ago name=service.name,
538 a47eb4c Dawsh 2y ago inbounds=db.query(Inbound).filter(Inbound.id.in_(service.inbounds)).all(),
539 01cdf2e Dawsh 2y ago users=db.query(User).filter(User.id.in_(service.users)).all(),
540 2de9d72 Dawsh 2y ago )
541 a47eb4c Dawsh 2y ago db.add(dbservice)
542 a47eb4c Dawsh 2y ago db.commit()
543 a47eb4c Dawsh 2y ago db.refresh(dbservice)
544 a47eb4c Dawsh 2y ago return dbservice
545 a47eb4c Dawsh 2y ago
546 a47eb4c Dawsh 2y ago
547 ee1351a Dawsh 2y ago def get_service(db: Session, service_id: id) -> Service:
548 ee1351a Dawsh 2y ago return db.query(Service).filter(Service.id == service_id).first()
549 a47eb4c Dawsh 2y ago
550 12b255b Dawsh 2y ago
551 a47eb4c Dawsh 2y ago def get_services(db: Session) -> List[Service]:
552 a47eb4c Dawsh 2y ago return db.query(Service).all()
553 a47eb4c Dawsh 2y ago
554 12b255b Dawsh 2y ago
555 ee1351a Dawsh 2y ago def update_service(db: Session, db_service: Service, modification: ServiceModify):
556 ee1351a Dawsh 2y ago if modification.name is not None:
557 ee1351a Dawsh 2y ago db_service.name = modification.name
558 ee1351a Dawsh 2y ago
559 ee1351a Dawsh 2y ago if modification.inbounds is not None:
560 01cdf2e Dawsh 2y ago db_service.inbounds = (
561 01cdf2e Dawsh 2y ago db.query(Inbound).filter(Inbound.id.in_(modification.inbounds)).all()
562 01cdf2e Dawsh 2y ago )
563 ee1351a Dawsh 2y ago
564 ee1351a Dawsh 2y ago db.commit()
565 ee1351a Dawsh 2y ago db.refresh(db_service)
566 ee1351a Dawsh 2y ago return db_service
567 ee1351a Dawsh 2y ago
568 ee1351a Dawsh 2y ago
569 ee1351a Dawsh 2y ago def remove_service(db: Session, db_service: Service):
570 ee1351a Dawsh 2y ago db.delete(db_service)
571 ee1351a Dawsh 2y ago db.commit()
572 ee1351a Dawsh 2y ago return db_service
573 ee1351a Dawsh 2y ago
574 ee1351a Dawsh 2y ago
575 a47eb4c Dawsh 2y ago def get_node(db: Session, name: str):
576 a47eb4c Dawsh 2y ago return db.query(Node).filter(Node.name == name).first()
577 a47eb4c Dawsh 2y ago
578 a47eb4c Dawsh 2y ago
579 a47eb4c Dawsh 2y ago def get_node_by_id(db: Session, node_id: int):
580 a47eb4c Dawsh 2y ago return db.query(Node).filter(Node.id == node_id).first()
581 a47eb4c Dawsh 2y ago
582 a47eb4c Dawsh 2y ago
583 01cdf2e Dawsh 2y ago def get_nodes(
584 01cdf2e Dawsh 2y ago db: Session, status: Optional[Union[NodeStatus, list]] = None, enabled: bool = None
585 01cdf2e Dawsh 2y ago ):
586 a47eb4c Dawsh 2y ago query = db.query(Node)
587 a47eb4c Dawsh 2y ago
588 a47eb4c Dawsh 2y ago if status:
589 a47eb4c Dawsh 2y ago if isinstance(status, list):
590 a47eb4c Dawsh 2y ago query = query.filter(Node.status.in_(status))
591 a47eb4c Dawsh 2y ago else:
592 a47eb4c Dawsh 2y ago query = query.filter(Node.status == status)
593 a47eb4c Dawsh 2y ago
594 a47eb4c Dawsh 2y ago if enabled:
595 a47eb4c Dawsh 2y ago query = query.filter(Node.status != NodeStatus.disabled)
596 a47eb4c Dawsh 2y ago
597 a47eb4c Dawsh 2y ago return query.all()
598 a47eb4c Dawsh 2y ago
599 a47eb4c Dawsh 2y ago
600 01cdf2e Dawsh 2y ago def get_nodes_usage(
601 01cdf2e Dawsh 2y ago db: Session, start: datetime, end: datetime
602 01cdf2e Dawsh 2y ago ) -> List[NodeUsageResponse]:
603 12b255b Dawsh 2y ago usages = dict()
604 a47eb4c Dawsh 2y ago
605 a47eb4c Dawsh 2y ago usages[0] = NodeUsageResponse( # Main Core
606 01cdf2e Dawsh 2y ago node_id=None, node_name="Master", uplink=0, downlink=0
607 a47eb4c Dawsh 2y ago )
608 a47eb4c Dawsh 2y ago for node in db.query(Node).all():
609 a47eb4c Dawsh 2y ago usages[node.id] = NodeUsageResponse(
610 01cdf2e Dawsh 2y ago node_id=node.id, node_name=node.name, uplink=0, downlink=0
611 a47eb4c Dawsh 2y ago )
612 a47eb4c Dawsh 2y ago
613 a47eb4c Dawsh 2y ago cond = and_(NodeUsage.created_at >= start, NodeUsage.created_at <= end)
614 a47eb4c Dawsh 2y ago
615 a47eb4c Dawsh 2y ago for v in db.query(NodeUsage).filter(cond):
616 a47eb4c Dawsh 2y ago try:
617 a47eb4c Dawsh 2y ago usages[v.node_id or 0].uplink += v.uplink
618 a47eb4c Dawsh 2y ago usages[v.node_id or 0].downlink += v.downlink
619 a47eb4c Dawsh 2y ago except KeyError:
620 a47eb4c Dawsh 2y ago pass
621 a47eb4c Dawsh 2y ago
622 a47eb4c Dawsh 2y ago return list(usages.values())
623 a47eb4c Dawsh 2y ago
624 a47eb4c Dawsh 2y ago
625 a47eb4c Dawsh 2y ago def create_node(db: Session, node: NodeCreate):
626 01cdf2e Dawsh 2y ago dbnode = Node(
627 01cdf2e Dawsh 2y ago name=node.name,
628 01cdf2e Dawsh 2y ago address=node.address,
629 01cdf2e Dawsh 2y ago port=node.port,
630 01cdf2e Dawsh 2y ago connection_backend=node.connection_backend,
631 01cdf2e Dawsh 2y ago )
632 a47eb4c Dawsh 2y ago
633 a47eb4c Dawsh 2y ago db.add(dbnode)
634 a47eb4c Dawsh 2y ago db.commit()
635 a47eb4c Dawsh 2y ago db.refresh(dbnode)
636 a47eb4c Dawsh 2y ago return dbnode
637 a47eb4c Dawsh 2y ago
638 a47eb4c Dawsh 2y ago
639 a47eb4c Dawsh 2y ago def remove_node(db: Session, dbnode: Node):
640 a47eb4c Dawsh 2y ago db.delete(dbnode)
641 a47eb4c Dawsh 2y ago db.commit()
642 a47eb4c Dawsh 2y ago return dbnode
643 a47eb4c Dawsh 2y ago
644 a47eb4c Dawsh 2y ago
645 a47eb4c Dawsh 2y ago def update_node(db: Session, dbnode: Node, modify: NodeModify):
646 a47eb4c Dawsh 2y ago if modify.name is not None:
647 a47eb4c Dawsh 2y ago dbnode.name = modify.name
648 a47eb4c Dawsh 2y ago
649 a47eb4c Dawsh 2y ago if modify.address is not None:
650 a47eb4c Dawsh 2y ago dbnode.address = modify.address
651 a47eb4c Dawsh 2y ago
652 a47eb4c Dawsh 2y ago if modify.port is not None:
653 a47eb4c Dawsh 2y ago dbnode.port = modify.port
654 a47eb4c Dawsh 2y ago
655 a47eb4c Dawsh 2y ago if modify.status is NodeStatus.disabled:
656 a47eb4c Dawsh 2y ago dbnode.status = modify.status
657 a47eb4c Dawsh 2y ago dbnode.xray_version = None
658 a47eb4c Dawsh 2y ago dbnode.message = None
659 a47eb4c Dawsh 2y ago else:
660 12b255b Dawsh 2y ago dbnode.status = NodeStatus.unhealthy
661 a47eb4c Dawsh 2y ago
662 a47eb4c Dawsh 2y ago if modify.usage_coefficient:
663 a47eb4c Dawsh 2y ago dbnode.usage_coefficient = modify.usage_coefficient
664 a47eb4c Dawsh 2y ago
665 a47eb4c Dawsh 2y ago db.commit()
666 a47eb4c Dawsh 2y ago db.refresh(dbnode)
667 a47eb4c Dawsh 2y ago return dbnode
668 a47eb4c Dawsh 2y ago
669 a47eb4c Dawsh 2y ago
670 01cdf2e Dawsh 2y ago def update_node_status(
671 01cdf2e Dawsh 2y ago db: Session,
672 01cdf2e Dawsh 2y ago node_id: int,
673 01cdf2e Dawsh 2y ago status: NodeStatus,
674 01cdf2e Dawsh 2y ago message: str = None,
675 01cdf2e Dawsh 2y ago version: str = None,
676 01cdf2e Dawsh 2y ago ):
677 f6a32ea Dawsh 2y ago db_node = db.query(Node).where(Node.id == node_id).first()
678 f6a32ea Dawsh 2y ago db_node.status = status
679 f6a32ea Dawsh 2y ago if message:
680 f6a32ea Dawsh 2y ago db_node.message = message
681 f6a32ea Dawsh 2y ago db_node.last_status_change = datetime.utcnow()
682 a47eb4c Dawsh 2y ago db.commit()
683 a47eb4c Dawsh 2y ago
684 a47eb4c Dawsh 2y ago
685 a47eb4c Dawsh 2y ago def create_notification_reminder(
686 01cdf2e Dawsh 2y ago db: Session, reminder_type: ReminderType, expires_at: datetime, user_id: int
687 01cdf2e Dawsh 2y ago ) -> NotificationReminder:
688 01cdf2e Dawsh 2y ago reminder = NotificationReminder(
689 01cdf2e Dawsh 2y ago type=reminder_type, expires_at=expires_at, user_id=user_id
690 01cdf2e Dawsh 2y ago )
691 a47eb4c Dawsh 2y ago db.add(reminder)
692 a47eb4c Dawsh 2y ago db.commit()
693 a47eb4c Dawsh 2y ago db.refresh(reminder)
694 a47eb4c Dawsh 2y ago return reminder
695 a47eb4c Dawsh 2y ago
696 a47eb4c Dawsh 2y ago
697 a47eb4c Dawsh 2y ago def get_notification_reminder(
698 01cdf2e Dawsh 2y ago db: Session,
699 01cdf2e Dawsh 2y ago user_id: int,
700 01cdf2e Dawsh 2y ago reminder_type: ReminderType,
701 12b255b Dawsh 2y ago ) -> Optional[NotificationReminder]:
702 01cdf2e Dawsh 2y ago reminder = (
703 01cdf2e Dawsh 2y ago db.query(NotificationReminder)
704 01cdf2e Dawsh 2y ago .filter(NotificationReminder.user_id == user_id)
705 01cdf2e Dawsh 2y ago .filter(NotificationReminder.type == reminder_type)
706 01cdf2e Dawsh 2y ago .first()
707 01cdf2e Dawsh 2y ago )
708 a47eb4c Dawsh 2y ago if reminder is None:
709 a47eb4c Dawsh 2y ago return
710 a47eb4c Dawsh 2y ago if reminder.expires_at and reminder.expires_at < datetime.utcnow():
711 a47eb4c Dawsh 2y ago db.delete(reminder)
712 a47eb4c Dawsh 2y ago db.commit()
713 a47eb4c Dawsh 2y ago return
714 a47eb4c Dawsh 2y ago return reminder
715 a47eb4c Dawsh 2y ago
716 a47eb4c Dawsh 2y ago
717 01cdf2e Dawsh 2y ago def delete_notification_reminder_by_type(
718 01cdf2e Dawsh 2y ago db: Session, user_id: int, reminder_type: ReminderType
719 01cdf2e Dawsh 2y ago ) -> None:
720 a47eb4c Dawsh 2y ago """Deletes notification reminder filtered by user_id and type if exists"""
721 a47eb4c Dawsh 2y ago stmt = delete(NotificationReminder).where(
722 a47eb4c Dawsh 2y ago NotificationReminder.user_id == user_id,
723 a47eb4c Dawsh 2y ago NotificationReminder.type == reminder_type,
724 a47eb4c Dawsh 2y ago )
725 a47eb4c Dawsh 2y ago db.execute(stmt)
726 a47eb4c Dawsh 2y ago db.commit()
727 a47eb4c Dawsh 2y ago return
728 a47eb4c Dawsh 2y ago
729 a47eb4c Dawsh 2y ago
730 a47eb4c Dawsh 2y ago def delete_notification_reminder(db: Session, dbreminder: NotificationReminder) -> None:
731 a47eb4c Dawsh 2y ago db.delete(dbreminder)
732 a47eb4c Dawsh 2y ago db.commit()
733 a47eb4c Dawsh 2y ago return