Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New dds user ls command #384

Merged
merged 5 commits into from
Mar 14, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,8 @@ Please add a _short_ line describing the PR you make, if the PR implements a spe
* Ask user confirmation for project abort, archive and delete([#357](https://github.com/ScilifelabDataCentre/dds_cli/pull/357))
* Replaced the default help messages of Click for the `--version` and `--help` options as requested in [issue 338](https://github.com/scilifelabdatacentre/dds_web/issues/338).
* Explicit error message for `--destination` when the path exists ([#371](https://github.com/ScilifelabDataCentre/dds_cli/pull/371))
* Escape variables that are printed in the cli (avoiding e.g. hidden text and bad coloring) ([#364](https://github.com/ScilifelabDataCentre/dds_cli/pull/364))
* Escape variables that are printed in the cli (avoiding e.g. hidden text and bad coloring) ([#364](https://github.com/ScilifelabDataCentre/dds_cli/pull/364))

## Sprint (2022-03-09 - 2022-03-23)

* New `dds user ls` command for listing unit users ([#384](https://github.com/ScilifelabDataCentre/dds_cli/pull/384))
1 change: 1 addition & 0 deletions dds_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class DDSEndpoint:
LIST_PROJ = BASE_ENDPOINT + "/proj/list"
LIST_FILES = BASE_ENDPOINT + "/files/list"
LIST_PROJ_USERS = BASE_ENDPOINT + "/proj/users"
LIST_UNIT_USERS = BASE_ENDPOINT + "/unit/users"

# Deleting urls
REMOVE_PROJ_CONT = BASE_ENDPOINT + "/proj/rm"
Expand Down
21 changes: 21 additions & 0 deletions dds_cli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,27 @@ def user_group_command(_):
# USER COMMANDS ******************************************************************** USER COMMANDS #
# ************************************************************************************************ #

# -- dds user ls -- #
@user_group_command.command(name="ls")
@click.pass_obj
def list_users(click_ctx, project):
i-oden marked this conversation as resolved.
Show resolved Hide resolved
"""List users."""
try:
with dds_cli.account_manager.AccountManager(
no_prompt=click_ctx.get("NO_PROMPT", False),
token_path=click_ctx.get("TOKEN_PATH"),
) as lister:
lister.list_unit_users()
except (
dds_cli.exceptions.AuthenticationError,
dds_cli.exceptions.ApiResponseError,
dds_cli.exceptions.ApiRequestError,
dds_cli.exceptions.DDSCLIException,
) as err:
LOG.error(err)
sys.exit(1)


# -- dds user add -- #
@user_group_command.command(name="add", no_args_is_help=True)
# Positional args
Expand Down
58 changes: 58 additions & 0 deletions dds_cli/account_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
import http
import requests
import rich.markup
from rich.table import Table
import simplejson

# Own modules
import dds_cli
import dds_cli.auth
import dds_cli.base
import dds_cli.exceptions
import dds_cli.utils


####################################################################################################
Expand Down Expand Up @@ -290,3 +292,59 @@ def fix_project_access(self, email, project):
),
)
)

def list_unit_users(self):
"""List all unit users within a specific unit."""
try:
response = requests.get(
dds_cli.DDSEndpoint.LIST_UNIT_USERS,
headers=self.token,
timeout=dds_cli.DDSEndpoint.TIMEOUT,
)
response_json = response.json()
except requests.exceptions.RequestException as err:
raise dds_cli.exceptions.ApiRequestError(message=str(err))
except simplejson.JSONDecodeError as err:
raise dds_cli.exceptions.ApiResponseError(message=str(err))

# Check if response is ok.
if not response.ok:
message = "Failed getting unit users from API"
if response.status_code == http.HTTPStatus.INTERNAL_SERVER_ERROR:
raise dds_cli.exceptions.ApiResponseError(message=f"{message}: {response.reason}")

raise dds_cli.exceptions.DDSCLIException(
message=f"{message}: {response_json.get('message', 'Unexpected error!')}"
)

# Get items from response
users = response_json.get("users")
keys = response_json.get("keys")
unit = response_json.get("unit")
if not users:
raise dds_cli.exceptions.ApiResponseError(message="No users returned.")

# Sort users according to name
users = sorted(users, key=lambda i: i["Name"])

# Create table
table = Table(
title=f"Unit Admins and Personnel within {f'unit: {unit}' or 'your unit'}.",
show_header=True,
header_style="bold",
show_footer=False,
caption="All users (Unit Personnel and Admins) within your unit.",
)

# Get columns
for key in keys:
table.add_column(key, justify="left", overflow="fold")

# Add rows
for row in users:
table.add_row(
*[rich.markup.escape(dds_cli.utils.format_api_response(row[x], x)) for x in keys]
)

# Print out table
dds_cli.utils.print_or_page(item=table)
11 changes: 2 additions & 9 deletions dds_cli/data_lister.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,18 +571,11 @@ def __print_project_table(self, sorted_projects, usage_info, total_size):
)

# Print to stdout if there are any lines
if table.columns:
# Use a pager if output is taller than the visible terminal
if len(sorted_projects) + 5 > dds_cli.utils.console.height:
with dds_cli.utils.console.pager():
dds_cli.utils.console.print(table)
else:
dds_cli.utils.console.print(table)
else:
raise exceptions.NoDataError("No projects found.")
dds_cli.utils.print_or_page(item=table)

# User listing
def __print_users_table(self, research_users):
# TODO: call on future list_project_users function, will be implemented for dds user ls --project
default_format = {"justify": "left", "style": "", "footer": "", "overflow": "fold"}
column_formatting = {
**{x: default_format for x in ["User Name", "Primary email", "Role"]},
Expand Down
16 changes: 16 additions & 0 deletions dds_cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ def format_api_response(response, key, magnitude=None, iec_standard=False):
if isinstance(response, str):
return response # pass the response if already a string

if isinstance(response, bool):
return ":white_heavy_check_mark:" if response else ":x:"

if isinstance(response, numbers.Number):
response = float(f"{response:.3g}")
mag = 0
Expand Down Expand Up @@ -192,3 +195,16 @@ def get_deletion_confirmation(action: str, project: str) -> bool:

proceed_deletion = rich.prompt.Confirm.ask(question)
return proceed_deletion


def print_or_page(item):
"""Paginate or print out depending on size of item."""
if isinstance(item, rich.table.Table):
if item.columns:
if item.row_count + 5 > dds_cli.utils.console.height:
with dds_cli.utils.console.pager():
dds_cli.utils.console.print(item)
else:
dds_cli.utils.console.print(item)
else:
raise dds_cli.exceptions.NoDataError("No users found.")