From 470165fc6cf1b51ec8f33ad9166a649a247f0c32 Mon Sep 17 00:00:00 2001
From: Maximilian Moser <maximilian.moser@tuwien.ac.at>
Date: Thu, 8 Jul 2021 16:39:12 +0200
Subject: [PATCH] Add more user-related cli commands

---
 invenio_utilities_tuw/cli/users.py | 62 ++++++++++++++++++++++++++++++
 invenio_utilities_tuw/cli/utils.py |  6 +++
 2 files changed, 68 insertions(+)

diff --git a/invenio_utilities_tuw/cli/users.py b/invenio_utilities_tuw/cli/users.py
index 6c96a6e..9e21faa 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 e8d9c57..f6b976e 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()
-- 
GitLab