From 382ad7708eb5dadff30a89da33f2fba9f53cd8c6 Mon Sep 17 00:00:00 2001 From: Xithrius Date: Wed, 4 Nov 2020 15:43:22 -0800 Subject: User command gets verification time and message count. --- bot/exts/info/information.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 5aaf85e5a..c83dfadc5 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -6,6 +6,7 @@ from collections import Counter, defaultdict from string import Template from typing import Any, Mapping, Optional, Tuple, Union +from dateutil import parser from discord import ChannelType, Colour, Embed, Guild, Message, Role, Status, utils from discord.abc import GuildChannel from discord.ext.commands import BucketType, Cog, Context, Paginator, command, group, has_any_role @@ -21,7 +22,6 @@ from bot.utils.time import time_since log = logging.getLogger(__name__) - STATUS_EMOTES = { Status.offline: constants.Emojis.status_offline, Status.dnd: constants.Emojis.status_dnd, @@ -254,6 +254,7 @@ class Information(Cog): if is_mod_channel(ctx.channel): fields.append(await self.expanded_user_infraction_counts(user)) fields.append(await self.user_nomination_counts(user)) + fields.append(await self.user_verification_and_messages(user)) else: fields.append(await self.basic_user_infraction_counts(user)) @@ -354,6 +355,25 @@ class Information(Cog): return "Nominations", "\n".join(output) + async def user_verification_and_messages(self, user: FetchedMember) -> Tuple[str, str]: + """Gets the time of verification and amount of messages for `member`.""" + user_activity = await self.bot.api_client.get(f'bot/users/{user.id}/metricity_data') + + activity_output = [] + + if user_activity['verified_at'] is not None: + verified_delta_formatted = time_since(parser.isoparse(user_activity['verified_at']), max_units=3) + activity_output.append(f'This user verified {verified_delta_formatted}') + else: + activity_output.append('This user is not verified.') + + if user_activity['total_messages']: + activity_output.append(f"This user has a total of {user_activity['total_messages']} messages.") + else: + activity_output.append(f"This user has not sent any messages on this server.") + + return "Activity", "\n".join(activity_output) + def format_fields(self, mapping: Mapping[str, Any], field_width: Optional[int] = None) -> str: """Format a mapping to be readable to a human.""" # sorting is technically superfluous but nice if you want to look for a specific field -- cgit v1.2.3 From e42cdaed973408c0753366401adb946e8402d082 Mon Sep 17 00:00:00 2001 From: Xithrius Date: Fri, 6 Nov 2020 18:12:23 -0800 Subject: Moved activity data further up in embed. --- bot/exts/info/information.py | 45 ++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index c83dfadc5..c4c73efdf 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -12,6 +12,7 @@ from discord.abc import GuildChannel from discord.ext.commands import BucketType, Cog, Context, Paginator, command, group, has_any_role from bot import constants +from bot.api import ResponseCodeError from bot.bot import Bot from bot.converters import FetchedMember from bot.decorators import in_whitelist @@ -235,14 +236,18 @@ class Information(Cog): roles = None membership = "The user is not a member of the server" + verified_at, activity = await self.user_verification_and_messages(user) + verified_at = f"Verified: {verified_at}" if is_mod_channel(ctx.channel) else "" + fields = [ ( "User information", textwrap.dedent(f""" Created: {created} + {verified_at} Profile: {user.mention} ID: {user.id} - """).strip() + """).strip().replace("\n\n", "\n") ), ( "Member information", @@ -252,9 +257,10 @@ class Information(Cog): # Show more verbose output in moderation channels for infractions and nominations if is_mod_channel(ctx.channel): + fields.append(activity) + fields.append(await self.expanded_user_infraction_counts(user)) fields.append(await self.user_nomination_counts(user)) - fields.append(await self.user_verification_and_messages(user)) else: fields.append(await self.basic_user_infraction_counts(user)) @@ -355,24 +361,35 @@ class Information(Cog): return "Nominations", "\n".join(output) - async def user_verification_and_messages(self, user: FetchedMember) -> Tuple[str, str]: + async def user_verification_and_messages(self, user: FetchedMember) -> Tuple[Union[bool, str], Tuple[str, str]]: """Gets the time of verification and amount of messages for `member`.""" - user_activity = await self.bot.api_client.get(f'bot/users/{user.id}/metricity_data') - activity_output = [] - if user_activity['verified_at'] is not None: - verified_delta_formatted = time_since(parser.isoparse(user_activity['verified_at']), max_units=3) - activity_output.append(f'This user verified {verified_delta_formatted}') + try: + user_activity = await self.bot.api_client.get(f'bot/users/{user.id}/metricity_data') + except ResponseCodeError as e: + verified_at = False + activity_output = f"{e.status}: No activity" else: - activity_output.append('This user is not verified.') + if user_activity['verified_at'] is not None: + verified_at = time_since(parser.isoparse(user_activity["verified_at"]), max_units=3) + else: + verified_at = "Not verified" - if user_activity['total_messages']: - activity_output.append(f"This user has a total of {user_activity['total_messages']} messages.") - else: - activity_output.append(f"This user has not sent any messages on this server.") + if user_activity["total_messages"]: + activity_output.append(user_activity['total_messages']) + else: + activity_output.append("No messages") + + if user_activity["activity_blocks"]: + activity_output.append(user_activity["activity_blocks"]) + else: + activity_output.append("No activity") + + activity_output = "\n".join( + f"{name}: {metric}" for name, metric in zip(["Messages", "Activity blocks"], activity_output)) - return "Activity", "\n".join(activity_output) + return verified_at, ("Activity", activity_output) def format_fields(self, mapping: Mapping[str, Any], field_width: Optional[int] = None) -> str: """Format a mapping to be readable to a human.""" -- cgit v1.2.3 From 097298e260f0d1d84a8442e5c267042424314f3e Mon Sep 17 00:00:00 2001 From: Xithrius Date: Wed, 11 Nov 2020 18:09:30 -0800 Subject: Changed logic of membership info creation. --- bot/exts/info/information.py | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index c4c73efdf..a8adb817b 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -225,29 +225,34 @@ class Information(Cog): if is_set and (emoji := getattr(constants.Emojis, f"badge_{badge}", None)): badges.append(emoji) + verified_at, activity = await self.user_verification_and_messages(user) + if on_server: joined = time_since(user.joined_at, max_units=3) roles = ", ".join(role.mention for role in user.roles[1:]) - membership = textwrap.dedent(f""" - Joined: {joined} - Roles: {roles or None} - """).strip() + if is_mod_channel(ctx.channel): + membership = textwrap.dedent(f""" + Joined: {joined} + Verified: {verified_at} + Roles: {roles or None} + """).strip() + else: + membership = textwrap.dedent(f""" + Joined: {joined} + Roles: {roles or None} + """).strip() else: roles = None membership = "The user is not a member of the server" - verified_at, activity = await self.user_verification_and_messages(user) - verified_at = f"Verified: {verified_at}" if is_mod_channel(ctx.channel) else "" - fields = [ ( "User information", textwrap.dedent(f""" Created: {created} - {verified_at} Profile: {user.mention} ID: {user.id} - """).strip().replace("\n\n", "\n") + """).strip() ), ( "Member information", @@ -364,17 +369,18 @@ class Information(Cog): async def user_verification_and_messages(self, user: FetchedMember) -> Tuple[Union[bool, str], Tuple[str, str]]: """Gets the time of verification and amount of messages for `member`.""" activity_output = [] + verified_at = False try: user_activity = await self.bot.api_client.get(f'bot/users/{user.id}/metricity_data') except ResponseCodeError as e: - verified_at = False - activity_output = f"{e.status}: No activity" + if e.status == 404: + activity_output = "No activity" + else: - if user_activity['verified_at'] is not None: + verified_at = user_activity['verified_at'] + if verified_at is not None: verified_at = time_since(parser.isoparse(user_activity["verified_at"]), max_units=3) - else: - verified_at = "Not verified" if user_activity["total_messages"]: activity_output.append(user_activity['total_messages']) -- cgit v1.2.3 From 9250608d1ec80fcc098e0174f5204f157fab9b8e Mon Sep 17 00:00:00 2001 From: Xithrius Date: Thu, 10 Dec 2020 16:34:47 -0800 Subject: Compressed if into or statements. --- bot/exts/info/information.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index a8adb817b..5d94d73e9 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -382,15 +382,8 @@ class Information(Cog): if verified_at is not None: verified_at = time_since(parser.isoparse(user_activity["verified_at"]), max_units=3) - if user_activity["total_messages"]: - activity_output.append(user_activity['total_messages']) - else: - activity_output.append("No messages") - - if user_activity["activity_blocks"]: - activity_output.append(user_activity["activity_blocks"]) - else: - activity_output.append("No activity") + activity_output.append(user_activity['total_messages'] or "No messages") + activity_output.append(user_activity["activity_blocks"] or "No activity") activity_output = "\n".join( f"{name}: {metric}" for name, metric in zip(["Messages", "Activity blocks"], activity_output)) -- cgit v1.2.3 From 223455d979cc794f857fc77e6211837c9639cca9 Mon Sep 17 00:00:00 2001 From: Xithrius <15021300+Xithrius@users.noreply.github.com> Date: Thu, 10 Dec 2020 16:38:48 -0800 Subject: Compressed embed building Co-authored-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/exts/info/information.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index a8adb817b..648f283bc 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -230,17 +230,11 @@ class Information(Cog): if on_server: joined = time_since(user.joined_at, max_units=3) roles = ", ".join(role.mention for role in user.roles[1:]) - if is_mod_channel(ctx.channel): - membership = textwrap.dedent(f""" - Joined: {joined} - Verified: {verified_at} - Roles: {roles or None} - """).strip() - else: - membership = textwrap.dedent(f""" - Joined: {joined} - Roles: {roles or None} - """).strip() + membership = {"Joined": joined, "Verified": verified_at, "Roles": roles or None} + if not is_mod_channel(ctx.channel): + membership.pop("Verified") + + membership = textwrap.dedent("\n".join([f"{key}: {value}" for key, value in membership.items()])) else: roles = None membership = "The user is not a member of the server" -- cgit v1.2.3 From dd2f29feae436a550b73b20d43166a9548840f47 Mon Sep 17 00:00:00 2001 From: Xithrius <15021300+Xithrius@users.noreply.github.com> Date: Thu, 10 Dec 2020 16:39:29 -0800 Subject: Slightly reformatted activity block building. Co-authored-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/exts/info/information.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 648f283bc..22a32cdb5 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -387,7 +387,8 @@ class Information(Cog): activity_output.append("No activity") activity_output = "\n".join( - f"{name}: {metric}" for name, metric in zip(["Messages", "Activity blocks"], activity_output)) + f"{name}: {metric}" for name, metric in zip(["Messages", "Activity blocks"], activity_output) + ) return verified_at, ("Activity", activity_output) -- cgit v1.2.3 From 77a8e420a69fdafb9fe96739d9d728c7a5d3638f Mon Sep 17 00:00:00 2001 From: Xithrius Date: Thu, 10 Dec 2020 16:57:35 -0800 Subject: Added docstring for the user activity function. --- bot/exts/info/information.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 26cf5fee3..8eec22c58 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -361,7 +361,12 @@ class Information(Cog): return "Nominations", "\n".join(output) async def user_verification_and_messages(self, user: FetchedMember) -> Tuple[Union[bool, str], Tuple[str, str]]: - """Gets the time of verification and amount of messages for `member`.""" + """ + Gets the time of verification and amount of messages for `member`. + + Fetches information from the metricity database that's hosted by the site. + If the database returns a code besides a 404, then many parts of the bot are broken including this one. + """ activity_output = [] verified_at = False -- cgit v1.2.3 From 2fa5b78e357bf45e23e188dc501180ed241237d1 Mon Sep 17 00:00:00 2001 From: Xithrius Date: Fri, 11 Dec 2020 05:06:03 -0800 Subject: Added catching for unparsable short ISO dates. --- bot/exts/info/information.py | 11 +++++++---- tests/bot/exts/info/test_information.py | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 8eec22c58..0c04d7cd0 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -230,7 +230,7 @@ class Information(Cog): if on_server: joined = time_since(user.joined_at, max_units=3) roles = ", ".join(role.mention for role in user.roles[1:]) - membership = {"Joined": joined, "Verified": verified_at, "Roles": roles or None} + membership = {"Joined": joined, "Verified": verified_at or "False", "Roles": roles or None} if not is_mod_channel(ctx.channel): membership.pop("Verified") @@ -377,9 +377,12 @@ class Information(Cog): activity_output = "No activity" else: - verified_at = user_activity['verified_at'] - if verified_at is not None: - verified_at = time_since(parser.isoparse(user_activity["verified_at"]), max_units=3) + try: + if (verified_at := user_activity['verified_at']) is not None: + verified_at = time_since(parser.isoparse(verified_at), max_units=3) + except ValueError: + log.warning('Could not parse ISO string correctly for user verification date.') + verified_at = None activity_output.append(user_activity['total_messages'] or "No messages") activity_output.append(user_activity["activity_blocks"] or "No activity") diff --git a/tests/bot/exts/info/test_information.py b/tests/bot/exts/info/test_information.py index daede54c5..254b0a867 100644 --- a/tests/bot/exts/info/test_information.py +++ b/tests/bot/exts/info/test_information.py @@ -355,6 +355,7 @@ class UserEmbedTests(unittest.IsolatedAsyncioTestCase): self.assertEqual( textwrap.dedent(f""" Joined: {"1 year ago"} + Verified: {"False"} Roles: &Moderators """).strip(), embed.fields[1].value -- cgit v1.2.3 From 9f1bbe528311afaf5a56ebafdac7a629c9ce238e Mon Sep 17 00:00:00 2001 From: Xithrius Date: Fri, 11 Dec 2020 05:11:48 -0800 Subject: Single to double quotes & warning includes user ID. --- bot/exts/info/information.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 0c04d7cd0..187950689 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -371,20 +371,20 @@ class Information(Cog): verified_at = False try: - user_activity = await self.bot.api_client.get(f'bot/users/{user.id}/metricity_data') + user_activity = await self.bot.api_client.get(f"bot/users/{user.id}/metricity_data") except ResponseCodeError as e: if e.status == 404: activity_output = "No activity" else: try: - if (verified_at := user_activity['verified_at']) is not None: + if (verified_at := user_activity["verified_at"]) is not None: verified_at = time_since(parser.isoparse(verified_at), max_units=3) except ValueError: - log.warning('Could not parse ISO string correctly for user verification date.') + log.warning(f"Could not parse ISO string correctly for user {user.id} verification date.") verified_at = None - activity_output.append(user_activity['total_messages'] or "No messages") + activity_output.append(user_activity["total_messages"] or "No messages") activity_output.append(user_activity["activity_blocks"] or "No activity") activity_output = "\n".join( -- cgit v1.2.3