gitscope
← marzneshin / v0.3.1 / cli/user.py
https://dev.kronoz.win/r/marzneshin.git
cli/user.py · Python
Blame Raw
  1from typing import List, Optional
  2
  3import typer
  4from rich.table import Table
  5
  6from app.db import GetDB, crud
  7from app.db.models import User
  8from app.utils.system import readable_size
  9
 10from . import utils
 11
 12app = typer.Typer(no_args_is_help=True)
 13
 14
 15@app.command(name="list")
 16def list_users(
 17    offset: Optional[int] = typer.Option(None, *utils.FLAGS["offset"]),
 18    limit: Optional[int] = typer.Option(None, *utils.FLAGS["limit"]),
 19    username: Optional[List[str]] = typer.Option(
 20        None, *utils.FLAGS["username"], help="Search by username(s)"
 21    ),
 22    status: Optional[crud.UserStatus] = typer.Option(
 23        None, *utils.FLAGS["status"]
 24    ),
 25    admin: Optional[str] = typer.Option(
 26        None, "--admin", "--owner", help="Search by owner admin's username"
 27    ),
 28):
 29    """
 30    Displays a table of users
 31
 32    NOTE: Sorting is not currently available.
 33    """
 34    with GetDB() as db:
 35        users: list[User] = crud.get_users(
 36            db=db,
 37            offset=offset,
 38            limit=limit,
 39            usernames=username,
 40            status=status,
 41            admin=crud.get_admin(db, admin) if admin else None,
 42        )
 43
 44        utils.print_table(
 45            table=Table(
 46                "ID",
 47                "Username",
 48                "Status",
 49                "Used traffic",
 50                "Data limit",
 51                "Reset strategy",
 52                "Expires at",
 53                "Owner",
 54            ),
 55            rows=[
 56                (
 57                    str(user.id),
 58                    user.username,
 59                    user.status.value,
 60                    readable_size(user.used_traffic),
 61                    (
 62                        readable_size(user.data_limit)
 63                        if user.data_limit
 64                        else "Unlimited"
 65                    ),
 66                    user.data_limit_reset_strategy.value,
 67                    utils.readable_datetime(user.expire, include_time=False),
 68                    user.admin.username if user.admin else "",
 69                )
 70                for user in users
 71            ],
 72        )
 73
 74
 75@app.command(name="set-owner")
 76def set_owner(
 77    username: str = typer.Option(None, *utils.FLAGS["username"], prompt=True),
 78    admin: str = typer.Option(
 79        None, "--admin", "--owner", prompt=True, help="Admin's username"
 80    ),
 81    yes_to_all: bool = typer.Option(
 82        False, *utils.FLAGS["yes_to_all"], help="Skips confirmations"
 83    ),
 84):
 85    """
 86    Transfers user's ownership
 87
 88    NOTE: This command needs additional confirmation for users who already have an owner.
 89    """
 90    with GetDB() as db:
 91        user: User = utils.raise_if_falsy(
 92            crud.get_user(db, username=username),
 93            f'User "{username}" not found.',
 94        )
 95
 96        dbadmin = utils.raise_if_falsy(
 97            crud.get_admin(db, username=admin), f'Admin "{admin}" not found.'
 98        )
 99
100        # Ask for confirmation if user already has an owner
101        if (
102            user.admin
103            and not yes_to_all
104            and not typer.confirm(
105                f'{username}\'s current owner is "{user.admin.username}".'
106                f' Are you sure about transferring its ownership to "{admin}"?'
107            )
108        ):
109            utils.error("Aborted.")
110
111        crud.set_owner(db, user, dbadmin)
112
113        utils.success(f'{username}\'s owner successfully set to "{admin}".')