gitscope
← marzneshin / v0.3.0-alpha3 / app/routes/service.py
https://dev.kronoz.win/r/marzneshin.git
app/routes/service.py · Python
Blame Raw
 1import sqlalchemy
 2from fastapi import APIRouter, Depends, Query
 3from fastapi import HTTPException
 4from fastapi_pagination.customization import UseParamsFields, CustomizedPage
 5from fastapi_pagination.ext.sqlalchemy import paginate
 6from fastapi_pagination.links import Page
 7
 8from app import marznode
 9from app.db import crud
10from app.db.models import Service
11from app.dependencies import DBDep, sudo_admin
12from app.models.service import ServiceCreate, ServiceModify, ServiceResponse
13
14router = APIRouter(
15    prefix="/services", dependencies=[Depends(sudo_admin)], tags=["Service"]
16)
17
18
19@router.get("", response_model=Page[ServiceResponse])
20def get_services(db: DBDep, name: str = Query(None)):
21    query = db.query(Service)
22    if name:
23        query = query.filter(Service.name.ilike(f"%{name}%"))
24    return paginate(query)
25
26
27@router.post("", response_model=ServiceResponse)
28def add_service(new_service: ServiceCreate, db: DBDep):
29    """
30    Add a new service
31
32    - **name** service name
33    - **inbounds** list of inbound ids
34    """
35    try:
36        return crud.create_service(db, new_service)
37    except sqlalchemy.exc.IntegrityError:
38        db.rollback()
39        raise HTTPException(
40            status_code=409, detail="Service by this name already exists"
41        )
42
43
44@router.get("/{id}", response_model=ServiceResponse)
45def get_service(id: int, db: DBDep):
46    """
47    Get Service information with id
48    """
49    dbservice = crud.get_service(db, id)
50    if not dbservice:
51        raise HTTPException(status_code=404, detail="Service not found")
52
53    return dbservice
54
55
56@router.put("/{id}", response_model=ServiceResponse)
57async def modify_service(id: int, modification: ServiceModify, db: DBDep):
58    """
59    Modify Service
60
61    - **name** can be up to 64 characters
62    - **inbounds** list of inbound ids. if not specified no change will be applied;
63    in case of an empty list all inbounds would be removed.
64    """
65    # TODO: Update all affected users in nodes
66    dbservice = crud.get_service(db, id)
67    if not dbservice:
68        raise HTTPException(status_code=404, detail="Service not found")
69    old_inbounds = {(i.node_id, i.protocol, i.tag) for i in dbservice.inbounds}
70    try:
71        response = crud.update_service(db, dbservice, modification)
72    except sqlalchemy.exc.IntegrityError:
73        db.rollback()
74        raise HTTPException(status_code=409, detail="problem updating the service")
75    else:
76        for user in response.users:
77            await marznode.operations.update_user(user, old_inbounds=old_inbounds)
78        return response
79
80
81@router.delete("/{id}")
82def remove_service(id: int, db: DBDep):
83    dbservice = crud.get_service(db, id)
84    if not dbservice:
85        raise HTTPException(status_code=404, detail="Service not found")
86
87    crud.remove_service(db, dbservice)
88    return dict()