gitscope
← marzneshin / v0.3.0-alpha5 / 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(None, *utils.FLAGS["status"]),
 23    admin: Optional[str] = typer.Option(
 24        None, "--admin", "--owner", help="Search by owner admin's username"
 25    ),
 26):
 27    """
 28    Displays a table of users
 29
 30    NOTE: Sorting is not currently available.
 31    """
 32    with GetDB() as db:
 33        users: list[User] = crud.get_users(
 34            db=db,
 35            offset=offset,
 36            limit=limit,
 37            usernames=username,
 38            status=status,
 39            admin=crud.get_admin(db, admin) if admin else None,
 40        )
 41
 42        utils.print_table(
 43            table=Table(
 44                "ID",
 45                "Username",
 46                "Status",
 47                "Used traffic",
 48                "Data limit",
 49                "Reset strategy",
 50                "Expires at",
 51                "Owner",
 52            ),
 53            rows=[
 54                (
 55                    str(user.id),
 56                    user.username,
 57                    user.status.value,
 58                    readable_size(user.used_traffic),
 59                    readable_size(user.data_limit) if user.data_limit else "Unlimited",
 60                    user.data_limit_reset_strategy.value,
 61                    utils.readable_datetime(user.expire, include_time=False),
 62                    user.admin.username if user.admin else "",
 63                )
 64                for user in users
 65            ],
 66        )
 67
 68
 69@app.command(name="set-owner")
 70def set_owner(
 71    username: str = typer.Option(None, *utils.FLAGS["username"], prompt=True),
 72    admin: str = typer.Option(
 73        None, "--admin", "--owner", prompt=True, help="Admin's username"
 74    ),
 75    yes_to_all: bool = typer.Option(
 76        False, *utils.FLAGS["yes_to_all"], help="Skips confirmations"
 77    ),
 78):
 79    """
 80    Transfers user's ownership
 81
 82    NOTE: This command needs additional confirmation for users who already have an owner.
 83    """
 84    with GetDB() as db:
 85        user: User = utils.raise_if_falsy(
 86            crud.get_user(db, username=username), f'User "{username}" not found.'
 87        )
 88
 89        dbadmin = utils.raise_if_falsy(
 90            crud.get_admin(db, username=admin), f'Admin "{admin}" not found.'
 91        )
 92
 93        # Ask for confirmation if user already has an owner
 94        if (
 95            user.admin
 96            and not yes_to_all
 97            and not typer.confirm(
 98                f'{username}\'s current owner is "{user.admin.username}".'
 99                f' Are you sure about transferring its ownership to "{admin}"?'
100            )
101        ):
102            utils.error("Aborted.")
103
104        crud.set_owner(db, user, dbadmin)
105
106        utils.success(f'{username}\'s owner successfully set to "{admin}".')