diff --git a/invenio_utilities_tuw/cli/users.py b/invenio_utilities_tuw/cli/users.py index 6c96a6ecedf5e791d3364ce946a1fbdbacce5171..9e21faabf5844de75320eeca1615981b221d5037 100644 --- a/invenio_utilities_tuw/cli/users.py +++ b/invenio_utilities_tuw/cli/users.py @@ -13,6 +13,7 @@ from flask.cli import with_appcontext from invenio_accounts.models import User from .options import option_hide_user_roles, option_only_list_active_users +from .utils import get_user_by_identifier, similarity @click.group() @@ -39,3 +40,64 @@ def list_users(only_active, show_roles): fg = "green" if user.active else "red" click.secho(line, fg=fg) + + +@users.command("show") +@option_hide_user_roles +@click.argument("user_id") +@with_appcontext +def show_user(user_id, show_roles): + """Show more information about the specified user.""" + user = get_user_by_identifier(user_id) + full_name = f'"{user.profile.full_name}"' if user.profile else "N/A" + + line = "{} {} {}".format(user.id, user.email, full_name) + if show_roles: + line += " {}".format([r.name for r in user.roles]) + + fg = "green" if user.active else "red" + click.secho(line, fg=fg) + + +@users.command("find") +@option_only_list_active_users +@click.option( + "--full-name", + "-n", + "full_name", + is_flag=True, + default=False, + help="query the user's full name instead of the email address", +) +@click.argument("query") +@with_appcontext +def find_user(only_active, query, full_name): + """Find users with the given (or similar) email address.""" + users = User.query.order_by(User.id) + + if only_active: + users = users.filter_by(active=True) + + all_users = users.all() + if all_users: + + def query_similarity(user): + if full_name: + value = user.profile.full_name if user.profile else "" + else: + value = user.email + + return similarity(value, query) + + # find the best match among all users + match = max(all_users, default=None, key=query_similarity) + + if match: + fg = "green" if match.active else "red" + line = f"{match.id} {match.email}" + click.secho(line, fg=fg) + else: + click.secho("no match found.", fg="yellow") + + else: + click.secho("no users registered.", fg="yellow") diff --git a/invenio_utilities_tuw/cli/utils.py b/invenio_utilities_tuw/cli/utils.py index e8d9c572c2e7e84e42b7058cb61537955bedd79e..f6b976ec5f56c51efa9bac7453acd4ba764f71d9 100644 --- a/invenio_utilities_tuw/cli/utils.py +++ b/invenio_utilities_tuw/cli/utils.py @@ -9,6 +9,7 @@ """Utilities for the CLI commands.""" import json +from difflib import SequenceMatcher from invenio_access.permissions import system_identity from invenio_access.utils import get_identity @@ -162,3 +163,8 @@ def set_creatibutor_names(record_metadata): _set_creatibutor_name(contributor) return metadata + + +def similarity(a: str, b: str) -> float: + """Calculate the similarity between two strings.""" + return SequenceMatcher(None, a, b).ratio()