Skip to content

Commit

Permalink
Feat(api): Adding the ability to calculate the consumption of admin u…
Browse files Browse the repository at this point in the history
…sers
  • Loading branch information
erfjab committed Sep 2, 2024
1 parent 2de1393 commit c2c98b7
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
52 changes: 52 additions & 0 deletions app/db/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,58 @@ def autodelete_expired_users(db: Session,
return expired_users


def get_all_users_usages(
db: Session, admin: Admin, start: datetime, end: datetime
) -> List[UserUsageResponse]:
"""
Retrieves usage data for all users associated with an admin within a specified time range.
This function calculates the total traffic used by users across different nodes,
including a "Master" node that represents the main core.
Args:
db (Session): Database session for querying.
admin (Admin): The admin user for which to retrieve user usage data.
start (datetime): The start date and time of the period to consider.
end (datetime): The end date and time of the period to consider.
Returns:
List[UserUsageResponse]: A list of UserUsageResponse objects, each representing
the usage data for a specific node or the main core.
"""
usages = {}

usages[0] = UserUsageResponse( # Main Core
node_id=None,
node_name="Master",
used_traffic=0
)

for node in db.query(Node).all():

usages[node.id] = UserUsageResponse(
node_id=node.id,
node_name=node.name,
used_traffic=0
)

admin_users = set(user.id for user in get_users(db=db, admins=admin))

cond = and_(
NodeUserUsage.created_at >= start,
NodeUserUsage.created_at <= end,
NodeUserUsage.user_id.in_(admin_users)
)

for v in db.query(NodeUserUsage).filter(cond):
try:
usages[v.node_id or 0].used_traffic += v.used_traffic
except KeyError:
pass

return list(usages.values())


def update_user_status(db: Session, dbuser: User, status: UserStatus) -> User:
"""
Updates a user's status and records the time of change.
Expand Down
3 changes: 3 additions & 0 deletions app/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,3 +335,6 @@ class UserUsageResponse(BaseModel):
class UserUsagesResponse(BaseModel):
username: str
usages: List[UserUsageResponse]

class UsersUsagesResponse(BaseModel):
usages: List[UserUsageResponse]
26 changes: 25 additions & 1 deletion app/routers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from app.db import Session, crud, get_db
from app.models.admin import Admin
from app.models.user import (UserCreate, UserModify, UserResponse,
UsersResponse, UserStatus, UserUsagesResponse)
UsersResponse, UserStatus, UserUsagesResponse, UsersUsagesResponse)
from app.utils import report
from app.dependencies import get_validated_user, validate_dates, get_expired_users_list

Expand Down Expand Up @@ -274,6 +274,30 @@ def get_user_usage(

return {"usages": usages, "username": dbuser.username}

@router.get("/users/usage", response_model=UsersUsagesResponse)
def get_users_usage(
start: datetime = Query(None, example="2024-01-01T00:00:00"),
end: datetime = Query(None, example="2024-01-31T23:59:59"),
db: Session = Depends(get_db),
owner: Union[List[str], None] = Query(None, alias="admin"),
admin: Admin = Depends(Admin.get_current)
):
"""Get all users usage"""
if not validate_dates(start, end):
raise HTTPException(status_code=400, detail="Invalid date range or format")

start_date = start or datetime.utcnow() - timedelta(days=30)
end_date = end or datetime.utcnow()

usages = crud.get_all_users_usages(
db=db,
start=start_date,
end=end_date,
admin=owner if admin.is_sudo else [admin.username]
)

return {"usages": usages}


@router.put("/user/{username}/set-owner", response_model=UserResponse)
def set_owner(
Expand Down

0 comments on commit c2c98b7

Please sign in to comment.